From f85bb0fb09a1932cdc17ebb0dcd13b81c93346f7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 27 Feb 2021 12:24:58 +0100 Subject: [PATCH 1/2] test for unnecessary rebuilds in 'cargo miri run' --- test-cargo-miri/run-test.py | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/test-cargo-miri/run-test.py b/test-cargo-miri/run-test.py index 8edd947c3b..0505b422d9 100755 --- a/test-cargo-miri/run-test.py +++ b/test-cargo-miri/run-test.py @@ -15,8 +15,10 @@ def fail(msg): print("\nTEST FAIL: {}".format(msg)) sys.exit(1) -def cargo_miri(cmd): - args = ["cargo", "miri", cmd, "-q"] +def cargo_miri(cmd, quiet = True): + args = ["cargo", "miri", cmd] + if quiet: + args += ["-q"] if 'MIRI_TEST_TARGET' in os.environ: args += ["--target", os.environ['MIRI_TEST_TARGET']] return args @@ -48,6 +50,25 @@ def test(name, cmd, stdout_ref, stderr_ref, stdin=b'', env={}): print("--- END stderr ---") fail("exit code was {}".format(p.returncode)) +def test_rebuild(name, cmd, rebuild_count_expected): + print("Testing {}...".format(name)) + p = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + (stdout, stderr) = p.communicate() + stdout = stdout.decode("UTF-8") + stderr = stderr.decode("UTF-8") + if p.returncode != 0: + fail("rebuild failed"); + rebuild_count = stderr.count(" Compiling "); + if rebuild_count != rebuild_count_expected: + print("--- BEGIN stderr ---") + print(stderr, end="") + print("--- END stderr ---") + fail("Expected {} rebuild(s), but got {}".format(rebuild_count_expected, rebuild_count)); + def test_cargo_miri_run(): test("`cargo miri run` (no isolation)", cargo_miri("run"), @@ -67,6 +88,11 @@ def test_cargo_miri_run(): "run.subcrate.stdout.ref", "run.subcrate.stderr.ref", env={'MIRIFLAGS': "-Zmiri-disable-isolation"}, ) + # Special test: run it again *without* `-q` to make sure nothing is being rebuilt (Miri issue #1722) + test_rebuild("`cargo miri run` (clean rebuild)", + cargo_miri("run", quiet=False) + ["--", ""], + rebuild_count_expected=1, + ) def test_cargo_miri_test(): # rustdoc is not run on foreign targets From 3e987e127c9865189af59f7878e172b9f1297de5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 27 Feb 2021 12:32:06 +0100 Subject: [PATCH 2/2] create more fake files for cdylibs and staticlibs --- cargo-miri/bin.rs | 13 +++++++++---- test-cargo-miri/run-test.py | 13 +++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/cargo-miri/bin.rs b/cargo-miri/bin.rs index cb003c0f3e..051f3dd3b6 100644 --- a/cargo-miri/bin.rs +++ b/cargo-miri/bin.rs @@ -692,12 +692,17 @@ fn phase_cargo_rustc(mut args: env::Args) { exec(cmd); // Create a stub .rlib file if "link" was requested by cargo. + // This is necessary to prevent cargo from doing rebuilds all the time. if emit_link_hack { // Some platforms prepend "lib", some do not... let's just create both files. - let filename = out_filename("lib", ".rlib"); - File::create(filename).expect("failed to create rlib file"); - let filename = out_filename("", ".rlib"); - File::create(filename).expect("failed to create rlib file"); + File::create(out_filename("lib", ".rlib")).expect("failed to create fake .rlib file"); + File::create(out_filename("", ".rlib")).expect("failed to create fake .rlib file"); + // Just in case this is a cdylib or staticlib, also create those fake files. + File::create(out_filename("lib", ".so")).expect("failed to create fake .so file"); + File::create(out_filename("lib", ".a")).expect("failed to create fake .a file"); + File::create(out_filename("lib", ".dylib")).expect("failed to create fake .dylib file"); + File::create(out_filename("", ".dll")).expect("failed to create fake .dll file"); + File::create(out_filename("", ".lib")).expect("failed to create fake .lib file"); } } diff --git a/test-cargo-miri/run-test.py b/test-cargo-miri/run-test.py index 0505b422d9..b9259b7d0d 100755 --- a/test-cargo-miri/run-test.py +++ b/test-cargo-miri/run-test.py @@ -50,7 +50,7 @@ def test(name, cmd, stdout_ref, stderr_ref, stdin=b'', env={}): print("--- END stderr ---") fail("exit code was {}".format(p.returncode)) -def test_rebuild(name, cmd, rebuild_count_expected): +def test_no_rebuild(name, cmd): print("Testing {}...".format(name)) p = subprocess.Popen( cmd, @@ -62,12 +62,12 @@ def test_rebuild(name, cmd, rebuild_count_expected): stderr = stderr.decode("UTF-8") if p.returncode != 0: fail("rebuild failed"); - rebuild_count = stderr.count(" Compiling "); - if rebuild_count != rebuild_count_expected: + # Also check for 'Running' as a sanity check. + if stderr.count(" Compiling ") > 0 or stderr.count(" Running ") == 0: print("--- BEGIN stderr ---") print(stderr, end="") print("--- END stderr ---") - fail("Expected {} rebuild(s), but got {}".format(rebuild_count_expected, rebuild_count)); + fail("Something was being rebuilt when it should not be (or we got no output)"); def test_cargo_miri_run(): test("`cargo miri run` (no isolation)", @@ -89,9 +89,10 @@ def test_cargo_miri_run(): env={'MIRIFLAGS': "-Zmiri-disable-isolation"}, ) # Special test: run it again *without* `-q` to make sure nothing is being rebuilt (Miri issue #1722) - test_rebuild("`cargo miri run` (clean rebuild)", + # FIXME: move this test up to right after the first `test` + # (currently that fails, only the 3rd and later runs are really clean... see Miri issue #1722) + test_no_rebuild("`cargo miri run` (no rebuild)", cargo_miri("run", quiet=False) + ["--", ""], - rebuild_count_expected=1, ) def test_cargo_miri_test():