diff options
Diffstat (limited to 'src/tools/cargo/tests/testsuite/death.rs')
-rw-r--r-- | src/tools/cargo/tests/testsuite/death.rs | 153 |
1 files changed, 151 insertions, 2 deletions
diff --git a/src/tools/cargo/tests/testsuite/death.rs b/src/tools/cargo/tests/testsuite/death.rs index f0e182d01..b61896dc9 100644 --- a/src/tools/cargo/tests/testsuite/death.rs +++ b/src/tools/cargo/tests/testsuite/death.rs @@ -1,12 +1,12 @@ //! Tests for ctrl-C handling. +use cargo_test_support::{project, slow_cpu_multiplier}; use std::fs; use std::io::{self, Read}; use std::net::TcpListener; use std::process::{Child, Stdio}; use std::thread; - -use cargo_test_support::{project, slow_cpu_multiplier}; +use std::time; #[cargo_test] fn ctrl_c_kills_everyone() { @@ -87,6 +87,155 @@ fn ctrl_c_kills_everyone() { ); } +#[cargo_test] +fn kill_cargo_add_never_corrupts_cargo_toml() { + cargo_test_support::registry::init(); + cargo_test_support::registry::Package::new("my-package", "0.1.1+my-package").publish(); + + let with_dependency = r#" +[package] +name = "foo" +version = "0.0.1" +authors = [] + +[dependencies] +my-package = "0.1.1" +"#; + let without_dependency = r#" +[package] +name = "foo" +version = "0.0.1" +authors = [] +"#; + + for sleep_time_ms in [30, 60, 90] { + let p = project() + .file("Cargo.toml", without_dependency) + .file("src/lib.rs", "") + .build(); + + let mut cargo = p.cargo("add").arg("my-package").build_command(); + cargo + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()); + + let mut child = cargo.spawn().unwrap(); + + thread::sleep(time::Duration::from_millis(sleep_time_ms)); + + assert!(child.kill().is_ok()); + assert!(child.wait().is_ok()); + + // check the Cargo.toml + let contents = fs::read(p.root().join("Cargo.toml")).unwrap(); + + // not empty + assert_ne!( + contents, b"", + "Cargo.toml is empty, and should not be at {} milliseconds", + sleep_time_ms + ); + + // We should have the original Cargo.toml or the new one, nothing else. + if std::str::from_utf8(&contents) + .unwrap() + .contains("[dependencies]") + { + assert_eq!( + std::str::from_utf8(&contents).unwrap(), + with_dependency, + "Cargo.toml is with_dependency after add at {} milliseconds", + sleep_time_ms + ); + } else { + assert_eq!( + std::str::from_utf8(&contents).unwrap(), + without_dependency, + "Cargo.toml is without_dependency after add at {} milliseconds", + sleep_time_ms + ); + } + } +} + +#[cargo_test] +fn kill_cargo_remove_never_corrupts_cargo_toml() { + let with_dependency = r#" +[package] +name = "foo" +version = "0.0.1" +authors = [] +build = "build.rs" + +[dependencies] +bar = "0.0.1" +"#; + let without_dependency = r#" +[package] +name = "foo" +version = "0.0.1" +authors = [] +build = "build.rs" +"#; + + // This test depends on killing the cargo process at the right time to cause a failed write. + // Note that we're iterating and using the index as time in ms to sleep before killing the cargo process. + // If it is working correctly, we never fail, but can't hang out here all day... + // So we'll just run it a few times and hope for the best. + for sleep_time_ms in [30, 60, 90] { + // new basic project with a single dependency + let p = project() + .file("Cargo.toml", with_dependency) + .file("src/lib.rs", "") + .build(); + + // run cargo remove the dependency + let mut cargo = p.cargo("remove").arg("bar").build_command(); + cargo + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()); + + let mut child = cargo.spawn().unwrap(); + + thread::sleep(time::Duration::from_millis(sleep_time_ms)); + + assert!(child.kill().is_ok()); + assert!(child.wait().is_ok()); + + // check the Cargo.toml + let contents = fs::read(p.root().join("Cargo.toml")).unwrap(); + + // not empty + assert_ne!( + contents, b"", + "Cargo.toml is empty, and should not be at {} milliseconds", + sleep_time_ms + ); + + // We should have the original Cargo.toml or the new one, nothing else. + if std::str::from_utf8(&contents) + .unwrap() + .contains("[dependencies]") + { + assert_eq!( + std::str::from_utf8(&contents).unwrap(), + with_dependency, + "Cargo.toml is not the same as the original at {} milliseconds", + sleep_time_ms + ); + } else { + assert_eq!( + std::str::from_utf8(&contents).unwrap(), + without_dependency, + "Cargo.toml is not the same as expected at {} milliseconds", + sleep_time_ms + ); + } + } +} + #[cfg(unix)] pub fn ctrl_c(child: &mut Child) { let r = unsafe { libc::kill(-(child.id() as i32), libc::SIGINT) }; |