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.
8 import sys, subprocess, os
15 print("\nTEST FAIL: {}".format(msg))
18 def cargo_miri(cmd, quiet = True):
19 args = ["cargo", "miri", cmd]
22 if 'MIRI_TEST_TARGET' in os.environ:
23 args += ["--target", os.environ['MIRI_TEST_TARGET']]
26 def test(name, cmd, stdout_ref, stderr_ref, stdin=b'', env={}):
27 print("Testing {}...".format(name))
28 ## Call `cargo miri`, capture all output
29 p_env = os.environ.copy()
33 stdin=subprocess.PIPE,
34 stdout=subprocess.PIPE,
35 stderr=subprocess.PIPE,
38 (stdout, stderr) = p.communicate(input=stdin)
39 stdout = stdout.decode("UTF-8")
40 stderr = stderr.decode("UTF-8")
41 if p.returncode == 0 and stdout == open(stdout_ref).read() and stderr == open(stderr_ref).read():
45 print("--- BEGIN stdout ---")
47 print("--- END stdout ---")
48 print("--- BEGIN stderr ---")
50 print("--- END stderr ---")
51 fail("exit code was {}".format(p.returncode))
53 def test_no_rebuild(name, cmd, env={}):
54 print("Testing {}...".format(name))
55 p_env = os.environ.copy()
59 stdout=subprocess.PIPE,
60 stderr=subprocess.PIPE,
63 (stdout, stderr) = p.communicate()
64 stdout = stdout.decode("UTF-8")
65 stderr = stderr.decode("UTF-8")
67 fail("rebuild failed");
68 # Also check for 'Running' as a sanity check.
69 if stderr.count(" Compiling ") > 0 or stderr.count(" Running ") == 0:
70 print("--- BEGIN stderr ---")
72 print("--- END stderr ---")
73 fail("Something was being rebuilt when it should not be (or we got no output)");
75 def test_cargo_miri_run():
76 test("`cargo miri run` (no isolation)",
78 "run.default.stdout.ref", "run.default.stderr.ref",
81 'MIRIFLAGS': "-Zmiri-disable-isolation",
82 'MIRITESTVAR': "wrongval", # make sure the build.rs value takes precedence
85 # Special test: run it again *without* `-q` to make sure nothing is being rebuilt (Miri issue #1722)
86 test_no_rebuild("`cargo miri run` (no rebuild)",
87 cargo_miri("run", quiet=False) + ["--", ""],
88 env={'MIRITESTVAR': "wrongval"}, # changing the env var causes a rebuild (re-runs build.rs),
91 test("`cargo miri run` (with arguments and target)",
92 cargo_miri("run") + ["--bin", "cargo-miri-test", "--", "hello world", '"hello world"'],
93 "run.args.stdout.ref", "run.args.stderr.ref",
95 test("`cargo miri run` (subcrate, no ioslation)",
96 cargo_miri("run") + ["-p", "subcrate"],
97 "run.subcrate.stdout.ref", "run.subcrate.stderr.ref",
98 env={'MIRIFLAGS': "-Zmiri-disable-isolation"},
101 def test_cargo_miri_test():
102 # rustdoc is not run on foreign targets
103 is_foreign = 'MIRI_TEST_TARGET' in os.environ
104 rustdoc_ref = "test.stderr-empty.ref" if is_foreign else "test.stderr-rustdoc.ref"
106 test("`cargo miri test`",
108 "test.default.stdout.ref", rustdoc_ref,
109 env={'MIRIFLAGS': "-Zmiri-seed=feed"},
111 test("`cargo miri test` (no isolation)",
113 "test.default.stdout.ref", rustdoc_ref,
114 env={'MIRIFLAGS': "-Zmiri-disable-isolation"},
116 test("`cargo miri test` (raw-ptr tracking)",
118 "test.default.stdout.ref", rustdoc_ref,
119 env={'MIRIFLAGS': "-Zmiri-track-raw-pointers"},
121 test("`cargo miri test` (with filter)",
122 cargo_miri("test") + ["--", "--format=pretty", "le1"],
123 "test.filter.stdout.ref", rustdoc_ref,
125 test("`cargo miri test` (test target)",
126 cargo_miri("test") + ["--test", "test", "--", "--format=pretty"],
127 "test.test-target.stdout.ref", "test.stderr-empty.ref",
129 test("`cargo miri test` (bin target)",
130 cargo_miri("test") + ["--bin", "cargo-miri-test", "--", "--format=pretty"],
131 "test.bin-target.stdout.ref", "test.stderr-empty.ref",
133 test("`cargo miri test` (subcrate, no isolation)",
134 cargo_miri("test") + ["-p", "subcrate"],
135 "test.subcrate.stdout.ref", "test.stderr-proc-macro.ref",
136 env={'MIRIFLAGS': "-Zmiri-disable-isolation"},
139 os.chdir(os.path.dirname(os.path.realpath(__file__)))
140 os.environ["RUST_TEST_NOCAPTURE"] = "0" # this affects test output, so make sure it is not set
142 target_str = " for target {}".format(os.environ['MIRI_TEST_TARGET']) if 'MIRI_TEST_TARGET' in os.environ else ""
143 print(CGREEN + CBOLD + "## Running `cargo miri` tests{}".format(target_str) + CEND)
145 if not 'MIRI_SYSROOT' in os.environ:
146 # Make sure we got a working sysroot.
147 # (If the sysroot gets built later when output is compared, that leads to test failures.)
148 subprocess.run(cargo_miri("setup"), check=True)
149 test_cargo_miri_run()
150 test_cargo_miri_test()
152 print("\nTEST SUCCESSFUL!")