1
use std::error::Error;
2
use std::path::Path;
3

            
4
pub use duct::cmd;
5

            
6
#[allow(clippy::ptr_arg)]
7
fn add_target_flag(_arguments: &mut Vec<String>) {
8
    #[cfg(target_os = "linux")]
9
    {
10
        _arguments.push("--target".to_string());
11
        _arguments.push("x86_64-unknown-linux-gnu".to_string());
12
    }
13

            
14
    #[cfg(target_os = "macos")]
15
    {
16
        _arguments.push("--target".to_string());
17
        _arguments.push("x86_64-apple-darwin".to_string());
18
    }
19
}
20

            
21
///
22
/// Run the tests with the address sanitizer enabled to detect memory issues in unsafe code.
23
///
24
/// This only works under Linux and MacOS currently and requires the nightly toolchain.
25
///
26
pub fn address_sanitizer(mut arguments: Vec<String>) -> Result<(), Box<dyn Error>> {
27
    arguments.extend(vec!["-Zbuild-std".to_string()]);
28

            
29
    add_target_flag(&mut arguments);
30

            
31
    cmd("cargo", arguments)
32
        .env("RUSTFLAGS", "-Zsanitizer=address,leak")
33
        .env("RUSTDOCFLAGS", "-Zsanitizer=address,leak")
34
        .env("CFLAGS", "-fsanitize=address,leak")
35
        .env("CXXFLAGS", "-fsanitize=address,leak")
36
        .run()?;
37
    println!("ok.");
38

            
39
    Ok(())
40
}
41

            
42
///
43
/// Run the tests with the thread sanitizer enabled to detect data race conditions.
44
///
45
/// This only works under Linux and MacOS currently and requires the nightly toolchain.
46
///
47
pub fn thread_sanitizer(mut arguments: Vec<String>) -> Result<(), Box<dyn Error>> {
48
    arguments.extend(vec!["-Zbuild-std".to_string()]);
49

            
50
    add_target_flag(&mut arguments);
51

            
52
    let thread_sanitizer_suppress = Path::new(env!("CARGO_MANIFEST_DIR")).join("data/thread_sanitizer.suppress");
53

            
54
    cmd("cargo", arguments)
55
        .env(
56
            "TSAN_OPTIONS",
57
            format!("suppressions={}", thread_sanitizer_suppress.to_string_lossy()),
58
        )
59
        .env("RUSTFLAGS", "-Zsanitizer=thread")
60
        .env("RUSTDOCFLAGS", "-Zsanitizer=thread")
61
        .env("CFLAGS", "-fsanitize=thread")
62
        .env("CXXFLAGS", "-fsanitize=thread")
63
        .run()?;
64
    println!("ok.");
65

            
66
    Ok(())
67
}