]> git.lizzy.rs Git - rust.git/blob - test-cargo-miri/run-test.py
Don't `unwrap()` in `in_std()`
[rust.git] / test-cargo-miri / run-test.py
1 #!/usr/bin/env python3
2 '''
3 Test whether cargo-miri works properly.
4 Assumes the `MIRI_SYSROOT` env var to be set appropriately,
5 and the working directory to contain the cargo-miri-test project.
6 '''
7
8 import sys, subprocess, os, re
9
10 CGREEN  = '\33[32m'
11 CBOLD   = '\33[1m'
12 CEND    = '\33[0m'
13
14 def fail(msg):
15     print("\nTEST FAIL: {}".format(msg))
16     sys.exit(1)
17
18 def cargo_miri(cmd, quiet = True):
19     args = ["cargo", "miri", cmd]
20     if quiet:
21         args += ["-q"]
22     if 'MIRI_TEST_TARGET' in os.environ:
23         args += ["--target", os.environ['MIRI_TEST_TARGET']]
24     return args
25
26 def normalize_stdout(str):
27     str = str.replace("src\\", "src/") # normalize paths across platforms
28     return re.sub("finished in \d+\.\d\ds", "finished in $TIME", str)
29
30 def test(name, cmd, stdout_ref, stderr_ref, stdin=b'', env={}):
31     print("Testing {}...".format(name))
32     ## Call `cargo miri`, capture all output
33     p_env = os.environ.copy()
34     p_env.update(env)
35     p = subprocess.Popen(
36         cmd,
37         stdin=subprocess.PIPE,
38         stdout=subprocess.PIPE,
39         stderr=subprocess.PIPE,
40         env=p_env,
41     )
42     (stdout, stderr) = p.communicate(input=stdin)
43     stdout = stdout.decode("UTF-8")
44     stderr = stderr.decode("UTF-8")
45     if p.returncode == 0 and normalize_stdout(stdout) == open(stdout_ref).read() and stderr == open(stderr_ref).read():
46         # All good!
47         return
48     # Show output
49     print("--- BEGIN stdout ---")
50     print(stdout, end="")
51     print("--- END stdout ---")
52     print("--- BEGIN stderr ---")
53     print(stderr, end="")
54     print("--- END stderr ---")
55     fail("exit code was {}".format(p.returncode))
56
57 def test_no_rebuild(name, cmd, env={}):
58     print("Testing {}...".format(name))
59     p_env = os.environ.copy()
60     p_env.update(env)
61     p = subprocess.Popen(
62         cmd,
63         stdout=subprocess.PIPE,
64         stderr=subprocess.PIPE,
65         env=p_env,
66     )
67     (stdout, stderr) = p.communicate()
68     stdout = stdout.decode("UTF-8")
69     stderr = stderr.decode("UTF-8")
70     if p.returncode != 0:
71         fail("rebuild failed");
72     # Also check for 'Running' as a sanity check.
73     if stderr.count(" Compiling ") > 0 or stderr.count(" Running ") == 0:
74         print("--- BEGIN stderr ---")
75         print(stderr, end="")
76         print("--- END stderr ---")
77         fail("Something was being rebuilt when it should not be (or we got no output)");
78
79 def test_cargo_miri_run():
80     test("`cargo miri run` (no isolation)",
81         cargo_miri("run"),
82         "run.default.stdout.ref", "run.default.stderr.ref",
83         stdin=b'12\n21\n',
84         env={
85             'MIRIFLAGS': "-Zmiri-disable-isolation",
86             'MIRITESTVAR': "wrongval", # make sure the build.rs value takes precedence
87         },
88     )
89     # Special test: run it again *without* `-q` to make sure nothing is being rebuilt (Miri issue #1722)
90     test_no_rebuild("`cargo miri run` (no rebuild)",
91         cargo_miri("run", quiet=False) + ["--", ""],
92         env={'MIRITESTVAR': "wrongval"}, # changing the env var causes a rebuild (re-runs build.rs),
93                                          # so keep it set
94     )
95     test("`cargo miri run` (with arguments and target)",
96         cargo_miri("run") + ["--bin", "cargo-miri-test", "--", "hello world", '"hello world"'],
97         "run.args.stdout.ref", "run.args.stderr.ref",
98     )
99     test("`cargo miri run` (subcrate, no ioslation)",
100         cargo_miri("run") + ["-p", "subcrate"],
101         "run.subcrate.stdout.ref", "run.subcrate.stderr.ref",
102         env={'MIRIFLAGS': "-Zmiri-disable-isolation"},
103     )
104
105 def test_cargo_miri_test():
106     # rustdoc is not run on foreign targets
107     is_foreign = 'MIRI_TEST_TARGET' in os.environ
108     default_ref = "test.cross-target.stdout.ref" if is_foreign else "test.default.stdout.ref"
109     filter_ref = "test.filter.cross-target.stdout.ref" if is_foreign else "test.filter.stdout.ref"
110
111     test("`cargo miri test`",
112         cargo_miri("test"),
113         default_ref, "test.stderr-empty.ref",
114         env={'MIRIFLAGS': "-Zmiri-seed=feed"},
115     )
116     test("`cargo miri test` (no isolation, no doctests)",
117         cargo_miri("test") + ["--bins", "--tests"], # no `--lib`, we disabled that in `Cargo.toml`
118         "test.cross-target.stdout.ref", "test.stderr-empty.ref",
119         env={'MIRIFLAGS': "-Zmiri-disable-isolation"},
120     )
121     test("`cargo miri test` (raw-ptr tracking)",
122         cargo_miri("test"),
123         default_ref, "test.stderr-empty.ref",
124         env={'MIRIFLAGS': "-Zmiri-track-raw-pointers"},
125     )
126     test("`cargo miri test` (with filter)",
127         cargo_miri("test") + ["--", "--format=pretty", "le1"],
128         filter_ref, "test.stderr-empty.ref",
129     )
130     test("`cargo miri test` (test target)",
131         cargo_miri("test") + ["--test", "test", "--", "--format=pretty"],
132         "test.test-target.stdout.ref", "test.stderr-empty.ref",
133     )
134     test("`cargo miri test` (bin target)",
135         cargo_miri("test") + ["--bin", "cargo-miri-test", "--", "--format=pretty"],
136         "test.bin-target.stdout.ref", "test.stderr-empty.ref",
137     )
138     test("`cargo miri test` (subcrate, no isolation)",
139         cargo_miri("test") + ["-p", "subcrate"],
140         "test.subcrate.stdout.ref", "test.stderr-proc-macro.ref",
141         env={'MIRIFLAGS': "-Zmiri-disable-isolation"},
142     )
143     test("`cargo miri test` (subcrate, doctests)",
144         cargo_miri("test") + ["-p", "subcrate", "--doc"],
145         "test.stdout-empty.ref", "test.stderr-proc-macro-doctest.ref",
146     )
147
148 os.chdir(os.path.dirname(os.path.realpath(__file__)))
149 os.environ["RUST_TEST_NOCAPTURE"] = "0" # this affects test output, so make sure it is not set
150 os.environ["RUST_TEST_THREADS"] = "1" # avoid non-deterministic output due to concurrent test runs
151
152 target_str = " for target {}".format(os.environ['MIRI_TEST_TARGET']) if 'MIRI_TEST_TARGET' in os.environ else ""
153 print(CGREEN + CBOLD + "## Running `cargo miri` tests{}".format(target_str) + CEND)
154
155 if not 'MIRI_SYSROOT' in os.environ:
156     # Make sure we got a working sysroot.
157     # (If the sysroot gets built later when output is compared, that leads to test failures.)
158     subprocess.run(cargo_miri("setup"), check=True)
159 test_cargo_miri_run()
160 test_cargo_miri_test()
161
162 print("\nTEST SUCCESSFUL!")
163 sys.exit(0)