summaryrefslogtreecommitdiffstats
path: root/vendor/ui_test/tests/integration.rs
blob: a9a77b45fa1a960047b96df1d76d104f4538ddee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::path::Path;

use colored::Colorize;
use ui_test::color_eyre::Result;
use ui_test::*;

fn main() -> Result<()> {
    run("integrations", Mode::Pass)?;
    run("integrations", Mode::Panic)?;

    eprintln!("integration tests done");

    Ok(())
}

fn run(name: &str, mode: Mode) -> Result<()> {
    eprintln!("\n{} `{name}` tests in mode {mode}", "Running".green());
    let path = Path::new(file!()).parent().unwrap();
    let root_dir = path.join(name);
    let bless = std::env::args().all(|arg| arg != "--check");
    let mut config = Config {
        trailing_args: vec!["--".into(), "--test-threads".into(), "1".into()],
        mode,
        ..Config::cargo(root_dir.clone())
    };

    if bless {
        config.output_conflict_handling = OutputConflictHandling::Bless;
    }

    config.program.args = vec![
        "test".into(),
        "--color".into(),
        "never".into(),
        "--quiet".into(),
        "--jobs".into(),
        "1".into(),
        "--no-fail-fast".into(),
    ];

    config
        .program
        .envs
        .push(("BLESS".into(), bless.then(|| String::new().into())));

    config.stdout_filter("in ([0-9]m )?[0-9\\.]+s", "");
    config.stderr_filter(r#""--out-dir"(,)? "[^"]+""#, r#""--out-dir"$1 "$$TMP"#);
    config.stderr_filter(
        "( *process didn't exit successfully: `[^-]+)-[0-9a-f]+",
        "$1-HASH",
    );
    // Windows io::Error uses "exit code".
    config.stderr_filter("exit code", "exit status");
    // The order of the `/deps` directory flag is flaky
    config.stderr_filter("/deps", "");
    config.path_stderr_filter(&std::path::Path::new(path), "$DIR");
    config.stderr_filter("[0-9a-f]+\\.rmeta", "$$HASH.rmeta");
    // Windows backslashes are sometimes escaped.
    // Insert the replacement filter at the start to make sure the filter for single backslashes
    // runs afterwards.
    config
        .stderr_filters
        .insert(0, (Match::Exact(b"\\\\".iter().copied().collect()), b"\\"));
    config.stderr_filter("\\.exe", b"");
    config.stderr_filter(r#"(panic.*)\.rs:[0-9]+:[0-9]+"#, "$1.rs");
    config.stderr_filter("   [0-9]: .*", "");
    config.stderr_filter("/target/[^/]+/[^/]+/debug", "/target/$$TMP/$$TRIPLE/debug");
    config.stderr_filter("/target/[^/]+/tests", "/target/$$TMP/tests");
    // Normalize proc macro filenames on windows to their linux repr
    config.stderr_filter("/([^/\\.]+)\\.dll", "/lib$1.so");
    // Normalize proc macro filenames on mac to their linux repr
    config.stderr_filter("/([^/\\.]+)\\.dylib", "/$1.so");
    config.stderr_filter("(command: )\"[^<rp][^\"]+", "$1\"$$CMD");
    config.stderr_filter("(src/.*?\\.rs):[0-9]+:[0-9]+", "$1:LL:CC");
    config.stderr_filter("program not found", "No such file or directory");
    config.stderr_filter(" \\(os error [0-9]+\\)", "");

    run_tests_generic(
        config,
        |path| {
            let fail = path
                .parent()
                .unwrap()
                .file_name()
                .unwrap()
                .to_str()
                .unwrap()
                .ends_with("-fail");
            if cfg!(windows) && path.components().any(|c| c.as_os_str() == "basic-bin") {
                // on windows there's also a .pdb file, so we get additional errors that aren't there on other platforms
                return false;
            }
            path.ends_with("Cargo.toml")
                && path.parent().unwrap().parent().unwrap() == root_dir
                && match mode {
                    Mode::Pass => !fail,
                    // This is weird, but `cargo test` returns 101 instead of 1 when
                    // multiple [[test]]s exist. If there's only one test, it returns
                    // 1 on failure.
                    Mode::Panic => fail,
                    Mode::Fix | Mode::Run { .. } | Mode::Yolo | Mode::Fail { .. } => unreachable!(),
                }
        },
        |_, _| None,
        (
            ui_test::status_emitter::Text,
            ui_test::status_emitter::Gha::<true> {
                name: format!("{mode:?}"),
            },
        ),
    )
}