summaryrefslogtreecommitdiffstats
path: root/src/tools/cargo/tests/testsuite/death.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/cargo/tests/testsuite/death.rs')
-rw-r--r--src/tools/cargo/tests/testsuite/death.rs153
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) };