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/lockfile_compat.rs | 890 +++++++++++++++++++++ 1 file changed, 890 insertions(+) create mode 100644 src/tools/cargo/tests/testsuite/lockfile_compat.rs (limited to 'src/tools/cargo/tests/testsuite/lockfile_compat.rs') diff --git a/src/tools/cargo/tests/testsuite/lockfile_compat.rs b/src/tools/cargo/tests/testsuite/lockfile_compat.rs new file mode 100644 index 000000000..aad8723c3 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/lockfile_compat.rs @@ -0,0 +1,890 @@ +//! Tests for supporting older versions of the Cargo.lock file format. + +use cargo_test_support::compare::assert_match_exact; +use cargo_test_support::git; +use cargo_test_support::registry::Package; +use cargo_test_support::{basic_lib_manifest, basic_manifest, project}; + +#[cargo_test] +fn oldest_lockfile_still_works() { + let cargo_commands = vec!["build", "update"]; + for cargo_command in cargo_commands { + oldest_lockfile_still_works_with_command(cargo_command); + } +} + +fn oldest_lockfile_still_works_with_command(cargo_command: &str) { + Package::new("bar", "0.1.0").publish(); + + let expected_lockfile = r#"# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "[..]" + +[[package]] +name = "foo" +version = "0.0.1" +dependencies = [ + "bar", +] +"#; + + let old_lockfile = r#" +[root] +name = "foo" +version = "0.0.1" +dependencies = [ + "bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +"#; + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "0.1.0" + "#, + ) + .file("src/lib.rs", "") + .file("Cargo.lock", old_lockfile) + .build(); + + p.cargo(cargo_command).run(); + + let lock = p.read_lockfile(); + assert_match_exact(expected_lockfile, &lock); +} + +#[cargo_test] +fn frozen_flag_preserves_old_lockfile() { + let cksum = Package::new("bar", "0.1.0").publish(); + + let old_lockfile = format!( + r#"[root] +name = "foo" +version = "0.0.1" +dependencies = [ + "bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "{}" +"#, + cksum, + ); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "0.1.0" + "#, + ) + .file("src/lib.rs", "") + .file("Cargo.lock", &old_lockfile) + .build(); + + p.cargo("check --locked").run(); + + let lock = p.read_lockfile(); + assert_match_exact(&old_lockfile, &lock); +} + +#[cargo_test] +fn totally_wild_checksums_works() { + Package::new("bar", "0.1.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "0.1.0" + "#, + ) + .file("src/lib.rs", "") + .file( + "Cargo.lock", + r#" +[[package]] +name = "foo" +version = "0.0.1" +dependencies = [ + "bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum baz 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "checksum" +"checksum bar 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "checksum" +"#, + ); + + let p = p.build(); + + p.cargo("check").run(); + + let lock = p.read_lockfile(); + assert_match_exact( + r#"# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "[..]" + +[[package]] +name = "foo" +version = "0.0.1" +dependencies = [ + "bar", +] +"#, + &lock, + ); +} + +#[cargo_test] +fn wrong_checksum_is_an_error() { + Package::new("bar", "0.1.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "0.1.0" + "#, + ) + .file("src/lib.rs", "") + .file( + "Cargo.lock", + r#" +[[package]] +name = "foo" +version = "0.0.1" +dependencies = [ + "bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "checksum" +"#, + ); + + let p = p.build(); + + p.cargo("check") + .with_status(101) + .with_stderr( + "\ +[UPDATING] `[..]` index +error: checksum for `bar v0.1.0` changed between lock files + +this could be indicative of a few possible errors: + + * the lock file is corrupt + * a replacement source in use (e.g., a mirror) returned a different checksum + * the source itself may be corrupt in one way or another + +unable to verify that `bar v0.1.0` is the same as when the lockfile was generated + +", + ) + .run(); +} + +// If the checksum is unlisted in the lock file (e.g., ) yet we can +// calculate it (e.g., it's a registry dep), then we should in theory just fill +// it in. +#[cargo_test] +fn unlisted_checksum_is_bad_if_we_calculate() { + Package::new("bar", "0.1.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "0.1.0" + "#, + ) + .file("src/lib.rs", "") + .file( + "Cargo.lock", + r#" +[[package]] +name = "foo" +version = "0.0.1" +dependencies = [ + "bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "" +"#, + ); + let p = p.build(); + + p.cargo("fetch") + .with_status(101) + .with_stderr( + "\ +[UPDATING] `[..]` index +error: checksum for `bar v0.1.0` was not previously calculated, but a checksum \ +could now be calculated + +this could be indicative of a few possible situations: + + * the source `[..]` did not previously support checksums, + but was replaced with one that does + * newer Cargo implementations know how to checksum this source, but this + older implementation does not + * the lock file is corrupt + +", + ) + .run(); +} + +// If the checksum is listed in the lock file yet we cannot calculate it (e.g., +// Git dependencies as of today), then make sure we choke. +#[cargo_test] +fn listed_checksum_bad_if_we_cannot_compute() { + let git = git::new("bar", |p| { + p.file("Cargo.toml", &basic_manifest("bar", "0.1.0")) + .file("src/lib.rs", "") + }); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = {{ git = '{}' }} + "#, + git.url() + ), + ) + .file("src/lib.rs", "") + .file( + "Cargo.lock", + &format!( + r#" +[[package]] +name = "foo" +version = "0.0.1" +dependencies = [ + "bar 0.1.0 (git+{0})" +] + +[[package]] +name = "bar" +version = "0.1.0" +source = "git+{0}" + +[metadata] +"checksum bar 0.1.0 (git+{0})" = "checksum" +"#, + git.url() + ), + ); + + let p = p.build(); + + p.cargo("fetch") + .with_status(101) + .with_stderr( + "\ +[UPDATING] git repository `[..]` +error: checksum for `bar v0.1.0 ([..])` could not be calculated, but a \ +checksum is listed in the existing lock file[..] + +this could be indicative of a few possible situations: + + * the source `[..]` supports checksums, + but was replaced with one that doesn't + * the lock file is corrupt + +unable to verify that `bar v0.1.0 ([..])` is the same as when the lockfile was generated + +", + ) + .run(); +} + +#[cargo_test] +fn current_lockfile_format() { + Package::new("bar", "0.1.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "0.1.0" + "#, + ) + .file("src/lib.rs", ""); + let p = p.build(); + + p.cargo("check").run(); + + let actual = p.read_lockfile(); + + let expected = "\ +# This file is automatically @generated by Cargo.\n# It is not intended for manual editing. +version = 3 + +[[package]] +name = \"bar\" +version = \"0.1.0\" +source = \"registry+https://github.com/rust-lang/crates.io-index\" +checksum = \"[..]\" + +[[package]] +name = \"foo\" +version = \"0.0.1\" +dependencies = [ + \"bar\", +] +"; + assert_match_exact(expected, &actual); +} + +#[cargo_test] +fn lockfile_without_root() { + Package::new("bar", "0.1.0").publish(); + + let lockfile = r#" +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "foo" +version = "0.0.1" +dependencies = [ + "bar", +] +"#; + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "0.1.0" + "#, + ) + .file("src/lib.rs", "") + .file("Cargo.lock", lockfile); + + let p = p.build(); + + p.cargo("check").run(); + + let lock = p.read_lockfile(); + assert_match_exact( + r#"# [..] +# [..] +version = 3 + +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "[..]" + +[[package]] +name = "foo" +version = "0.0.1" +dependencies = [ + "bar", +] +"#, + &lock, + ); +} + +#[cargo_test] +fn locked_correct_error() { + Package::new("bar", "0.1.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "0.1.0" + "#, + ) + .file("src/lib.rs", ""); + let p = p.build(); + + p.cargo("check --locked") + .with_status(101) + .with_stderr( + "\ +[UPDATING] `[..]` index +error: the lock file [CWD]/Cargo.lock needs to be updated but --locked was passed to prevent this +If you want to try to generate the lock file without accessing the network, \ +remove the --locked flag and use --offline instead. +", + ) + .run(); +} + +#[cargo_test] +fn v2_format_preserved() { + let cksum = Package::new("bar", "0.1.0").publish(); + + let lockfile = format!( + r#"# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "{}" + +[[package]] +name = "foo" +version = "0.0.1" +dependencies = [ + "bar", +] +"#, + cksum + ); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "0.1.0" + "#, + ) + .file("src/lib.rs", "") + .file("Cargo.lock", &lockfile) + .build(); + + p.cargo("fetch").run(); + + let lock = p.read_lockfile(); + assert_match_exact(&lockfile, &lock); +} + +#[cargo_test] +fn v2_path_and_crates_io() { + let cksum010 = Package::new("a", "0.1.0").publish(); + let cksum020 = Package::new("a", "0.2.0").publish(); + + let lockfile = format!( + r#"# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "a" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "{}" + +[[package]] +name = "a" +version = "0.2.0" + +[[package]] +name = "a" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "{}" + +[[package]] +name = "foo" +version = "0.0.1" +dependencies = [ + "a 0.1.0", + "a 0.2.0", + "a 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] +"#, + cksum010, cksum020, + ); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + a = { path = 'a' } + b = { version = "0.1", package = 'a' } + c = { version = "0.2", package = 'a' } + "#, + ) + .file("src/lib.rs", "") + .file( + "a/Cargo.toml", + r#" + [package] + name = "a" + version = "0.2.0" + "#, + ) + .file("a/src/lib.rs", "") + .file("Cargo.lock", &lockfile) + .build(); + + p.cargo("fetch").run(); + p.cargo("fetch").run(); + + let lock = p.read_lockfile(); + assert_match_exact(&lockfile, &lock); +} + +#[cargo_test] +fn v3_and_git() { + let (git_project, repo) = git::new_repo("dep1", |project| { + project + .file("Cargo.toml", &basic_lib_manifest("dep1")) + .file("src/lib.rs", "") + }); + let head_id = repo.head().unwrap().target().unwrap(); + + let lockfile = format!( + r#"# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "dep1" +version = "0.5.0" +source = "git+{}?branch=master#{}" + +[[package]] +name = "foo" +version = "0.0.1" +dependencies = [ + "dep1", +] +"#, + git_project.url(), + head_id, + ); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + dep1 = {{ git = '{}', branch = 'master' }} + "#, + git_project.url(), + ), + ) + .file("src/lib.rs", "") + .file("Cargo.lock", "version = 3") + .build(); + + p.cargo("fetch").run(); + + let lock = p.read_lockfile(); + assert_match_exact(&lockfile, &lock); +} + +#[cargo_test] +fn lock_from_the_future() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + "#, + ) + .file("src/lib.rs", "") + .file("Cargo.lock", "version = 10000000") + .build(); + + p.cargo("fetch") + .with_stderr( + "\ +error: failed to parse lock file at: [..] + +Caused by: + lock file version `10000000` was found, but this version of Cargo does not \ + understand this lock file, perhaps Cargo needs to be updated? +", + ) + .with_status(101) + .run(); +} + +#[cargo_test] +fn preserve_old_format_if_no_update_needed() { + let cksum = Package::new("bar", "0.1.0").publish(); + let lockfile = format!( + r#"# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "foo" +version = "0.0.1" +dependencies = [ + "bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "{}" +"#, + cksum + ); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "0.1.0" + "#, + ) + .file("src/lib.rs", "") + .file("Cargo.lock", &lockfile) + .build(); + + p.cargo("check --locked").run(); +} + +#[cargo_test] +fn same_name_version_different_sources() { + let cksum = Package::new("foo", "0.1.0").publish(); + let (git_project, repo) = git::new_repo("dep1", |project| { + project + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + "#, + ) + .file("src/lib.rs", "") + }); + let head_id = repo.head().unwrap().target().unwrap(); + + // Lockfile was generated with Rust 1.51 + let lockfile = format!( + r#"# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "foo" +version = "0.1.0" +dependencies = [ + "foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "foo 0.1.0 (git+{url})", +] + +[[package]] +name = "foo" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "{cksum}" + +[[package]] +name = "foo" +version = "0.1.0" +source = "git+{url}#{sha}" +"#, + sha = head_id, + url = git_project.url(), + cksum = cksum + ); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + foo = "0.1.0" + foo2 = {{ git = '{}', package = 'foo' }} + "#, + git_project.url(), + ), + ) + .file("src/lib.rs", "") + .file("Cargo.lock", &lockfile) + .build(); + + p.cargo("check").run(); + + assert_eq!(p.read_file("Cargo.lock"), lockfile); +} + +#[cargo_test] +fn bad_data_in_lockfile_error_meg() { + Package::new("bar", "0.0.1").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "test" + version = "0.0.0" + + [dependencies] + bar = "*" + "#, + ) + .file("src/main.rs", "fn main() {}") + .file( + "Cargo.lock", + r#"# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1b9346248cf3391ead604c4407258d327c28e37209f6d56127598165165dda" + +[[package]] +name = "test" +version = "0.0.0" +dependencies = [ + "bar", +]"#, + ) + .build(); + p.cargo("check") + .with_status(101) + .with_stderr( + "\ +[..] +[ERROR] failed to select a version for the requirement `bar = \"*\"` (locked to 0.1.0) +candidate versions found which didn't match: 0.0.1 +location searched: `dummy-registry` index (which is replacing registry `crates-io`) +required by package `test v0.0.0 ([..])` +perhaps a crate was updated and forgotten to be re-vendored? +", + ) + .run(); +} -- cgit v1.2.3