Skip to content

Commit ba9dd1e

Browse files
committed
Adds tests for source overlays.
1 parent 04c963a commit ba9dd1e

File tree

4 files changed

+326
-1
lines changed

4 files changed

+326
-1
lines changed

crates/cargo-test-support/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,17 @@ impl Execs {
877877
self
878878
}
879879

880+
pub fn overlay_registry(&mut self, url: &Url, path: &str) -> &mut Self {
881+
if let Some(ref mut p) = self.process_builder {
882+
let env_value = format!("{}={}", url, path);
883+
p.env(
884+
"__CARGO_TEST_DEPENDENCY_CONFUSION_VULNERABILITY_DO_NOT_USE_THIS",
885+
env_value,
886+
);
887+
}
888+
self
889+
}
890+
880891
pub fn enable_split_debuginfo_packed(&mut self) -> &mut Self {
881892
self.env("CARGO_PROFILE_DEV_SPLIT_DEBUGINFO", "packed")
882893
.env("CARGO_PROFILE_TEST_SPLIT_DEBUGINFO", "packed")

crates/cargo-test-support/src/registry.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1649,7 +1649,12 @@ impl Package {
16491649
/// Returns the path to the compressed package file.
16501650
pub fn archive_dst(&self) -> PathBuf {
16511651
if self.local {
1652-
registry_path().join(format!("{}-{}.crate", self.name, self.vers))
1652+
let path = if self.alternative {
1653+
alt_registry_path()
1654+
} else {
1655+
registry_path()
1656+
};
1657+
path.join(format!("{}-{}.crate", self.name, self.vers))
16531658
} else if self.alternative {
16541659
alt_dl_path()
16551660
.join(&self.name)

tests/testsuite/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ mod publish_lockfile;
152152
mod read_manifest;
153153
mod registry;
154154
mod registry_auth;
155+
mod registry_overlay;
155156
mod rename_deps;
156157
mod replace;
157158
mod required_features;

tests/testsuite/registry_overlay.rs

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
//! Tests for local-registry sources.
2+
3+
use cargo_test_support::project;
4+
use cargo_test_support::registry::{Package, RegistryBuilder, TestRegistry};
5+
6+
fn setup() -> (TestRegistry, String) {
7+
let alt = RegistryBuilder::new().alternative().build();
8+
(
9+
RegistryBuilder::new().http_index().build(),
10+
alt.index_url()
11+
.to_file_path()
12+
.unwrap()
13+
.into_os_string()
14+
.into_string()
15+
.unwrap(),
16+
)
17+
}
18+
19+
#[cargo_test]
20+
fn overlay_hit() {
21+
let (reg, alt_path) = setup();
22+
let p = project()
23+
.file(
24+
"Cargo.toml",
25+
r#"
26+
[package]
27+
name = "foo"
28+
version = "0.0.1"
29+
edition = "2015"
30+
authors = []
31+
32+
[dependencies]
33+
baz = "0.1.0"
34+
"#,
35+
)
36+
.file("src/main.rs", "fn main() {}")
37+
.build();
38+
39+
// baz is only in the local registry, but it gets found
40+
Package::new("baz", "0.1.1")
41+
.alternative(true)
42+
.local(true)
43+
.publish();
44+
45+
p.cargo("check")
46+
.overlay_registry(&reg.index_url(), &alt_path)
47+
.run();
48+
}
49+
50+
#[cargo_test]
51+
fn registry_version_wins() {
52+
let (reg, alt_path) = setup();
53+
let p = project()
54+
.file(
55+
"Cargo.toml",
56+
r#"
57+
[package]
58+
name = "foo"
59+
version = "0.0.1"
60+
edition = "2015"
61+
authors = []
62+
63+
[dependencies]
64+
baz = "0.1.0"
65+
"#,
66+
)
67+
.file("src/main.rs", "fn main() {}")
68+
.build();
69+
70+
// The latest one is in the main registry, so it will get chosen.
71+
Package::new("baz", "0.1.1").publish();
72+
Package::new("baz", "0.1.0")
73+
.alternative(true)
74+
.local(true)
75+
.publish();
76+
77+
p.cargo("check")
78+
.overlay_registry(&reg.index_url(), &alt_path)
79+
.with_stderr_data(
80+
"\
81+
[UPDATING] [..]
82+
[LOCKING] 2 packages to latest compatible versions
83+
[DOWNLOADING] crates ...
84+
[DOWNLOADED] baz v0.1.1 (registry [..])
85+
[CHECKING] baz v0.1.1
86+
[CHECKING] foo v0.0.1 ([ROOT]/foo)
87+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
88+
",
89+
)
90+
.run();
91+
}
92+
93+
#[cargo_test]
94+
fn overlay_version_wins() {
95+
let (reg, alt_path) = setup();
96+
let p = project()
97+
.file(
98+
"Cargo.toml",
99+
r#"
100+
[package]
101+
name = "foo"
102+
version = "0.0.1"
103+
edition = "2015"
104+
authors = []
105+
106+
[dependencies]
107+
baz = "0.1.0"
108+
"#,
109+
)
110+
.file("src/main.rs", "fn main() {}")
111+
.build();
112+
113+
// The latest one is in the overlay registry, so it will get chosen.
114+
Package::new("baz", "0.1.0").publish();
115+
Package::new("baz", "0.1.1")
116+
.alternative(true)
117+
.local(true)
118+
.publish();
119+
120+
p.cargo("check")
121+
.overlay_registry(&reg.index_url(), &alt_path)
122+
.with_stderr_data(
123+
"\
124+
[UPDATING] [..]
125+
[LOCKING] 2 packages to latest compatible versions
126+
[UNPACKING] baz v0.1.1 (registry [..])
127+
[CHECKING] baz v0.1.1
128+
[CHECKING] foo v0.0.1 ([ROOT]/foo)
129+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
130+
",
131+
)
132+
.run();
133+
}
134+
135+
#[cargo_test]
136+
fn version_collision() {
137+
let (reg, alt_path) = setup();
138+
let p = project()
139+
.file(
140+
"Cargo.toml",
141+
r#"
142+
[package]
143+
name = "foo"
144+
version = "0.0.1"
145+
edition = "2015"
146+
authors = []
147+
148+
[dependencies]
149+
baz = "0.1.0"
150+
"#,
151+
)
152+
.file("src/main.rs", "fn main() {}")
153+
.build();
154+
155+
// The one we want is in the main registry.
156+
Package::new("baz", "0.1.1").publish();
157+
Package::new("baz", "0.1.1")
158+
.alternative(true)
159+
.local(true)
160+
.publish();
161+
162+
p.cargo("check")
163+
.overlay_registry(&reg.index_url(), &alt_path)
164+
.with_status(101)
165+
.with_stderr_data(
166+
"\
167+
[UPDATING] [..]
168+
[ERROR] failed to get `baz` [..]
169+
170+
Caused by:
171+
failed to query replaced source registry `crates-io`
172+
173+
Caused by:
174+
found a package in the remote registry and the local overlay: [email protected]
175+
",
176+
)
177+
.run();
178+
}
179+
180+
#[cargo_test]
181+
fn local_depends_on_old_registry_package() {
182+
let (reg, alt_path) = setup();
183+
let p = project()
184+
.file(
185+
"Cargo.toml",
186+
r#"
187+
[package]
188+
name = "foo"
189+
version = "0.0.1"
190+
edition = "2015"
191+
authors = []
192+
193+
[dependencies]
194+
baz = "0.1.0"
195+
"#,
196+
)
197+
.file("src/main.rs", "fn main() {}")
198+
.build();
199+
200+
Package::new("baz", "0.0.1").publish();
201+
// A new local package can depend on an older version in the registry.
202+
Package::new("baz", "0.1.1")
203+
.dep("baz", "=0.0.1")
204+
.alternative(true)
205+
.local(true)
206+
.publish();
207+
208+
p.cargo("check")
209+
.overlay_registry(&reg.index_url(), &alt_path)
210+
.run();
211+
}
212+
213+
#[cargo_test]
214+
fn registry_dep_depends_on_new_local_package() {
215+
let (reg, alt_path) = setup();
216+
let p = project()
217+
.file(
218+
"Cargo.toml",
219+
r#"
220+
[package]
221+
name = "foo"
222+
version = "0.0.1"
223+
edition = "2015"
224+
authors = []
225+
226+
[dependencies]
227+
registry-package = "0.1.0"
228+
workspace-package = "0.0.1"
229+
"#,
230+
)
231+
.file("src/main.rs", "fn main() {}")
232+
.build();
233+
234+
Package::new("registry-package", "0.1.0")
235+
.dep("workspace-package", "0.1.0")
236+
.publish();
237+
// The local overlay contains an updated version of workspace-package
238+
Package::new("workspace-package", "0.1.1")
239+
.alternative(true)
240+
.local(true)
241+
.publish();
242+
243+
// The registry contains older versions of workspace-package (one of which
244+
// we depend on directly).
245+
Package::new("workspace-package", "0.1.0").publish();
246+
Package::new("workspace-package", "0.0.1").publish();
247+
248+
p.cargo("check")
249+
.overlay_registry(&reg.index_url(), &alt_path)
250+
.with_stderr_data(
251+
"\
252+
[UPDATING] [..]
253+
[LOCKING] 4 packages to latest compatible versions
254+
[ADDING] workspace-package v0.0.1 (latest: v0.1.1)
255+
[DOWNLOADING] crates ...
256+
[UNPACKING] [..]
257+
[DOWNLOADED] [..]
258+
[DOWNLOADED] [..]
259+
[CHECKING] workspace-package v0.1.1
260+
[CHECKING] workspace-package v0.0.1
261+
[CHECKING] registry-package v0.1.0
262+
[CHECKING] foo v0.0.1 [..]
263+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
264+
",
265+
)
266+
.run();
267+
}
268+
269+
// Test that we can overlay on top of alternate registries, not just crates-io.
270+
// Since the test framework only supports a single alternate registry, we repurpose
271+
// the dummy crates-io as the registry to overlay on top.
272+
#[cargo_test]
273+
fn alt_registry() {
274+
let alt = RegistryBuilder::new().http_index().alternative().build();
275+
let crates_io = RegistryBuilder::new().build();
276+
let crates_io_path = crates_io
277+
.index_url()
278+
.to_file_path()
279+
.unwrap()
280+
.into_os_string()
281+
.into_string()
282+
.unwrap();
283+
284+
let p = project()
285+
.file(
286+
"Cargo.toml",
287+
r#"
288+
[package]
289+
name = "foo"
290+
version = "0.0.1"
291+
edition = "2015"
292+
authors = []
293+
294+
[dependencies]
295+
baz = { version = "0.1.0", registry = "alternative" }
296+
"#,
297+
)
298+
.file("src/main.rs", "fn main() {}")
299+
.build();
300+
301+
// This package isn't used, but publishing it forces the creation of the registry index.
302+
Package::new("bar", "0.0.1").local(true).publish();
303+
Package::new("baz", "0.1.1").alternative(true).publish();
304+
305+
p.cargo("check")
306+
.overlay_registry(&alt.index_url(), &crates_io_path)
307+
.run();
308+
}

0 commit comments

Comments
 (0)