From 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 14:41:41 +0200 Subject: Merging upstream version 1.70.0+dfsg2. Signed-off-by: Daniel Baumann --- src/tools/cargo/tests/testsuite/corrupt_git.rs | 159 +++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 src/tools/cargo/tests/testsuite/corrupt_git.rs (limited to 'src/tools/cargo/tests/testsuite/corrupt_git.rs') diff --git a/src/tools/cargo/tests/testsuite/corrupt_git.rs b/src/tools/cargo/tests/testsuite/corrupt_git.rs new file mode 100644 index 000000000..2569e460b --- /dev/null +++ b/src/tools/cargo/tests/testsuite/corrupt_git.rs @@ -0,0 +1,159 @@ +//! Tests for corrupt git repos. + +use cargo_test_support::paths; +use cargo_test_support::{basic_manifest, git, project}; +use cargo_util::paths as cargopaths; +use std::fs; +use std::path::{Path, PathBuf}; + +#[cargo_test] +fn deleting_database_files() { + let project = project(); + let git_project = git::new("bar", |project| { + project + .file("Cargo.toml", &basic_manifest("bar", "0.5.0")) + .file("src/lib.rs", "") + }); + + let project = project + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.5.0" + authors = [] + + [dependencies] + bar = {{ git = '{}' }} + "#, + git_project.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + project.cargo("check").run(); + + let mut files = Vec::new(); + find_files(&paths::home().join(".cargo/git/db"), &mut files); + assert!(!files.is_empty()); + + let log = "cargo::sources::git=trace"; + for file in files { + if !file.exists() { + continue; + } + println!("deleting {}", file.display()); + cargopaths::remove_file(&file).unwrap(); + project.cargo("check -v").env("CARGO_LOG", log).run(); + + if !file.exists() { + continue; + } + println!("truncating {}", file.display()); + make_writable(&file); + fs::OpenOptions::new() + .write(true) + .open(&file) + .unwrap() + .set_len(2) + .unwrap(); + project.cargo("check -v").env("CARGO_LOG", log).run(); + } +} + +#[cargo_test] +fn deleting_checkout_files() { + let project = project(); + let git_project = git::new("bar", |project| { + project + .file("Cargo.toml", &basic_manifest("bar", "0.5.0")) + .file("src/lib.rs", "") + }); + + let project = project + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.5.0" + authors = [] + + [dependencies] + bar = {{ git = '{}' }} + "#, + git_project.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + project.cargo("check").run(); + + let dir = paths::home() + .join(".cargo/git/checkouts") + // get the first entry in the checkouts dir for the package's location + .read_dir() + .unwrap() + .next() + .unwrap() + .unwrap() + .path() + // get the first child of that checkout dir for our checkout + .read_dir() + .unwrap() + .next() + .unwrap() + .unwrap() + .path() + // and throw on .git to corrupt things + .join(".git"); + let mut files = Vec::new(); + find_files(&dir, &mut files); + assert!(!files.is_empty()); + + let log = "cargo::sources::git=trace"; + for file in files { + if !file.exists() { + continue; + } + println!("deleting {}", file.display()); + cargopaths::remove_file(&file).unwrap(); + project.cargo("check -v").env("CARGO_LOG", log).run(); + + if !file.exists() { + continue; + } + println!("truncating {}", file.display()); + make_writable(&file); + fs::OpenOptions::new() + .write(true) + .open(&file) + .unwrap() + .set_len(2) + .unwrap(); + project.cargo("check -v").env("CARGO_LOG", log).run(); + } +} + +fn make_writable(path: &Path) { + let mut p = path.metadata().unwrap().permissions(); + p.set_readonly(false); + fs::set_permissions(path, p).unwrap(); +} + +fn find_files(path: &Path, dst: &mut Vec) { + for e in path.read_dir().unwrap() { + let e = e.unwrap(); + let path = e.path(); + if e.file_type().unwrap().is_dir() { + find_files(&path, dst); + } else { + dst.push(path); + } + } +} -- cgit v1.2.3