summaryrefslogtreecommitdiffstats
path: root/src/tools/cargo/tests/testsuite/install.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/cargo/tests/testsuite/install.rs')
-rw-r--r--src/tools/cargo/tests/testsuite/install.rs122
1 files changed, 119 insertions, 3 deletions
diff --git a/src/tools/cargo/tests/testsuite/install.rs b/src/tools/cargo/tests/testsuite/install.rs
index fd53b607b..16ed32ee7 100644
--- a/src/tools/cargo/tests/testsuite/install.rs
+++ b/src/tools/cargo/tests/testsuite/install.rs
@@ -3,6 +3,7 @@
use std::fs::{self, OpenOptions};
use std::io::prelude::*;
use std::path::Path;
+use std::thread;
use cargo_test_support::compare;
use cargo_test_support::cross_compile;
@@ -11,10 +12,10 @@ use cargo_test_support::registry::{self, registry_path, Package};
use cargo_test_support::{
basic_manifest, cargo_process, no_such_file_err_msg, project, project_in, symlink_supported, t,
};
-use cargo_util::ProcessError;
+use cargo_util::{ProcessBuilder, ProcessError};
use cargo_test_support::install::{
- assert_has_installed_exe, assert_has_not_installed_exe, cargo_home,
+ assert_has_installed_exe, assert_has_not_installed_exe, cargo_home, exe,
};
use cargo_test_support::paths::{self, CargoPathExt};
use std::env;
@@ -1010,7 +1011,7 @@ fn compile_failure() {
.with_status(101)
.with_stderr_contains(
"\
-[ERROR] could not compile `foo` (bin \"foo\") due to previous error
+[ERROR] could not compile `foo` (bin \"foo\") due to 1 previous error
[ERROR] failed to compile `foo v0.0.1 ([..])`, intermediate artifacts can be \
found at `[..]target`.\nTo reuse those artifacts with a future compilation, \
set the environment variable `CARGO_TARGET_DIR` to that path.
@@ -2507,3 +2508,118 @@ fn install_incompat_msrv() {
")
.with_status(101).run();
}
+
+fn assert_tracker_noexistence(key: &str) {
+ let v1_data: toml::Value =
+ toml::from_str(&fs::read_to_string(cargo_home().join(".crates.toml")).unwrap()).unwrap();
+ let v2_data: serde_json::Value =
+ serde_json::from_str(&fs::read_to_string(cargo_home().join(".crates2.json")).unwrap())
+ .unwrap();
+
+ assert!(v1_data["v1"].get(key).is_none());
+ assert!(v2_data["installs"][key].is_null());
+}
+
+#[cargo_test]
+fn uninstall_running_binary() {
+ use std::io::Write;
+
+ Package::new("foo", "0.0.1")
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ "#,
+ )
+ .file(
+ "src/main.rs",
+ r#"
+ use std::net::TcpStream;
+ use std::env::var;
+ use std::io::Read;
+ fn main() {
+ for i in 0..2 {
+ TcpStream::connect(&var("__ADDR__").unwrap()[..])
+ .unwrap()
+ .read_to_end(&mut Vec::new())
+ .unwrap();
+ }
+ }
+ "#,
+ )
+ .publish();
+
+ cargo_process("install foo")
+ .with_stderr(
+ "\
+[UPDATING] `[..]` index
+[DOWNLOADING] crates ...
+[DOWNLOADED] foo v0.0.1 (registry [..])
+[INSTALLING] foo v0.0.1
+[COMPILING] foo v0.0.1
+[FINISHED] release [optimized] target(s) in [..]
+[INSTALLING] [CWD]/home/.cargo/bin/foo[EXE]
+[INSTALLED] package `foo v0.0.1` (executable `foo[EXE]`)
+[WARNING] be sure to add `[..]` to your PATH to be able to run the installed binaries
+",
+ )
+ .run();
+ assert_has_installed_exe(cargo_home(), "foo");
+
+ let foo_bin = cargo_home().join("bin").join(exe("foo"));
+ let l = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
+ let addr = l.local_addr().unwrap().to_string();
+ let t = thread::spawn(move || {
+ ProcessBuilder::new(foo_bin)
+ .env("__ADDR__", addr)
+ .exec()
+ .unwrap();
+ });
+ let key = "foo 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)";
+
+ #[cfg(windows)]
+ {
+ // Ensure foo is running before the first `cargo uninstall` call
+ l.accept().unwrap().0.write_all(&[1]).unwrap();
+ cargo_process("uninstall foo")
+ .with_status(101)
+ .with_stderr_contains("[ERROR] failed to remove file `[CWD]/home/.cargo/bin/foo[EXE]`")
+ .run();
+ // Ensure foo is stopped before the second `cargo uninstall` call
+ l.accept().unwrap().0.write_all(&[1]).unwrap();
+ t.join().unwrap();
+ cargo_process("uninstall foo")
+ .with_stderr("[REMOVING] [CWD]/home/.cargo/bin/foo[EXE]")
+ .run();
+ };
+
+ #[cfg(not(windows))]
+ {
+ // Ensure foo is running before the first `cargo uninstall` call
+ l.accept().unwrap().0.write_all(&[1]).unwrap();
+ cargo_process("uninstall foo")
+ .with_stderr("[REMOVING] [CWD]/home/.cargo/bin/foo[EXE]")
+ .run();
+ l.accept().unwrap().0.write_all(&[1]).unwrap();
+ t.join().unwrap();
+ };
+
+ assert_has_not_installed_exe(cargo_home(), "foo");
+ assert_tracker_noexistence(key);
+
+ cargo_process("install foo")
+ .with_stderr(
+ "\
+[UPDATING] `[..]` index
+[INSTALLING] foo v0.0.1
+[COMPILING] foo v0.0.1
+[FINISHED] release [optimized] target(s) in [..]
+[INSTALLING] [CWD]/home/.cargo/bin/foo[EXE]
+[INSTALLED] package `foo v0.0.1` (executable `foo[EXE]`)
+[WARNING] be sure to add `[..]` to your PATH to be able to run the installed binaries
+",
+ )
+ .run();
+}