Skip to content

Commit 394ec96

Browse files
committed
Fix spurious Windows errors with switch_features_rerun.
1 parent 10e3230 commit 394ec96

File tree

3 files changed

+31
-18
lines changed

3 files changed

+31
-18
lines changed

tests/testsuite/build_script.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3171,9 +3171,12 @@ fn switch_features_rerun() {
31713171
)
31723172
.build();
31733173

3174-
p.cargo("run -v --features=foo").with_stdout("foo\n").run();
3175-
p.cargo("run -v").with_stdout("bar\n").run();
3176-
p.cargo("run -v --features=foo").with_stdout("foo\n").run();
3174+
p.cargo("build -v --features=foo").run();
3175+
p.safely_rename_run("foo", "with_foo").with_stdout("foo\n").run();
3176+
p.cargo("build -v").run();
3177+
p.safely_rename_run("foo", "without_foo").with_stdout("bar\n").run();
3178+
p.cargo("build -v --features=foo").run();
3179+
p.safely_rename_run("foo", "with_foo2").with_stdout("foo\n").run();
31773180
}
31783181

31793182
#[test]

tests/testsuite/freshness.rs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -447,17 +447,6 @@ fn changing_bin_features_caches_targets() {
447447
)
448448
.build();
449449

450-
// Windows has a problem with replacing a binary that was just executed.
451-
// Unlinking it will succeed, but then attempting to immediately replace
452-
// it will sometimes fail with "Already Exists".
453-
// See https://github.com/rust-lang/cargo/issues/5481
454-
let foo_proc = |name: &str| {
455-
let src = p.bin("foo");
456-
let dst = p.bin(name);
457-
fs::rename(&src, &dst).expect("Failed to rename foo");
458-
p.process(dst)
459-
};
460-
461450
p.cargo("build")
462451
.with_stderr(
463452
"\
@@ -466,7 +455,7 @@ fn changing_bin_features_caches_targets() {
466455
",
467456
)
468457
.run();
469-
foo_proc("off1").with_stdout("feature off").run();
458+
p.safely_rename_run("foo", "off1").with_stdout("feature off").run();
470459

471460
p.cargo("build --features foo")
472461
.with_stderr(
@@ -476,7 +465,7 @@ fn changing_bin_features_caches_targets() {
476465
",
477466
)
478467
.run();
479-
foo_proc("on1").with_stdout("feature on").run();
468+
p.safely_rename_run("foo", "on1").with_stdout("feature on").run();
480469

481470
/* Targets should be cached from the first build */
482471

@@ -487,7 +476,7 @@ fn changing_bin_features_caches_targets() {
487476
",
488477
)
489478
.run();
490-
foo_proc("off2").with_stdout("feature off").run();
479+
p.safely_rename_run("foo", "off2").with_stdout("feature off").run();
491480

492481
p.cargo("build --features foo")
493482
.with_stderr(
@@ -496,7 +485,7 @@ fn changing_bin_features_caches_targets() {
496485
",
497486
)
498487
.run();
499-
foo_proc("on2").with_stdout("feature on").run();
488+
p.safely_rename_run("foo", "on2").with_stdout("feature on").run();
500489
}
501490

502491
#[test]

tests/testsuite/support/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,27 @@ impl Project {
399399
execs
400400
}
401401

402+
/// Safely run a process after `cargo build`.
403+
///
404+
/// Windows has a problem where a process cannot be reliably
405+
/// be replaced, removed, or renamed immediately after executing it.
406+
/// The action may fail (with errors like Access is denied), or
407+
/// it may succeed, but future attempts to use the same filename
408+
/// will fail with "Already Exists".
409+
///
410+
/// If you have a test that needs to do `cargo run` multiple
411+
/// times, you should instead use `cargo build` and use this
412+
/// method to run the executable. Each time you call this,
413+
/// use a new name for `dst`.
414+
/// See https://github.com/rust-lang/cargo/issues/5481
415+
pub fn safely_rename_run(&self, src: &str, dst: &str) -> Execs {
416+
let src = self.bin(src);
417+
let dst = self.bin(dst);
418+
fs::rename(&src, &dst)
419+
.unwrap_or_else(|e| panic!("Failed to rename `{:?}` to `{:?}`: {}", src, dst, e));
420+
self.process(dst)
421+
}
422+
402423
/// Returns the contents of `Cargo.lock`.
403424
pub fn read_lockfile(&self) -> String {
404425
self.read_file("Cargo.lock")

0 commit comments

Comments
 (0)