]> git.proxmox.com Git - rustc.git/blame - src/tools/cargo/tests/testsuite/registry.rs
New upstream version 1.74.1+dfsg1
[rustc.git] / src / tools / cargo / tests / testsuite / registry.rs
CommitLineData
0a29b90c
FG
1//! Tests for normal registry dependencies.
2
3use cargo::core::SourceId;
4use cargo_test_support::cargo_process;
5use cargo_test_support::paths::{self, CargoPathExt};
6use cargo_test_support::registry::{
7 self, registry_path, Dependency, Package, RegistryBuilder, Response, TestRegistry,
8};
9use cargo_test_support::{basic_manifest, project};
10use cargo_test_support::{git, install::cargo_home, t};
11use cargo_util::paths::remove_dir_all;
12use std::fmt::Write;
13use std::fs::{self, File};
14use std::path::Path;
15use std::sync::Arc;
16use std::sync::Mutex;
17
18fn setup_http() -> TestRegistry {
19 RegistryBuilder::new().http_index().build()
20}
21
22#[cargo_test]
23fn test_server_stops() {
24 let server = setup_http();
25 server.join(); // ensure the server fully shuts down
26}
27
28#[cargo_test]
29fn simple_http() {
30 let _server = setup_http();
31 simple();
32}
33
34#[cargo_test]
35fn simple_git() {
36 simple();
37}
38
39fn simple() {
40 let p = project()
41 .file(
42 "Cargo.toml",
43 r#"
44 [package]
45 name = "foo"
46 version = "0.0.1"
47 authors = []
48
49 [dependencies]
50 bar = ">= 0.0.0"
51 "#,
52 )
53 .file("src/main.rs", "fn main() {}")
54 .build();
55
56 Package::new("bar", "0.0.1").publish();
57
58 p.cargo("check")
59 .with_stderr(
60 "\
61[UPDATING] `dummy-registry` index
62[DOWNLOADING] crates ...
63[DOWNLOADED] bar v0.0.1 (registry `dummy-registry`)
64[CHECKING] bar v0.0.1
65[CHECKING] foo v0.0.1 ([CWD])
66[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
67",
68 )
69 .run();
70
71 p.cargo("clean").run();
72
73 assert!(paths::home().join(".cargo/registry/CACHEDIR.TAG").is_file());
74
75 // Don't download a second time
76 p.cargo("check")
77 .with_stderr(
78 "\
79[CHECKING] bar v0.0.1
80[CHECKING] foo v0.0.1 ([CWD])
81[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
82",
83 )
84 .run();
85}
86
87#[cargo_test]
88fn deps_http() {
89 let _server = setup_http();
90 deps();
91}
92
93#[cargo_test]
94fn deps_git() {
95 deps();
96}
97
98fn deps() {
99 let p = project()
100 .file(
101 "Cargo.toml",
102 r#"
103 [package]
104 name = "foo"
105 version = "0.0.1"
106 authors = []
107
108 [dependencies]
109 bar = ">= 0.0.0"
110 "#,
111 )
112 .file("src/main.rs", "fn main() {}")
113 .build();
114
115 Package::new("baz", "0.0.1").publish();
116 Package::new("bar", "0.0.1").dep("baz", "*").publish();
117
118 p.cargo("check")
119 .with_stderr(
120 "\
121[UPDATING] `dummy-registry` index
122[DOWNLOADING] crates ...
123[DOWNLOADED] [..] v0.0.1 (registry `dummy-registry`)
124[DOWNLOADED] [..] v0.0.1 (registry `dummy-registry`)
125[CHECKING] baz v0.0.1
126[CHECKING] bar v0.0.1
127[CHECKING] foo v0.0.1 ([CWD])
128[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
129",
130 )
131 .run();
132
133 assert!(paths::home().join(".cargo/registry/CACHEDIR.TAG").is_file());
134}
135
136#[cargo_test]
137fn nonexistent_http() {
138 let _server = setup_http();
139 nonexistent();
140}
141
142#[cargo_test]
143fn nonexistent_git() {
144 nonexistent();
145}
146
147fn nonexistent() {
148 Package::new("init", "0.0.1").publish();
149
150 let p = project()
151 .file(
152 "Cargo.toml",
153 r#"
154 [package]
155 name = "foo"
156 version = "0.0.1"
157 authors = []
158
159 [dependencies]
160 nonexistent = ">= 0.0.0"
161 "#,
162 )
163 .file("src/main.rs", "fn main() {}")
164 .build();
165
166 p.cargo("check")
167 .with_status(101)
168 .with_stderr(
169 "\
170[UPDATING] [..] index
171error: no matching package named `nonexistent` found
172location searched: registry [..]
173required by package `foo v0.0.1 ([..])`
174",
175 )
176 .run();
177}
178
179#[cargo_test]
180fn wrong_case_http() {
181 let _server = setup_http();
182 wrong_case();
183}
184
185#[cargo_test]
186fn wrong_case_git() {
187 wrong_case();
188}
189
190fn wrong_case() {
191 Package::new("init", "0.0.1").publish();
192
193 let p = project()
194 .file(
195 "Cargo.toml",
196 r#"
197 [package]
198 name = "foo"
199 version = "0.0.1"
200 authors = []
201
202 [dependencies]
203 Init = ">= 0.0.0"
204 "#,
205 )
206 .file("src/main.rs", "fn main() {}")
207 .build();
208
209 // #5678 to make this work
210 p.cargo("check")
211 .with_status(101)
212 .with_stderr(
213 "\
214[UPDATING] [..] index
215error: no matching package found
216searched package name: `Init`
217perhaps you meant: init
218location searched: registry [..]
219required by package `foo v0.0.1 ([..])`
220",
221 )
222 .run();
223}
224
225#[cargo_test]
226fn mis_hyphenated_http() {
227 let _server = setup_http();
228 mis_hyphenated();
229}
230
231#[cargo_test]
232fn mis_hyphenated_git() {
233 mis_hyphenated();
234}
235
236fn mis_hyphenated() {
237 Package::new("mis-hyphenated", "0.0.1").publish();
238
239 let p = project()
240 .file(
241 "Cargo.toml",
242 r#"
243 [package]
244 name = "foo"
245 version = "0.0.1"
246 authors = []
247
248 [dependencies]
249 mis_hyphenated = ">= 0.0.0"
250 "#,
251 )
252 .file("src/main.rs", "fn main() {}")
253 .build();
254
255 // #2775 to make this work
256 p.cargo("check")
257 .with_status(101)
258 .with_stderr(
259 "\
260[UPDATING] [..] index
261error: no matching package found
262searched package name: `mis_hyphenated`
263perhaps you meant: mis-hyphenated
264location searched: registry [..]
265required by package `foo v0.0.1 ([..])`
266",
267 )
268 .run();
269}
270
271#[cargo_test]
272fn wrong_version_http() {
273 let _server = setup_http();
274 wrong_version();
275}
276
277#[cargo_test]
278fn wrong_version_git() {
279 wrong_version();
280}
281
282fn wrong_version() {
283 let p = project()
284 .file(
285 "Cargo.toml",
286 r#"
287 [package]
288 name = "foo"
289 version = "0.0.1"
290 authors = []
291
292 [dependencies]
293 foo = ">= 1.0.0"
294 "#,
295 )
296 .file("src/main.rs", "fn main() {}")
297 .build();
298
299 Package::new("foo", "0.0.1").publish();
300 Package::new("foo", "0.0.2").publish();
301
302 p.cargo("check")
303 .with_status(101)
304 .with_stderr_contains(
305 "\
306error: failed to select a version for the requirement `foo = \">=1.0.0\"`
307candidate versions found which didn't match: 0.0.2, 0.0.1
308location searched: `[..]` index (which is replacing registry `[..]`)
309required by package `foo v0.0.1 ([..])`
310",
311 )
312 .run();
313
314 Package::new("foo", "0.0.3").publish();
315 Package::new("foo", "0.0.4").publish();
316
317 p.cargo("check")
318 .with_status(101)
319 .with_stderr_contains(
320 "\
321error: failed to select a version for the requirement `foo = \">=1.0.0\"`
322candidate versions found which didn't match: 0.0.4, 0.0.3, 0.0.2, ...
323location searched: `[..]` index (which is replacing registry `[..]`)
324required by package `foo v0.0.1 ([..])`
325",
326 )
327 .run();
328}
329
330#[cargo_test]
331fn bad_cksum_http() {
332 let _server = setup_http();
333 bad_cksum();
334}
335
336#[cargo_test]
337fn bad_cksum_git() {
338 bad_cksum();
339}
340
341fn bad_cksum() {
342 let p = project()
343 .file(
344 "Cargo.toml",
345 r#"
346 [package]
347 name = "foo"
348 version = "0.0.1"
349 authors = []
350
351 [dependencies]
352 bad-cksum = ">= 0.0.0"
353 "#,
354 )
355 .file("src/main.rs", "fn main() {}")
356 .build();
357
358 let pkg = Package::new("bad-cksum", "0.0.1");
359 pkg.publish();
360 t!(File::create(&pkg.archive_dst()));
361
362 p.cargo("check -v")
363 .with_status(101)
364 .with_stderr(
365 "\
366[UPDATING] [..] index
367[DOWNLOADING] crates ...
368[DOWNLOADED] bad-cksum [..]
369[ERROR] failed to download replaced source registry `crates-io`
370
371Caused by:
372 failed to verify the checksum of `bad-cksum v0.0.1 (registry `dummy-registry`)`
373",
374 )
375 .run();
376}
377
378#[cargo_test]
379fn update_registry_http() {
380 let _server = setup_http();
381 update_registry();
382}
383
384#[cargo_test]
385fn update_registry_git() {
386 update_registry();
387}
388
389fn update_registry() {
390 Package::new("init", "0.0.1").publish();
391
392 let p = project()
393 .file(
394 "Cargo.toml",
395 r#"
396 [package]
397 name = "foo"
398 version = "0.0.1"
399 authors = []
400
401 [dependencies]
402 notyet = ">= 0.0.0"
403 "#,
404 )
405 .file("src/main.rs", "fn main() {}")
406 .build();
407
408 p.cargo("check")
409 .with_status(101)
410 .with_stderr_contains(
411 "\
412error: no matching package named `notyet` found
413location searched: registry `[..]`
414required by package `foo v0.0.1 ([..])`
415",
416 )
417 .run();
418
419 Package::new("notyet", "0.0.1").publish();
420
421 p.cargo("check")
422 .with_stderr(
423 "\
424[UPDATING] `dummy-registry` index
425[DOWNLOADING] crates ...
426[DOWNLOADED] notyet v0.0.1 (registry `dummy-registry`)
427[CHECKING] notyet v0.0.1
428[CHECKING] foo v0.0.1 ([CWD])
429[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
430",
431 )
432 .run();
433}
434
435#[cargo_test]
436fn package_with_path_deps_http() {
437 let _server = setup_http();
438 package_with_path_deps();
439}
440
441#[cargo_test]
442fn package_with_path_deps_git() {
443 package_with_path_deps();
444}
445
446fn package_with_path_deps() {
447 Package::new("init", "0.0.1").publish();
448
449 let p = project()
450 .file(
451 "Cargo.toml",
452 r#"
453 [package]
454 name = "foo"
455 version = "0.0.1"
456 authors = []
457 license = "MIT"
458 description = "foo"
459 repository = "bar"
460
461 [dependencies.notyet]
462 version = "0.0.1"
463 path = "notyet"
464 "#,
465 )
466 .file("src/main.rs", "fn main() {}")
467 .file("notyet/Cargo.toml", &basic_manifest("notyet", "0.0.1"))
468 .file("notyet/src/lib.rs", "")
469 .build();
470
471 p.cargo("package")
472 .with_status(101)
473 .with_stderr_contains(
474 "\
475[PACKAGING] foo [..]
476[UPDATING] [..]
477[ERROR] failed to prepare local package for uploading
478
479Caused by:
480 no matching package named `notyet` found
481 location searched: registry `crates-io`
482 required by package `foo v0.0.1 [..]`
483",
484 )
485 .run();
486
487 Package::new("notyet", "0.0.1").publish();
488
489 p.cargo("package")
490 .with_stderr(
491 "\
492[PACKAGING] foo v0.0.1 ([CWD])
493[UPDATING] `[..]` index
494[VERIFYING] foo v0.0.1 ([CWD])
495[DOWNLOADING] crates ...
496[DOWNLOADED] notyet v0.0.1 (registry `dummy-registry`)
497[COMPILING] notyet v0.0.1
498[COMPILING] foo v0.0.1 ([CWD][..])
499[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
500[PACKAGED] [..]
501",
502 )
503 .run();
504}
505
506#[cargo_test]
507fn lockfile_locks_http() {
508 let _server = setup_http();
509 lockfile_locks();
510}
511
512#[cargo_test]
513fn lockfile_locks_git() {
514 lockfile_locks();
515}
516
517fn lockfile_locks() {
518 let p = project()
519 .file(
520 "Cargo.toml",
521 r#"
522 [package]
523 name = "foo"
524 version = "0.0.1"
525 authors = []
526
527 [dependencies]
528 bar = "*"
529 "#,
530 )
531 .file("src/main.rs", "fn main() {}")
532 .build();
533
534 Package::new("bar", "0.0.1").publish();
535
536 p.cargo("check")
537 .with_stderr(
538 "\
539[UPDATING] `[..]` index
540[DOWNLOADING] crates ...
541[DOWNLOADED] bar v0.0.1 (registry `dummy-registry`)
542[CHECKING] bar v0.0.1
543[CHECKING] foo v0.0.1 ([CWD])
544[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
545",
546 )
547 .run();
548
549 p.root().move_into_the_past();
550 Package::new("bar", "0.0.2").publish();
551
552 p.cargo("check").with_stdout("").run();
553}
554
555#[cargo_test]
556fn lockfile_locks_transitively_http() {
557 let _server = setup_http();
558 lockfile_locks_transitively();
559}
560
561#[cargo_test]
562fn lockfile_locks_transitively_git() {
563 lockfile_locks_transitively();
564}
565
566fn lockfile_locks_transitively() {
567 let p = project()
568 .file(
569 "Cargo.toml",
570 r#"
571 [package]
572 name = "foo"
573 version = "0.0.1"
574 authors = []
575
576 [dependencies]
577 bar = "*"
578 "#,
579 )
580 .file("src/main.rs", "fn main() {}")
581 .build();
582
583 Package::new("baz", "0.0.1").publish();
584 Package::new("bar", "0.0.1").dep("baz", "*").publish();
585
586 p.cargo("check")
587 .with_stderr(
588 "\
589[UPDATING] `[..]` index
590[DOWNLOADING] crates ...
591[DOWNLOADED] [..] v0.0.1 (registry `dummy-registry`)
592[DOWNLOADED] [..] v0.0.1 (registry `dummy-registry`)
593[CHECKING] baz v0.0.1
594[CHECKING] bar v0.0.1
595[CHECKING] foo v0.0.1 ([CWD])
596[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
597",
598 )
599 .run();
600
601 p.root().move_into_the_past();
602 Package::new("baz", "0.0.2").publish();
603 Package::new("bar", "0.0.2").dep("baz", "*").publish();
604
605 p.cargo("check").with_stdout("").run();
606}
607
608#[cargo_test]
609fn yanks_are_not_used_http() {
610 let _server = setup_http();
611 yanks_are_not_used();
612}
613
614#[cargo_test]
615fn yanks_are_not_used_git() {
616 yanks_are_not_used();
617}
618
619fn yanks_are_not_used() {
620 let p = project()
621 .file(
622 "Cargo.toml",
623 r#"
624 [package]
625 name = "foo"
626 version = "0.0.1"
627 authors = []
628
629 [dependencies]
630 bar = "*"
631 "#,
632 )
633 .file("src/main.rs", "fn main() {}")
634 .build();
635
636 Package::new("baz", "0.0.1").publish();
637 Package::new("baz", "0.0.2").yanked(true).publish();
638 Package::new("bar", "0.0.1").dep("baz", "*").publish();
639 Package::new("bar", "0.0.2")
640 .dep("baz", "*")
641 .yanked(true)
642 .publish();
643
644 p.cargo("check")
645 .with_stderr(
646 "\
647[UPDATING] `[..]` index
648[DOWNLOADING] crates ...
649[DOWNLOADED] [..] v0.0.1 (registry `dummy-registry`)
650[DOWNLOADED] [..] v0.0.1 (registry `dummy-registry`)
651[CHECKING] baz v0.0.1
652[CHECKING] bar v0.0.1
653[CHECKING] foo v0.0.1 ([CWD])
654[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
655",
656 )
657 .run();
658}
659
660#[cargo_test]
661fn relying_on_a_yank_is_bad_http() {
662 let _server = setup_http();
663 relying_on_a_yank_is_bad();
664}
665
666#[cargo_test]
667fn relying_on_a_yank_is_bad_git() {
668 relying_on_a_yank_is_bad();
669}
670
671fn relying_on_a_yank_is_bad() {
672 let p = project()
673 .file(
674 "Cargo.toml",
675 r#"
676 [package]
677 name = "foo"
678 version = "0.0.1"
679 authors = []
680
681 [dependencies]
682 bar = "*"
683 "#,
684 )
685 .file("src/main.rs", "fn main() {}")
686 .build();
687
688 Package::new("baz", "0.0.1").publish();
689 Package::new("baz", "0.0.2").yanked(true).publish();
690 Package::new("bar", "0.0.1").dep("baz", "=0.0.2").publish();
691
692 p.cargo("check")
693 .with_status(101)
694 .with_stderr_contains(
695 "\
696error: failed to select a version for the requirement `baz = \"=0.0.2\"`
697candidate versions found which didn't match: 0.0.1
698location searched: `[..]` index (which is replacing registry `[..]`)
699required by package `bar v0.0.1`
700 ... which satisfies dependency `bar = \"*\"` of package `foo [..]`
701",
702 )
703 .run();
704}
705
706#[cargo_test]
707fn yanks_in_lockfiles_are_ok_http() {
708 let _server = setup_http();
709 yanks_in_lockfiles_are_ok();
710}
711
712#[cargo_test]
713fn yanks_in_lockfiles_are_ok_git() {
714 yanks_in_lockfiles_are_ok();
715}
716
717fn yanks_in_lockfiles_are_ok() {
718 let p = project()
719 .file(
720 "Cargo.toml",
721 r#"
722 [package]
723 name = "foo"
724 version = "0.0.1"
725 authors = []
726
727 [dependencies]
728 bar = "*"
729 "#,
730 )
731 .file("src/main.rs", "fn main() {}")
732 .build();
733
734 Package::new("bar", "0.0.1").publish();
735
736 p.cargo("check").run();
737
738 registry_path().join("3").rm_rf();
739
740 Package::new("bar", "0.0.1").yanked(true).publish();
741
742 p.cargo("check").with_stdout("").run();
743
744 p.cargo("update")
745 .with_status(101)
746 .with_stderr_contains(
747 "\
748error: no matching package named `bar` found
749location searched: registry [..]
750required by package `foo v0.0.1 ([..])`
751",
752 )
753 .run();
754}
755
756#[cargo_test]
757fn yanks_in_lockfiles_are_ok_for_other_update_http() {
758 let _server = setup_http();
759 yanks_in_lockfiles_are_ok_for_other_update();
760}
761
762#[cargo_test]
763fn yanks_in_lockfiles_are_ok_for_other_update_git() {
764 yanks_in_lockfiles_are_ok_for_other_update();
765}
766
767fn yanks_in_lockfiles_are_ok_for_other_update() {
768 let p = project()
769 .file(
770 "Cargo.toml",
771 r#"
772 [package]
773 name = "foo"
774 version = "0.0.1"
775 authors = []
776
777 [dependencies]
778 bar = "*"
779 baz = "*"
780 "#,
781 )
782 .file("src/main.rs", "fn main() {}")
783 .build();
784
785 Package::new("bar", "0.0.1").publish();
786 Package::new("baz", "0.0.1").publish();
787
788 p.cargo("check").run();
789
790 registry_path().join("3").rm_rf();
791
792 Package::new("bar", "0.0.1").yanked(true).publish();
793 Package::new("baz", "0.0.1").publish();
794
795 p.cargo("check").with_stdout("").run();
796
797 Package::new("baz", "0.0.2").publish();
798
799 p.cargo("update")
800 .with_status(101)
801 .with_stderr_contains(
802 "\
803error: no matching package named `bar` found
804location searched: registry [..]
805required by package `foo v0.0.1 ([..])`
806",
807 )
808 .run();
809
781aab86 810 p.cargo("update baz")
0a29b90c
FG
811 .with_stderr_contains(
812 "\
813[UPDATING] `[..]` index
814[UPDATING] baz v0.0.1 -> v0.0.2
815",
816 )
817 .run();
818}
819
820#[cargo_test]
821fn yanks_in_lockfiles_are_ok_with_new_dep_http() {
822 let _server = setup_http();
823 yanks_in_lockfiles_are_ok_with_new_dep();
824}
825
826#[cargo_test]
827fn yanks_in_lockfiles_are_ok_with_new_dep_git() {
828 yanks_in_lockfiles_are_ok_with_new_dep();
829}
830
831fn yanks_in_lockfiles_are_ok_with_new_dep() {
832 let p = project()
833 .file(
834 "Cargo.toml",
835 r#"
836 [package]
837 name = "foo"
838 version = "0.0.1"
839 authors = []
840
841 [dependencies]
842 bar = "*"
843 "#,
844 )
845 .file("src/main.rs", "fn main() {}")
846 .build();
847
848 Package::new("bar", "0.0.1").publish();
849
850 p.cargo("check").run();
851
852 registry_path().join("3").rm_rf();
853
854 Package::new("bar", "0.0.1").yanked(true).publish();
855 Package::new("baz", "0.0.1").publish();
856
857 p.change_file(
858 "Cargo.toml",
859 r#"
860 [package]
861 name = "foo"
862 version = "0.0.1"
863 authors = []
864
865 [dependencies]
866 bar = "*"
867 baz = "*"
868 "#,
869 );
870
871 p.cargo("check").with_stdout("").run();
872}
873
874#[cargo_test]
875fn update_with_lockfile_if_packages_missing_http() {
876 let _server = setup_http();
877 update_with_lockfile_if_packages_missing();
878}
879
880#[cargo_test]
881fn update_with_lockfile_if_packages_missing_git() {
882 update_with_lockfile_if_packages_missing();
883}
884
885fn update_with_lockfile_if_packages_missing() {
886 let p = project()
887 .file(
888 "Cargo.toml",
889 r#"
890 [package]
891 name = "foo"
892 version = "0.0.1"
893 authors = []
894
895 [dependencies]
896 bar = "*"
897 "#,
898 )
899 .file("src/main.rs", "fn main() {}")
900 .build();
901
902 Package::new("bar", "0.0.1").publish();
903 p.cargo("check").run();
904 p.root().move_into_the_past();
905
906 paths::home().join(".cargo/registry").rm_rf();
907 p.cargo("check")
908 .with_stderr(
909 "\
910[UPDATING] `[..]` index
911[DOWNLOADING] crates ...
912[DOWNLOADED] bar v0.0.1 (registry `dummy-registry`)
913[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
914",
915 )
916 .run();
917}
918
919#[cargo_test]
920fn update_lockfile_http() {
921 let _server = setup_http();
922 update_lockfile();
923}
924
925#[cargo_test]
926fn update_lockfile_git() {
927 update_lockfile();
928}
929
930fn update_lockfile() {
931 let p = project()
932 .file(
933 "Cargo.toml",
934 r#"
935 [package]
936 name = "foo"
937 version = "0.0.1"
938 authors = []
939
940 [dependencies]
941 bar = "*"
942 "#,
943 )
944 .file("src/main.rs", "fn main() {}")
945 .build();
946
947 println!("0.0.1");
948 Package::new("bar", "0.0.1").publish();
949 p.cargo("check").run();
950
951 Package::new("bar", "0.0.2").publish();
952 Package::new("bar", "0.0.3").publish();
953 paths::home().join(".cargo/registry").rm_rf();
954 println!("0.0.2 update");
781aab86 955 p.cargo("update bar --precise 0.0.2")
0a29b90c
FG
956 .with_stderr(
957 "\
958[UPDATING] `[..]` index
959[UPDATING] bar v0.0.1 -> v0.0.2
960",
961 )
962 .run();
963
964 println!("0.0.2 build");
965 p.cargo("check")
966 .with_stderr(
967 "\
968[DOWNLOADING] crates ...
969[DOWNLOADED] [..] v0.0.2 (registry `dummy-registry`)
970[CHECKING] bar v0.0.2
971[CHECKING] foo v0.0.1 ([CWD])
972[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
973",
974 )
975 .run();
976
977 println!("0.0.3 update");
781aab86 978 p.cargo("update bar")
0a29b90c
FG
979 .with_stderr(
980 "\
981[UPDATING] `[..]` index
982[UPDATING] bar v0.0.2 -> v0.0.3
983",
984 )
985 .run();
986
987 println!("0.0.3 build");
988 p.cargo("check")
989 .with_stderr(
990 "\
991[DOWNLOADING] crates ...
992[DOWNLOADED] [..] v0.0.3 (registry `dummy-registry`)
993[CHECKING] bar v0.0.3
994[CHECKING] foo v0.0.1 ([CWD])
995[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
996",
997 )
998 .run();
999
1000 println!("new dependencies update");
1001 Package::new("bar", "0.0.4").dep("spam", "0.2.5").publish();
1002 Package::new("spam", "0.2.5").publish();
781aab86 1003 p.cargo("update bar")
0a29b90c
FG
1004 .with_stderr(
1005 "\
1006[UPDATING] `[..]` index
1007[UPDATING] bar v0.0.3 -> v0.0.4
1008[ADDING] spam v0.2.5
1009",
1010 )
1011 .run();
1012
1013 println!("new dependencies update");
1014 Package::new("bar", "0.0.5").publish();
781aab86 1015 p.cargo("update bar")
0a29b90c
FG
1016 .with_stderr(
1017 "\
1018[UPDATING] `[..]` index
1019[UPDATING] bar v0.0.4 -> v0.0.5
1020[REMOVING] spam v0.2.5
1021",
1022 )
1023 .run();
1024}
1025
1026#[cargo_test]
1027fn dev_dependency_not_used_http() {
1028 let _server = setup_http();
1029 dev_dependency_not_used();
1030}
1031
1032#[cargo_test]
1033fn dev_dependency_not_used_git() {
1034 dev_dependency_not_used();
1035}
1036
1037fn dev_dependency_not_used() {
1038 let p = project()
1039 .file(
1040 "Cargo.toml",
1041 r#"
1042 [package]
1043 name = "foo"
1044 version = "0.0.1"
1045 authors = []
1046
1047 [dependencies]
1048 bar = "*"
1049 "#,
1050 )
1051 .file("src/main.rs", "fn main() {}")
1052 .build();
1053
1054 Package::new("baz", "0.0.1").publish();
1055 Package::new("bar", "0.0.1").dev_dep("baz", "*").publish();
1056
1057 p.cargo("check")
1058 .with_stderr(
1059 "\
1060[UPDATING] `[..]` index
1061[DOWNLOADING] crates ...
1062[DOWNLOADED] [..] v0.0.1 (registry `dummy-registry`)
1063[CHECKING] bar v0.0.1
1064[CHECKING] foo v0.0.1 ([CWD])
1065[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
1066",
1067 )
1068 .run();
1069}
1070
1071#[cargo_test]
1072fn bad_license_file_http() {
1073 let registry = setup_http();
1074 bad_license_file(&registry);
1075}
1076
1077#[cargo_test]
1078fn bad_license_file_git() {
1079 let registry = registry::init();
1080 bad_license_file(&registry);
1081}
1082
1083fn bad_license_file(registry: &TestRegistry) {
1084 Package::new("foo", "1.0.0").publish();
1085 let p = project()
1086 .file(
1087 "Cargo.toml",
1088 r#"
1089 [package]
1090 name = "foo"
1091 version = "0.0.1"
1092 authors = []
1093 license-file = "foo"
1094 description = "bar"
1095 repository = "baz"
1096 "#,
1097 )
1098 .file("src/main.rs", "fn main() {}")
1099 .build();
1100 p.cargo("publish -v")
1101 .replace_crates_io(registry.index_url())
1102 .with_status(101)
1103 .with_stderr_contains("[ERROR] the license file `foo` does not exist")
1104 .run();
1105}
1106
1107#[cargo_test]
1108fn updating_a_dep_http() {
1109 let _server = setup_http();
1110 updating_a_dep();
1111}
1112
1113#[cargo_test]
1114fn updating_a_dep_git() {
1115 updating_a_dep();
1116}
1117
1118fn updating_a_dep() {
1119 let p = project()
1120 .file(
1121 "Cargo.toml",
1122 r#"
1123 [package]
1124 name = "foo"
1125 version = "0.0.1"
1126 authors = []
1127
1128 [dependencies.a]
1129 path = "a"
1130 "#,
1131 )
1132 .file("src/main.rs", "fn main() {}")
1133 .file(
1134 "a/Cargo.toml",
1135 r#"
1136 [package]
1137 name = "a"
1138 version = "0.0.1"
1139 authors = []
1140
1141 [dependencies]
1142 bar = "*"
1143 "#,
1144 )
1145 .file("a/src/lib.rs", "")
1146 .build();
1147
1148 Package::new("bar", "0.0.1").publish();
1149
1150 p.cargo("check")
1151 .with_stderr(
1152 "\
1153[UPDATING] `[..]` index
1154[DOWNLOADING] crates ...
1155[DOWNLOADED] bar v0.0.1 (registry `dummy-registry`)
1156[CHECKING] bar v0.0.1
1157[CHECKING] a v0.0.1 ([CWD]/a)
1158[CHECKING] foo v0.0.1 ([CWD])
1159[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
1160",
1161 )
1162 .run();
1163 assert!(paths::home().join(".cargo/registry/CACHEDIR.TAG").is_file());
1164
1165 // Now delete the CACHEDIR.TAG file: this is the situation we'll be in after
1166 // upgrading from a version of Cargo that doesn't mark this directory, to one that
1167 // does. It should be recreated.
1168 fs::remove_file(paths::home().join(".cargo/registry/CACHEDIR.TAG"))
1169 .expect("remove CACHEDIR.TAG");
1170
1171 p.change_file(
1172 "a/Cargo.toml",
1173 r#"
1174 [package]
1175 name = "a"
1176 version = "0.0.1"
1177 authors = []
1178
1179 [dependencies]
1180 bar = "0.1.0"
1181 "#,
1182 );
1183 Package::new("bar", "0.1.0").publish();
1184
1185 println!("second");
1186 p.cargo("check")
1187 .with_stderr(
1188 "\
1189[UPDATING] `[..]` index
1190[DOWNLOADING] crates ...
1191[DOWNLOADED] bar v0.1.0 (registry `dummy-registry`)
1192[CHECKING] bar v0.1.0
1193[CHECKING] a v0.0.1 ([CWD]/a)
1194[CHECKING] foo v0.0.1 ([CWD])
1195[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
1196",
1197 )
1198 .run();
1199
1200 assert!(
1201 paths::home().join(".cargo/registry/CACHEDIR.TAG").is_file(),
1202 "CACHEDIR.TAG recreated in existing registry"
1203 );
1204}
1205
1206#[cargo_test]
1207fn git_and_registry_dep_http() {
1208 let _server = setup_http();
1209 git_and_registry_dep();
1210}
1211
1212#[cargo_test]
1213fn git_and_registry_dep_git() {
1214 git_and_registry_dep();
1215}
1216
1217fn git_and_registry_dep() {
1218 let b = git::repo(&paths::root().join("b"))
1219 .file(
1220 "Cargo.toml",
1221 r#"
1222 [package]
1223 name = "b"
1224 version = "0.0.1"
1225 authors = []
1226
1227 [dependencies]
1228 a = "0.0.1"
1229 "#,
1230 )
1231 .file("src/lib.rs", "")
1232 .build();
1233 let p = project()
1234 .file(
1235 "Cargo.toml",
1236 &format!(
1237 r#"
1238 [package]
1239 name = "foo"
1240 version = "0.0.1"
1241 authors = []
1242
1243 [dependencies]
1244 a = "0.0.1"
1245
1246 [dependencies.b]
1247 git = '{}'
1248 "#,
1249 b.url()
1250 ),
1251 )
1252 .file("src/main.rs", "fn main() {}")
1253 .build();
1254
1255 Package::new("a", "0.0.1").publish();
1256
1257 p.root().move_into_the_past();
1258 p.cargo("check")
1259 .with_stderr(
1260 "\
1261[UPDATING] [..]
1262[UPDATING] [..]
1263[DOWNLOADING] crates ...
1264[DOWNLOADED] a v0.0.1 (registry `dummy-registry`)
1265[CHECKING] a v0.0.1
1266[CHECKING] b v0.0.1 ([..])
1267[CHECKING] foo v0.0.1 ([CWD])
1268[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
1269",
1270 )
1271 .run();
1272 p.root().move_into_the_past();
1273
1274 println!("second");
1275 p.cargo("check").with_stdout("").run();
1276}
1277
1278#[cargo_test]
1279fn update_publish_then_update_http() {
1280 let _server = setup_http();
1281 update_publish_then_update();
1282}
1283
1284#[cargo_test]
1285fn update_publish_then_update_git() {
1286 update_publish_then_update();
1287}
1288
1289fn update_publish_then_update() {
1290 // First generate a Cargo.lock and a clone of the registry index at the
1291 // "head" of the current registry.
1292 let p = project()
1293 .file(
1294 "Cargo.toml",
1295 r#"
1296 [package]
1297 name = "foo"
1298 version = "0.5.0"
1299 authors = []
1300
1301 [dependencies]
1302 a = "0.1.0"
1303 "#,
1304 )
1305 .file("src/main.rs", "fn main() {}")
1306 .build();
1307 Package::new("a", "0.1.0").publish();
1308 p.cargo("build").run();
1309
1310 // Next, publish a new package and back up the copy of the registry we just
1311 // created.
1312 Package::new("a", "0.1.1").publish();
1313 let registry = paths::home().join(".cargo/registry");
1314 let backup = paths::root().join("registry-backup");
1315 t!(fs::rename(&registry, &backup));
1316
1317 // Generate a Cargo.lock with the newer version, and then move the old copy
1318 // of the registry back into place.
1319 let p2 = project()
1320 .at("foo2")
1321 .file(
1322 "Cargo.toml",
1323 r#"
1324 [package]
1325 name = "foo"
1326 version = "0.5.0"
1327 authors = []
1328
1329 [dependencies]
1330 a = "0.1.1"
1331 "#,
1332 )
1333 .file("src/main.rs", "fn main() {}")
1334 .build();
1335 p2.cargo("build").run();
1336 registry.rm_rf();
1337 t!(fs::rename(&backup, &registry));
1338 t!(fs::rename(
1339 p2.root().join("Cargo.lock"),
1340 p.root().join("Cargo.lock")
1341 ));
1342
1343 // Finally, build the first project again (with our newer Cargo.lock) which
1344 // should force an update of the old registry, download the new crate, and
1345 // then build everything again.
1346 p.cargo("build")
1347 .with_stderr(
1348 "\
1349[UPDATING] [..]
1350[DOWNLOADING] crates ...
1351[DOWNLOADED] a v0.1.1 (registry `dummy-registry`)
1352[COMPILING] a v0.1.1
1353[COMPILING] foo v0.5.0 ([CWD])
1354[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
1355",
1356 )
1357 .run();
1358}
1359
1360#[cargo_test]
1361fn fetch_downloads_http() {
1362 let _server = setup_http();
1363 fetch_downloads();
1364}
1365
1366#[cargo_test]
1367fn fetch_downloads_git() {
1368 fetch_downloads();
1369}
1370
1371fn fetch_downloads() {
1372 let p = project()
1373 .file(
1374 "Cargo.toml",
1375 r#"
1376 [package]
1377 name = "foo"
1378 version = "0.5.0"
1379 authors = []
1380
1381 [dependencies]
1382 a = "0.1.0"
1383 "#,
1384 )
1385 .file("src/main.rs", "fn main() {}")
1386 .build();
1387
1388 Package::new("a", "0.1.0").publish();
1389
1390 p.cargo("fetch")
1391 .with_stderr(
1392 "\
1393[UPDATING] `[..]` index
1394[DOWNLOADING] crates ...
1395[DOWNLOADED] a v0.1.0 (registry [..])
1396",
1397 )
1398 .run();
1399}
1400
1401#[cargo_test]
1402fn update_transitive_dependency_http() {
1403 let _server = setup_http();
1404 update_transitive_dependency();
1405}
1406
1407#[cargo_test]
1408fn update_transitive_dependency_git() {
1409 update_transitive_dependency();
1410}
1411
1412fn update_transitive_dependency() {
1413 let p = project()
1414 .file(
1415 "Cargo.toml",
1416 r#"
1417 [package]
1418 name = "foo"
1419 version = "0.5.0"
1420 authors = []
1421
1422 [dependencies]
1423 a = "0.1.0"
1424 "#,
1425 )
1426 .file("src/main.rs", "fn main() {}")
1427 .build();
1428
1429 Package::new("a", "0.1.0").dep("b", "*").publish();
1430 Package::new("b", "0.1.0").publish();
1431
1432 p.cargo("fetch").run();
1433
1434 Package::new("b", "0.1.1").publish();
1435
781aab86 1436 p.cargo("update b")
0a29b90c
FG
1437 .with_stderr(
1438 "\
1439[UPDATING] `[..]` index
1440[UPDATING] b v0.1.0 -> v0.1.1
1441",
1442 )
1443 .run();
1444
1445 p.cargo("check")
1446 .with_stderr(
1447 "\
1448[DOWNLOADING] crates ...
1449[DOWNLOADED] b v0.1.1 (registry `dummy-registry`)
1450[CHECKING] b v0.1.1
1451[CHECKING] a v0.1.0
1452[CHECKING] foo v0.5.0 ([..])
1453[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
1454",
1455 )
1456 .run();
1457}
1458
1459#[cargo_test]
1460fn update_backtracking_ok_http() {
1461 let _server = setup_http();
1462 update_backtracking_ok();
1463}
1464
1465#[cargo_test]
1466fn update_backtracking_ok_git() {
1467 update_backtracking_ok();
1468}
1469
1470fn update_backtracking_ok() {
1471 let p = project()
1472 .file(
1473 "Cargo.toml",
1474 r#"
1475 [package]
1476 name = "foo"
1477 version = "0.5.0"
1478 authors = []
1479
1480 [dependencies]
1481 webdriver = "0.1"
1482 "#,
1483 )
1484 .file("src/main.rs", "fn main() {}")
1485 .build();
1486
1487 Package::new("webdriver", "0.1.0")
1488 .dep("hyper", "0.6")
1489 .publish();
1490 Package::new("hyper", "0.6.5")
1491 .dep("openssl", "0.1")
1492 .dep("cookie", "0.1")
1493 .publish();
1494 Package::new("cookie", "0.1.0")
1495 .dep("openssl", "0.1")
1496 .publish();
1497 Package::new("openssl", "0.1.0").publish();
1498
1499 p.cargo("generate-lockfile").run();
1500
1501 Package::new("openssl", "0.1.1").publish();
1502 Package::new("hyper", "0.6.6")
1503 .dep("openssl", "0.1.1")
1504 .dep("cookie", "0.1.0")
1505 .publish();
1506
781aab86 1507 p.cargo("update hyper")
0a29b90c
FG
1508 .with_stderr(
1509 "\
1510[UPDATING] `[..]` index
1511[UPDATING] hyper v0.6.5 -> v0.6.6
1512[UPDATING] openssl v0.1.0 -> v0.1.1
1513",
1514 )
1515 .run();
1516}
1517
1518#[cargo_test]
1519fn update_multiple_packages_http() {
1520 let _server = setup_http();
1521 update_multiple_packages();
1522}
1523
1524#[cargo_test]
1525fn update_multiple_packages_git() {
1526 update_multiple_packages();
1527}
1528
1529fn update_multiple_packages() {
1530 let p = project()
1531 .file(
1532 "Cargo.toml",
1533 r#"
1534 [package]
1535 name = "foo"
1536 version = "0.5.0"
1537 authors = []
1538
1539 [dependencies]
1540 a = "*"
1541 b = "*"
1542 c = "*"
1543 "#,
1544 )
1545 .file("src/main.rs", "fn main() {}")
1546 .build();
1547
1548 Package::new("a", "0.1.0").publish();
1549 Package::new("b", "0.1.0").publish();
1550 Package::new("c", "0.1.0").publish();
1551
1552 p.cargo("fetch").run();
1553
1554 Package::new("a", "0.1.1").publish();
1555 Package::new("b", "0.1.1").publish();
1556 Package::new("c", "0.1.1").publish();
1557
781aab86 1558 p.cargo("update a b")
0a29b90c
FG
1559 .with_stderr(
1560 "\
1561[UPDATING] `[..]` index
1562[UPDATING] a v0.1.0 -> v0.1.1
1563[UPDATING] b v0.1.0 -> v0.1.1
1564",
1565 )
1566 .run();
1567
781aab86 1568 p.cargo("update b c")
0a29b90c
FG
1569 .with_stderr(
1570 "\
1571[UPDATING] `[..]` index
1572[UPDATING] c v0.1.0 -> v0.1.1
1573",
1574 )
1575 .run();
1576
1577 p.cargo("check")
1578 .with_stderr_contains("[DOWNLOADED] a v0.1.1 (registry `dummy-registry`)")
1579 .with_stderr_contains("[DOWNLOADED] b v0.1.1 (registry `dummy-registry`)")
1580 .with_stderr_contains("[DOWNLOADED] c v0.1.1 (registry `dummy-registry`)")
1581 .with_stderr_contains("[CHECKING] a v0.1.1")
1582 .with_stderr_contains("[CHECKING] b v0.1.1")
1583 .with_stderr_contains("[CHECKING] c v0.1.1")
1584 .with_stderr_contains("[CHECKING] foo v0.5.0 ([..])")
1585 .run();
1586}
1587
1588#[cargo_test]
1589fn bundled_crate_in_registry_http() {
1590 let _server = setup_http();
1591 bundled_crate_in_registry();
1592}
1593
1594#[cargo_test]
1595fn bundled_crate_in_registry_git() {
1596 bundled_crate_in_registry();
1597}
1598
1599fn bundled_crate_in_registry() {
1600 let p = project()
1601 .file(
1602 "Cargo.toml",
1603 r#"
1604 [package]
1605 name = "foo"
1606 version = "0.5.0"
1607 authors = []
1608
1609 [dependencies]
1610 bar = "0.1"
1611 baz = "0.1"
1612 "#,
1613 )
1614 .file("src/main.rs", "fn main() {}")
1615 .build();
1616
1617 Package::new("bar", "0.1.0").publish();
1618 Package::new("baz", "0.1.0")
1619 .dep("bar", "0.1.0")
1620 .file(
1621 "Cargo.toml",
1622 r#"
1623 [package]
1624 name = "baz"
1625 version = "0.1.0"
1626 authors = []
1627
1628 [dependencies]
1629 bar = { path = "bar", version = "0.1.0" }
1630 "#,
1631 )
1632 .file("src/lib.rs", "")
1633 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
1634 .file("bar/src/lib.rs", "")
1635 .publish();
1636
1637 p.cargo("run").run();
1638}
1639
1640#[cargo_test]
1641fn update_same_prefix_oh_my_how_was_this_a_bug_http() {
1642 let _server = setup_http();
1643 update_same_prefix_oh_my_how_was_this_a_bug();
1644}
1645
1646#[cargo_test]
1647fn update_same_prefix_oh_my_how_was_this_a_bug_git() {
1648 update_same_prefix_oh_my_how_was_this_a_bug();
1649}
1650
1651fn update_same_prefix_oh_my_how_was_this_a_bug() {
1652 let p = project()
1653 .file(
1654 "Cargo.toml",
1655 r#"
1656 [package]
1657 name = "ugh"
1658 version = "0.5.0"
1659 authors = []
1660
1661 [dependencies]
1662 foo = "0.1"
1663 "#,
1664 )
1665 .file("src/main.rs", "fn main() {}")
1666 .build();
1667
1668 Package::new("foobar", "0.2.0").publish();
1669 Package::new("foo", "0.1.0")
1670 .dep("foobar", "0.2.0")
1671 .publish();
1672
1673 p.cargo("generate-lockfile").run();
781aab86 1674 p.cargo("update foobar --precise=0.2.0").run();
0a29b90c
FG
1675}
1676
1677#[cargo_test]
1678fn use_semver_http() {
1679 let _server = setup_http();
1680 use_semver();
1681}
1682
1683#[cargo_test]
1684fn use_semver_git() {
1685 use_semver();
1686}
1687
1688fn use_semver() {
1689 let p = project()
1690 .file(
1691 "Cargo.toml",
1692 r#"
1693 [package]
1694 name = "bar"
1695 version = "0.5.0"
1696 authors = []
1697
1698 [dependencies]
1699 foo = "1.2.3-alpha.0"
1700 "#,
1701 )
1702 .file("src/main.rs", "fn main() {}")
1703 .build();
1704
1705 Package::new("foo", "1.2.3-alpha.0").publish();
1706
1707 p.cargo("check").run();
1708}
1709
1710#[cargo_test]
1711fn use_semver_package_incorrectly_http() {
1712 let _server = setup_http();
1713 use_semver_package_incorrectly();
1714}
1715
1716#[cargo_test]
1717fn use_semver_package_incorrectly_git() {
1718 use_semver_package_incorrectly();
1719}
1720
1721fn use_semver_package_incorrectly() {
1722 let p = project()
1723 .file(
1724 "Cargo.toml",
1725 r#"
1726 [workspace]
1727 members = ["a", "b"]
1728 "#,
1729 )
1730 .file(
1731 "a/Cargo.toml",
1732 r#"
1733 [package]
1734 name = "a"
1735 version = "0.1.1-alpha.0"
1736 authors = []
1737 "#,
1738 )
1739 .file(
1740 "b/Cargo.toml",
1741 r#"
1742 [package]
1743 name = "b"
1744 version = "0.1.0"
1745 authors = []
1746
1747 [dependencies]
1748 a = { version = "^0.1", path = "../a" }
1749 "#,
1750 )
1751 .file("a/src/main.rs", "fn main() {}")
1752 .file("b/src/main.rs", "fn main() {}")
1753 .build();
1754
1755 p.cargo("check")
1756 .with_status(101)
1757 .with_stderr(
1758 "\
781aab86
FG
1759error: failed to select a version for the requirement `a = \"^0.1\"`
1760candidate versions found which didn't match: 0.1.1-alpha.0
0a29b90c
FG
1761location searched: [..]
1762required by package `b v0.1.0 ([..])`
781aab86
FG
1763if you are looking for the prerelease package it needs to be specified explicitly
1764 a = { version = \"0.1.1-alpha.0\" }
0a29b90c
FG
1765",
1766 )
1767 .run();
1768}
1769
1770#[cargo_test]
1771fn only_download_relevant_http() {
1772 let _server = setup_http();
1773 only_download_relevant();
1774}
1775
1776#[cargo_test]
1777fn only_download_relevant_git() {
1778 only_download_relevant();
1779}
1780
1781fn only_download_relevant() {
1782 let p = project()
1783 .file(
1784 "Cargo.toml",
1785 r#"
1786 [package]
1787 name = "bar"
1788 version = "0.5.0"
1789 authors = []
1790
1791 [target.foo.dependencies]
1792 foo = "*"
1793 [dev-dependencies]
1794 bar = "*"
1795 [dependencies]
1796 baz = "*"
1797 "#,
1798 )
1799 .file("src/main.rs", "fn main() {}")
1800 .build();
1801
1802 Package::new("foo", "0.1.0").publish();
1803 Package::new("bar", "0.1.0").publish();
1804 Package::new("baz", "0.1.0").publish();
1805
1806 p.cargo("check")
1807 .with_stderr(
1808 "\
1809[UPDATING] `[..]` index
1810[DOWNLOADING] crates ...
1811[DOWNLOADED] baz v0.1.0 ([..])
1812[CHECKING] baz v0.1.0
1813[CHECKING] bar v0.5.0 ([..])
1814[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
1815",
1816 )
1817 .run();
1818}
1819
1820#[cargo_test]
1821fn resolve_and_backtracking_http() {
1822 let _server = setup_http();
1823 resolve_and_backtracking();
1824}
1825
1826#[cargo_test]
1827fn resolve_and_backtracking_git() {
1828 resolve_and_backtracking();
1829}
1830
1831fn resolve_and_backtracking() {
1832 let p = project()
1833 .file(
1834 "Cargo.toml",
1835 r#"
1836 [package]
1837 name = "bar"
1838 version = "0.5.0"
1839 authors = []
1840
1841 [dependencies]
1842 foo = "*"
1843 "#,
1844 )
1845 .file("src/main.rs", "fn main() {}")
1846 .build();
1847
1848 Package::new("foo", "0.1.1")
1849 .feature_dep("bar", "0.1", &["a", "b"])
1850 .publish();
1851 Package::new("foo", "0.1.0").publish();
1852
1853 p.cargo("check").run();
1854}
1855
1856#[cargo_test]
1857fn upstream_warnings_on_extra_verbose_http() {
1858 let _server = setup_http();
1859 upstream_warnings_on_extra_verbose();
1860}
1861
1862#[cargo_test]
1863fn upstream_warnings_on_extra_verbose_git() {
1864 upstream_warnings_on_extra_verbose();
1865}
1866
1867fn upstream_warnings_on_extra_verbose() {
1868 let p = project()
1869 .file(
1870 "Cargo.toml",
1871 r#"
1872 [package]
1873 name = "bar"
1874 version = "0.5.0"
1875 authors = []
1876
1877 [dependencies]
1878 foo = "*"
1879 "#,
1880 )
1881 .file("src/main.rs", "fn main() {}")
1882 .build();
1883
1884 Package::new("foo", "0.1.0")
1885 .file("src/lib.rs", "fn unused() {}")
1886 .publish();
1887
1888 p.cargo("check -vv")
1889 .with_stderr_contains("[WARNING] [..]unused[..]")
1890 .run();
1891}
1892
1893#[cargo_test]
1894fn disallow_network_http() {
1895 let _server = setup_http();
1896 let p = project()
1897 .file(
1898 "Cargo.toml",
1899 r#"
1900 [package]
1901 name = "bar"
1902 version = "0.5.0"
1903 authors = []
1904
1905 [dependencies]
1906 foo = "*"
1907 "#,
1908 )
1909 .file("src/main.rs", "fn main() {}")
1910 .build();
1911
1912 p.cargo("check --frozen")
1913 .with_status(101)
1914 .with_stderr(
1915 "\
1916[UPDATING] [..]
1917[ERROR] failed to get `foo` as a dependency of package `bar v0.5.0 ([..])`
1918
1919Caused by:
1920 failed to query replaced source registry `crates-io`
1921
1922Caused by:
1923 attempting to make an HTTP request, but --frozen was specified
1924",
1925 )
1926 .run();
1927}
1928
1929#[cargo_test]
1930fn disallow_network_git() {
1931 let _server = RegistryBuilder::new().build();
1932 let p = project()
1933 .file(
1934 "Cargo.toml",
1935 r#"
1936 [package]
1937 name = "bar"
1938 version = "0.5.0"
1939 authors = []
1940
1941 [dependencies]
1942 foo = "*"
1943 "#,
1944 )
1945 .file("src/main.rs", "fn main() {}")
1946 .build();
1947
1948 p.cargo("check --frozen")
1949 .with_status(101)
1950 .with_stderr(
1951 "\
1952[ERROR] failed to get `foo` as a dependency of package `bar v0.5.0 [..]`
1953
1954Caused by:
1955 failed to load source for dependency `foo`
1956
1957Caused by:
1958 Unable to update registry `crates-io`
1959
1960Caused by:
1961 failed to update replaced source registry `crates-io`
1962
1963Caused by:
1964 attempting to make an HTTP request, but --frozen was specified
1965",
1966 )
1967 .run();
1968}
1969
1970#[cargo_test]
1971fn add_dep_dont_update_registry_http() {
1972 let _server = setup_http();
1973 add_dep_dont_update_registry();
1974}
1975
1976#[cargo_test]
1977fn add_dep_dont_update_registry_git() {
1978 add_dep_dont_update_registry();
1979}
1980
1981fn add_dep_dont_update_registry() {
1982 let p = project()
1983 .file(
1984 "Cargo.toml",
1985 r#"
1986 [package]
1987 name = "bar"
1988 version = "0.5.0"
1989 authors = []
1990
1991 [dependencies]
1992 baz = { path = "baz" }
1993 "#,
1994 )
1995 .file("src/main.rs", "fn main() {}")
1996 .file(
1997 "baz/Cargo.toml",
1998 r#"
1999 [package]
2000 name = "baz"
2001 version = "0.5.0"
2002 authors = []
2003
2004 [dependencies]
2005 remote = "0.3"
2006 "#,
2007 )
2008 .file("baz/src/lib.rs", "")
2009 .build();
2010
2011 Package::new("remote", "0.3.4").publish();
2012
2013 p.cargo("check").run();
2014
2015 p.change_file(
2016 "Cargo.toml",
2017 r#"
2018 [package]
2019 name = "bar"
2020 version = "0.5.0"
2021 authors = []
2022
2023 [dependencies]
2024 baz = { path = "baz" }
2025 remote = "0.3"
2026 "#,
2027 );
2028
2029 p.cargo("check")
2030 .with_stderr(
2031 "\
2032[CHECKING] bar v0.5.0 ([..])
2033[FINISHED] [..]
2034",
2035 )
2036 .run();
2037}
2038
2039#[cargo_test]
2040fn bump_version_dont_update_registry_http() {
2041 let _server = setup_http();
2042 bump_version_dont_update_registry();
2043}
2044
2045#[cargo_test]
2046fn bump_version_dont_update_registry_git() {
2047 bump_version_dont_update_registry();
2048}
2049
2050fn bump_version_dont_update_registry() {
2051 let p = project()
2052 .file(
2053 "Cargo.toml",
2054 r#"
2055 [package]
2056 name = "bar"
2057 version = "0.5.0"
2058 authors = []
2059
2060 [dependencies]
2061 baz = { path = "baz" }
2062 "#,
2063 )
2064 .file("src/main.rs", "fn main() {}")
2065 .file(
2066 "baz/Cargo.toml",
2067 r#"
2068 [package]
2069 name = "baz"
2070 version = "0.5.0"
2071 authors = []
2072
2073 [dependencies]
2074 remote = "0.3"
2075 "#,
2076 )
2077 .file("baz/src/lib.rs", "")
2078 .build();
2079
2080 Package::new("remote", "0.3.4").publish();
2081
2082 p.cargo("check").run();
2083
2084 p.change_file(
2085 "Cargo.toml",
2086 r#"
2087 [package]
2088 name = "bar"
2089 version = "0.6.0"
2090 authors = []
2091
2092 [dependencies]
2093 baz = { path = "baz" }
2094 "#,
2095 );
2096
2097 p.cargo("check")
2098 .with_stderr(
2099 "\
2100[CHECKING] bar v0.6.0 ([..])
2101[FINISHED] [..]
2102",
2103 )
2104 .run();
2105}
2106
2107#[cargo_test]
2108fn toml_lies_but_index_is_truth_http() {
2109 let _server = setup_http();
2110 toml_lies_but_index_is_truth();
2111}
2112
2113#[cargo_test]
2114fn toml_lies_but_index_is_truth_git() {
2115 toml_lies_but_index_is_truth();
2116}
2117
2118fn toml_lies_but_index_is_truth() {
2119 Package::new("foo", "0.2.0").publish();
2120 Package::new("bar", "0.3.0")
2121 .dep("foo", "0.2.0")
2122 .file(
2123 "Cargo.toml",
2124 r#"
2125 [package]
2126 name = "bar"
2127 version = "0.3.0"
2128 authors = []
2129
2130 [dependencies]
2131 foo = "0.1.0"
2132 "#,
2133 )
2134 .file("src/lib.rs", "extern crate foo;")
2135 .publish();
2136
2137 let p = project()
2138 .file(
2139 "Cargo.toml",
2140 r#"
2141 [package]
2142 name = "bar"
2143 version = "0.5.0"
2144 authors = []
2145
2146 [dependencies]
2147 bar = "0.3"
2148 "#,
2149 )
2150 .file("src/main.rs", "fn main() {}")
2151 .build();
2152
2153 p.cargo("check -v").run();
2154}
2155
2156#[cargo_test]
2157fn vv_prints_warnings_http() {
2158 let _server = setup_http();
2159 vv_prints_warnings();
2160}
2161
2162#[cargo_test]
2163fn vv_prints_warnings_git() {
2164 vv_prints_warnings();
2165}
2166
2167fn vv_prints_warnings() {
2168 Package::new("foo", "0.2.0")
2169 .file(
2170 "src/lib.rs",
2171 "#![deny(warnings)] fn foo() {} // unused function",
2172 )
2173 .publish();
2174
2175 let p = project()
2176 .file(
2177 "Cargo.toml",
2178 r#"
2179 [package]
2180 name = "fo"
2181 version = "0.5.0"
2182 authors = []
2183
2184 [dependencies]
2185 foo = "0.2"
2186 "#,
2187 )
2188 .file("src/main.rs", "fn main() {}")
2189 .build();
2190
2191 p.cargo("check -vv").run();
2192}
2193
2194#[cargo_test]
2195fn bad_and_or_malicious_packages_rejected_http() {
2196 let _server = setup_http();
2197 bad_and_or_malicious_packages_rejected();
2198}
2199
2200#[cargo_test]
2201fn bad_and_or_malicious_packages_rejected_git() {
2202 bad_and_or_malicious_packages_rejected();
2203}
2204
2205fn bad_and_or_malicious_packages_rejected() {
2206 Package::new("foo", "0.2.0")
2207 .extra_file("foo-0.1.0/src/lib.rs", "")
2208 .publish();
2209
2210 let p = project()
2211 .file(
2212 "Cargo.toml",
2213 r#"
2214 [package]
2215 name = "fo"
2216 version = "0.5.0"
2217 authors = []
2218
2219 [dependencies]
2220 foo = "0.2"
2221 "#,
2222 )
2223 .file("src/main.rs", "fn main() {}")
2224 .build();
2225
2226 p.cargo("check -vv")
2227 .with_status(101)
2228 .with_stderr(
2229 "\
2230[UPDATING] [..]
2231[DOWNLOADING] crates ...
2232[DOWNLOADED] [..]
2233error: failed to download [..]
2234
2235Caused by:
2236 failed to unpack [..]
2237
2238Caused by:
2239 [..] contains a file at \"foo-0.1.0/src/lib.rs\" which isn't under \"foo-0.2.0\"
2240",
2241 )
2242 .run();
2243}
2244
2245#[cargo_test]
2246fn git_init_templatedir_missing_http() {
2247 let _server = setup_http();
2248 git_init_templatedir_missing();
2249}
2250
2251#[cargo_test]
2252fn git_init_templatedir_missing_git() {
2253 git_init_templatedir_missing();
2254}
2255
2256fn git_init_templatedir_missing() {
2257 Package::new("foo", "0.2.0").dep("bar", "*").publish();
2258 Package::new("bar", "0.2.0").publish();
2259
2260 let p = project()
2261 .file(
2262 "Cargo.toml",
2263 r#"
2264 [package]
2265 name = "fo"
2266 version = "0.5.0"
2267 authors = []
2268
2269 [dependencies]
2270 foo = "0.2"
2271 "#,
2272 )
2273 .file("src/main.rs", "fn main() {}")
2274 .build();
2275
2276 p.cargo("check").run();
2277
2278 remove_dir_all(paths::home().join(".cargo/registry")).unwrap();
2279 fs::write(
2280 paths::home().join(".gitconfig"),
2281 r#"
2282 [init]
2283 templatedir = nowhere
2284 "#,
2285 )
2286 .unwrap();
2287
2288 p.cargo("check").run();
2289 p.cargo("check").run();
2290}
2291
2292#[cargo_test]
2293fn rename_deps_and_features_http() {
2294 let _server = setup_http();
2295 rename_deps_and_features();
2296}
2297
2298#[cargo_test]
2299fn rename_deps_and_features_git() {
2300 rename_deps_and_features();
2301}
2302
2303fn rename_deps_and_features() {
2304 Package::new("foo", "0.1.0")
2305 .file("src/lib.rs", "pub fn f1() {}")
2306 .publish();
2307 Package::new("foo", "0.2.0")
2308 .file("src/lib.rs", "pub fn f2() {}")
2309 .publish();
2310 Package::new("bar", "0.2.0")
2311 .add_dep(
2312 Dependency::new("foo01", "0.1.0")
2313 .package("foo")
2314 .optional(true),
2315 )
2316 .add_dep(Dependency::new("foo02", "0.2.0").package("foo"))
2317 .feature("another", &["foo01"])
2318 .file(
2319 "src/lib.rs",
2320 r#"
2321 extern crate foo02;
2322 #[cfg(feature = "foo01")]
2323 extern crate foo01;
2324
2325 pub fn foo() {
2326 foo02::f2();
2327 #[cfg(feature = "foo01")]
2328 foo01::f1();
2329 }
2330 "#,
2331 )
2332 .publish();
2333
2334 let p = project()
2335 .file(
2336 "Cargo.toml",
2337 r#"
2338 [package]
2339 name = "a"
2340 version = "0.5.0"
2341 authors = []
2342
2343 [dependencies]
2344 bar = "0.2"
2345 "#,
2346 )
2347 .file(
2348 "src/main.rs",
2349 "
2350 extern crate bar;
2351 fn main() { bar::foo(); }
2352 ",
2353 )
2354 .build();
2355
2356 p.cargo("check").run();
2357 p.cargo("check --features bar/foo01").run();
2358 p.cargo("check --features bar/another").run();
2359}
2360
2361#[cargo_test]
2362fn ignore_invalid_json_lines_http() {
2363 let _server = setup_http();
2364 ignore_invalid_json_lines();
2365}
2366
2367#[cargo_test]
2368fn ignore_invalid_json_lines_git() {
2369 ignore_invalid_json_lines();
2370}
2371
2372fn ignore_invalid_json_lines() {
2373 Package::new("foo", "0.1.0").publish();
2374 Package::new("foo", "0.1.1").invalid_json(true).publish();
2375 Package::new("foo", "0.2.0").publish();
2376
2377 let p = project()
2378 .file(
2379 "Cargo.toml",
2380 r#"
2381 [package]
2382 name = "a"
2383 version = "0.5.0"
2384 authors = []
2385
2386 [dependencies]
2387 foo = '0.1.0'
2388 foo02 = { version = '0.2.0', package = 'foo' }
2389 "#,
2390 )
2391 .file("src/lib.rs", "")
2392 .build();
2393
2394 p.cargo("check").run();
2395}
2396
2397#[cargo_test]
2398fn readonly_registry_still_works_http() {
2399 let _server = setup_http();
2400 readonly_registry_still_works();
2401}
2402
2403#[cargo_test]
2404fn readonly_registry_still_works_git() {
2405 readonly_registry_still_works();
2406}
2407
2408fn readonly_registry_still_works() {
2409 Package::new("foo", "0.1.0").publish();
2410
2411 let p = project()
2412 .file(
2413 "Cargo.toml",
2414 r#"
2415 [package]
2416 name = "a"
2417 version = "0.5.0"
2418 authors = []
2419
2420 [dependencies]
2421 foo = '0.1.0'
2422 "#,
2423 )
2424 .file("src/lib.rs", "")
2425 .build();
2426
2427 p.cargo("generate-lockfile").run();
2428 p.cargo("fetch --locked").run();
2429 chmod_readonly(&paths::home(), true);
2430 p.cargo("check").run();
2431 // make sure we un-readonly the files afterwards so "cargo clean" can remove them (#6934)
2432 chmod_readonly(&paths::home(), false);
2433
2434 fn chmod_readonly(path: &Path, readonly: bool) {
2435 for entry in t!(path.read_dir()) {
2436 let entry = t!(entry);
2437 let path = entry.path();
2438 if t!(entry.file_type()).is_dir() {
2439 chmod_readonly(&path, readonly);
2440 } else {
2441 set_readonly(&path, readonly);
2442 }
2443 }
2444 set_readonly(path, readonly);
2445 }
2446
2447 fn set_readonly(path: &Path, readonly: bool) {
2448 let mut perms = t!(path.metadata()).permissions();
2449 perms.set_readonly(readonly);
2450 t!(fs::set_permissions(path, perms));
2451 }
2452}
2453
2454#[cargo_test]
2455fn registry_index_rejected_http() {
2456 let _server = setup_http();
2457 registry_index_rejected();
2458}
2459
2460#[cargo_test]
2461fn registry_index_rejected_git() {
2462 registry_index_rejected();
2463}
2464
2465fn registry_index_rejected() {
2466 Package::new("dep", "0.1.0").publish();
2467
2468 let p = project()
2469 .file(
2470 ".cargo/config",
2471 r#"
2472 [registry]
2473 index = "https://example.com/"
2474 "#,
2475 )
2476 .file(
2477 "Cargo.toml",
2478 r#"
2479 [package]
2480 name = "foo"
2481 version = "0.1.0"
2482
2483 [dependencies]
2484 dep = "0.1"
2485 "#,
2486 )
2487 .file("src/lib.rs", "")
2488 .build();
2489
2490 p.cargo("check")
2491 .with_status(101)
2492 .with_stderr(
2493 "\
2494[ERROR] failed to parse manifest at `[..]/foo/Cargo.toml`
2495
2496Caused by:
2497 the `registry.index` config value is no longer supported
2498 Use `[source]` replacement to alter the default index for crates.io.
2499",
2500 )
2501 .run();
2502
2503 p.cargo("login")
2504 .with_status(101)
2505 .with_stderr(
2506 "\
2507[ERROR] the `registry.index` config value is no longer supported
2508Use `[source]` replacement to alter the default index for crates.io.
2509",
2510 )
2511 .run();
2512}
2513
2514#[cargo_test]
2515fn package_lock_inside_package_is_overwritten() {
2516 let registry = registry::init();
2517 let p = project()
2518 .file(
2519 "Cargo.toml",
2520 r#"
2521 [package]
2522 name = "foo"
2523 version = "0.0.1"
2524 authors = []
2525
2526 [dependencies]
2527 bar = ">= 0.0.0"
2528 "#,
2529 )
2530 .file("src/main.rs", "fn main() {}")
2531 .build();
2532
2533 Package::new("bar", "0.0.1")
2534 .file("src/lib.rs", "")
2535 .file(".cargo-ok", "")
2536 .publish();
2537
2538 p.cargo("check").run();
2539
2540 let id = SourceId::for_registry(registry.index_url()).unwrap();
2541 let hash = cargo::util::hex::short_hash(&id);
2542 let ok = cargo_home()
2543 .join("registry")
2544 .join("src")
2545 .join(format!("-{}", hash))
2546 .join("bar-0.0.1")
2547 .join(".cargo-ok");
2548
49aad941 2549 assert_eq!(ok.metadata().unwrap().len(), 7);
0a29b90c
FG
2550}
2551
2552#[cargo_test]
2553fn package_lock_as_a_symlink_inside_package_is_overwritten() {
2554 let registry = registry::init();
2555 let p = project()
2556 .file(
2557 "Cargo.toml",
2558 r#"
2559 [package]
2560 name = "foo"
2561 version = "0.0.1"
2562 authors = []
2563
2564 [dependencies]
2565 bar = ">= 0.0.0"
2566 "#,
2567 )
2568 .file("src/main.rs", "fn main() {}")
2569 .build();
2570
2571 Package::new("bar", "0.0.1")
2572 .file("src/lib.rs", "pub fn f() {}")
2573 .symlink(".cargo-ok", "src/lib.rs")
2574 .publish();
2575
2576 p.cargo("check").run();
2577
2578 let id = SourceId::for_registry(registry.index_url()).unwrap();
2579 let hash = cargo::util::hex::short_hash(&id);
2580 let pkg_root = cargo_home()
2581 .join("registry")
2582 .join("src")
2583 .join(format!("-{}", hash))
2584 .join("bar-0.0.1");
2585 let ok = pkg_root.join(".cargo-ok");
2586 let librs = pkg_root.join("src/lib.rs");
2587
2588 // Is correctly overwritten and doesn't affect the file linked to
49aad941 2589 assert_eq!(ok.metadata().unwrap().len(), 7);
0a29b90c
FG
2590 assert_eq!(fs::read_to_string(librs).unwrap(), "pub fn f() {}");
2591}
2592
2593#[cargo_test]
2594fn ignores_unknown_index_version_http() {
2595 let _server = setup_http();
2596 ignores_unknown_index_version();
2597}
2598
2599#[cargo_test]
2600fn ignores_unknown_index_version_git() {
2601 ignores_unknown_index_version();
2602}
2603
2604fn ignores_unknown_index_version() {
2605 // If the version field is not understood, it is ignored.
2606 Package::new("bar", "1.0.0").publish();
781aab86
FG
2607 Package::new("bar", "1.0.1")
2608 .schema_version(u32::MAX)
2609 .publish();
0a29b90c
FG
2610
2611 let p = project()
2612 .file(
2613 "Cargo.toml",
2614 r#"
2615 [package]
2616 name = "foo"
2617 version = "0.1.0"
2618
2619 [dependencies]
2620 bar = "1.0"
2621 "#,
2622 )
2623 .file("src/lib.rs", "")
2624 .build();
2625
2626 p.cargo("tree")
2627 .with_stdout(
2628 "foo v0.1.0 [..]\n\
2629 └── bar v1.0.0\n\
2630 ",
2631 )
2632 .run();
2633}
2634
781aab86
FG
2635#[cargo_test]
2636fn unknown_index_version_error() {
2637 // If the version field is not understood, it is ignored.
2638 Package::new("bar", "1.0.1")
2639 .schema_version(u32::MAX)
2640 .publish();
2641
2642 let p = project()
2643 .file(
2644 "Cargo.toml",
2645 r#"
2646 [package]
2647 name = "foo"
2648 version = "0.1.0"
2649
2650 [dependencies]
2651 bar = "1.0"
2652 "#,
2653 )
2654 .file("src/lib.rs", "")
2655 .build();
2656
2657 p.cargo("generate-lockfile")
2658 .with_status(101)
2659 .with_stderr(
2660 "\
2661[UPDATING] `dummy-registry` index
2662[ERROR] no matching package named `bar` found
2663location searched: registry `crates-io`
2664required by package `foo v0.1.0 ([CWD])`
2665",
2666 )
2667 .run();
2668}
2669
0a29b90c
FG
2670#[cargo_test]
2671fn protocol() {
2672 cargo_process("install bar")
2673 .with_status(101)
2674 .env("CARGO_REGISTRIES_CRATES_IO_PROTOCOL", "invalid")
2675 .with_stderr("[ERROR] unsupported registry protocol `invalid` (defined in environment variable `CARGO_REGISTRIES_CRATES_IO_PROTOCOL`)")
2676 .run()
2677}
2678
2679#[cargo_test]
2680fn http_requires_trailing_slash() {
2681 cargo_process("install bar --index sparse+https://invalid.crates.io/test")
2682 .with_status(101)
2683 .with_stderr("[ERROR] sparse registry url must end in a slash `/`: sparse+https://invalid.crates.io/test")
2684 .run()
2685}
2686
2687// Limit the test to debug builds so that `__CARGO_TEST_MAX_UNPACK_SIZE` will take affect.
2688#[cfg(debug_assertions)]
2689#[cargo_test]
2690fn reach_max_unpack_size() {
2691 let p = project()
2692 .file(
2693 "Cargo.toml",
2694 r#"
2695 [package]
2696 name = "foo"
2697 version = "0.0.1"
2698
2699 [dependencies]
2700 bar = ">= 0.0.0"
2701 "#,
2702 )
2703 .file("src/main.rs", "fn main() {}")
2704 .build();
2705
2706 // Size of bar.crate is around 180 bytes.
2707 Package::new("bar", "0.0.1").publish();
2708
2709 p.cargo("check")
2710 .env("__CARGO_TEST_MAX_UNPACK_SIZE", "8") // hit 8 bytes limit and boom!
2711 .env("__CARGO_TEST_MAX_UNPACK_RATIO", "0")
2712 .with_status(101)
2713 .with_stderr(
2714 "\
2715[UPDATING] `dummy-registry` index
2716[DOWNLOADING] crates ...
2717[DOWNLOADED] bar v0.0.1 (registry `dummy-registry`)
2718[ERROR] failed to download replaced source registry `crates-io`
2719
2720Caused by:
2721 failed to unpack package `bar v0.0.1 (registry `dummy-registry`)`
2722
2723Caused by:
2724 failed to iterate over archive
2725
2726Caused by:
2727 maximum limit reached when reading
2728",
2729 )
2730 .run();
2731
2732 // Restore to the default ratio and it should compile.
2733 p.cargo("check")
2734 .env("__CARGO_TEST_MAX_UNPACK_SIZE", "8")
2735 .with_stderr(
2736 "\
2737[CHECKING] bar v0.0.1
2738[CHECKING] foo v0.0.1 ([..])
2739[FINISHED] dev [..]
2740",
2741 )
2742 .run();
2743}
2744
2745#[cargo_test]
2746fn sparse_retry_single() {
2747 let fail_count = Mutex::new(0);
2748 let _registry = RegistryBuilder::new()
2749 .http_index()
2750 .add_responder("/index/3/b/bar", move |req, server| {
2751 let mut fail_count = fail_count.lock().unwrap();
2752 if *fail_count < 2 {
2753 *fail_count += 1;
2754 server.internal_server_error(req)
2755 } else {
2756 server.index(req)
2757 }
2758 })
2759 .build();
2760
2761 let p = project()
2762 .file(
2763 "Cargo.toml",
2764 r#"
2765 [package]
2766 name = "foo"
2767 version = "0.0.1"
2768 authors = []
2769
2770 [dependencies]
2771 bar = ">= 0.0.0"
2772 "#,
2773 )
2774 .file("src/main.rs", "fn main() {}")
2775 .build();
2776
2777 Package::new("bar", "0.0.1").publish();
2778
2779 p.cargo("check")
2780 .with_stderr(
2781 "\
2782[UPDATING] `dummy-registry` index
2783warning: spurious network error (3 tries remaining): failed to get successful HTTP response from `[..]` (127.0.0.1), got 500
2784body:
2785internal server error
2786warning: spurious network error (2 tries remaining): failed to get successful HTTP response from `[..]` (127.0.0.1), got 500
2787body:
2788internal server error
2789[DOWNLOADING] crates ...
2790[DOWNLOADED] bar v0.0.1 (registry `dummy-registry`)
2791[CHECKING] bar v0.0.1
2792[CHECKING] foo v0.0.1 ([CWD])
2793[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
2794",
2795 )
2796 .run();
2797}
2798
2799#[cargo_test]
2800fn sparse_retry_multiple() {
2801 // Tests retry behavior of downloading lots of packages with various
2802 // failure rates accessing the sparse index.
2803
2804 // The index is the number of retries, the value is the number of packages
2805 // that retry that number of times. Thus 50 packages succeed on first try,
2806 // 25 on second, etc.
2807 const RETRIES: &[u32] = &[50, 25, 12, 6];
2808
2809 let pkgs: Vec<_> = RETRIES
2810 .iter()
2811 .enumerate()
2812 .flat_map(|(retries, num)| {
2813 (0..*num)
2814 .into_iter()
2815 .map(move |n| (retries as u32, format!("{}-{n}-{retries}", rand_prefix())))
2816 })
2817 .collect();
2818
2819 let mut builder = RegistryBuilder::new().http_index();
2820 let fail_counts: Arc<Mutex<Vec<u32>>> = Arc::new(Mutex::new(vec![0; pkgs.len()]));
2821 let mut cargo_toml = r#"
2822 [package]
2823 name = "foo"
2824 version = "0.1.0"
2825
2826 [dependencies]
2827 "#
2828 .to_string();
2829 // The expected stderr output.
2830 let mut expected = "\
2831[UPDATING] `dummy-registry` index
2832[DOWNLOADING] crates ...
2833"
2834 .to_string();
2835 for (n, (retries, name)) in pkgs.iter().enumerate() {
2836 let count_clone = fail_counts.clone();
2837 let retries = *retries;
2838 let ab = &name[..2];
2839 let cd = &name[2..4];
2840 builder = builder.add_responder(format!("/index/{ab}/{cd}/{name}"), move |req, server| {
2841 let mut fail_counts = count_clone.lock().unwrap();
2842 if fail_counts[n] < retries {
2843 fail_counts[n] += 1;
2844 server.internal_server_error(req)
2845 } else {
2846 server.index(req)
2847 }
2848 });
2849 write!(&mut cargo_toml, "{name} = \"1.0.0\"\n").unwrap();
2850 for retry in 0..retries {
2851 let remain = 3 - retry;
2852 write!(
2853 &mut expected,
2854 "warning: spurious network error ({remain} tries remaining): \
2855 failed to get successful HTTP response from \
2856 `http://127.0.0.1:[..]/{ab}/{cd}/{name}` (127.0.0.1), got 500\n\
2857 body:\n\
2858 internal server error\n"
2859 )
2860 .unwrap();
2861 }
2862 write!(
2863 &mut expected,
2864 "[DOWNLOADED] {name} v1.0.0 (registry `dummy-registry`)\n"
2865 )
2866 .unwrap();
2867 }
2868 let _server = builder.build();
2869 for (_, name) in &pkgs {
2870 Package::new(name, "1.0.0").publish();
2871 }
2872 let p = project()
2873 .file("Cargo.toml", &cargo_toml)
2874 .file("src/lib.rs", "")
2875 .build();
2876 p.cargo("fetch").with_stderr_unordered(expected).run();
2877}
2878
2879#[cargo_test]
2880fn dl_retry_single() {
2881 // Tests retry behavior of downloading a package.
2882 // This tests a single package which exercises the code path that causes
2883 // it to block.
2884 let fail_count = Mutex::new(0);
2885 let _server = RegistryBuilder::new()
2886 .http_index()
2887 .add_responder("/dl/bar/1.0.0/download", move |req, server| {
2888 let mut fail_count = fail_count.lock().unwrap();
2889 if *fail_count < 2 {
2890 *fail_count += 1;
2891 server.internal_server_error(req)
2892 } else {
2893 server.dl(req)
2894 }
2895 })
2896 .build();
2897 Package::new("bar", "1.0.0").publish();
2898 let p = project()
2899 .file(
2900 "Cargo.toml",
2901 r#"
2902 [package]
2903 name = "foo"
2904 version = "0.1.0"
2905
2906 [dependencies]
2907 bar = "1.0"
2908 "#,
2909 )
2910 .file("src/lib.rs", "")
2911 .build();
2912 p.cargo("fetch")
2913 .with_stderr("\
2914[UPDATING] `dummy-registry` index
2915[DOWNLOADING] crates ...
2916warning: spurious network error (3 tries remaining): \
2917 failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download` (127.0.0.1), got 500
2918body:
2919internal server error
2920warning: spurious network error (2 tries remaining): \
2921 failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download` (127.0.0.1), got 500
2922body:
2923internal server error
2924[DOWNLOADED] bar v1.0.0 (registry `dummy-registry`)
2925").run();
2926}
2927
2928/// Creates a random prefix to randomly spread out the package names
2929/// to somewhat evenly distribute the different failures at different
2930/// points.
2931fn rand_prefix() -> String {
2932 use rand::Rng;
2933 const CHARS: &[u8] = b"abcdefghijklmnopqrstuvwxyz";
2934 let mut rng = rand::thread_rng();
2935 (0..5)
2936 .map(|_| CHARS[rng.gen_range(0..CHARS.len())] as char)
2937 .collect()
2938}
2939
2940#[cargo_test]
2941fn dl_retry_multiple() {
2942 // Tests retry behavior of downloading lots of packages with various
2943 // failure rates.
2944
2945 // The index is the number of retries, the value is the number of packages
2946 // that retry that number of times. Thus 50 packages succeed on first try,
2947 // 25 on second, etc.
2948 const RETRIES: &[u32] = &[50, 25, 12, 6];
2949
2950 let pkgs: Vec<_> = RETRIES
2951 .iter()
2952 .enumerate()
2953 .flat_map(|(retries, num)| {
2954 (0..*num)
2955 .into_iter()
2956 .map(move |n| (retries as u32, format!("{}-{n}-{retries}", rand_prefix())))
2957 })
2958 .collect();
2959
2960 let mut builder = RegistryBuilder::new().http_index();
2961 let fail_counts: Arc<Mutex<Vec<u32>>> = Arc::new(Mutex::new(vec![0; pkgs.len()]));
2962 let mut cargo_toml = r#"
2963 [package]
2964 name = "foo"
2965 version = "0.1.0"
2966
2967 [dependencies]
2968 "#
2969 .to_string();
2970 // The expected stderr output.
2971 let mut expected = "\
2972[UPDATING] `dummy-registry` index
2973[DOWNLOADING] crates ...
2974"
2975 .to_string();
2976 for (n, (retries, name)) in pkgs.iter().enumerate() {
2977 let count_clone = fail_counts.clone();
2978 let retries = *retries;
2979 builder =
2980 builder.add_responder(format!("/dl/{name}/1.0.0/download"), move |req, server| {
2981 let mut fail_counts = count_clone.lock().unwrap();
2982 if fail_counts[n] < retries {
2983 fail_counts[n] += 1;
2984 server.internal_server_error(req)
2985 } else {
2986 server.dl(req)
2987 }
2988 });
2989 write!(&mut cargo_toml, "{name} = \"1.0.0\"\n").unwrap();
2990 for retry in 0..retries {
2991 let remain = 3 - retry;
2992 write!(
2993 &mut expected,
2994 "warning: spurious network error ({remain} tries remaining): \
2995 failed to get successful HTTP response from \
2996 `http://127.0.0.1:[..]/dl/{name}/1.0.0/download` (127.0.0.1), got 500\n\
2997 body:\n\
2998 internal server error\n"
2999 )
3000 .unwrap();
3001 }
3002 write!(
3003 &mut expected,
3004 "[DOWNLOADED] {name} v1.0.0 (registry `dummy-registry`)\n"
3005 )
3006 .unwrap();
3007 }
3008 let _server = builder.build();
3009 for (_, name) in &pkgs {
3010 Package::new(name, "1.0.0").publish();
3011 }
3012 let p = project()
3013 .file("Cargo.toml", &cargo_toml)
3014 .file("src/lib.rs", "")
3015 .build();
3016 p.cargo("fetch").with_stderr_unordered(expected).run();
3017}
3018
3019#[cargo_test]
3020fn deleted_entry() {
3021 // Checks the behavior when a package is removed from the index.
3022 // This is done occasionally on crates.io to handle things like
3023 // copyright takedowns.
3024 let p = project()
3025 .file(
3026 "Cargo.toml",
3027 r#"
3028 [package]
3029 name = "foo"
3030 version = "0.1.0"
3031
3032 [dependencies]
3033 bar = "0.1"
3034 "#,
3035 )
3036 .file("src/lib.rs", "")
3037 .build();
3038
3039 // First, test removing a single version, but leaving an older version.
3040 Package::new("bar", "0.1.0").publish();
3041 let bar_path = Path::new("3/b/bar");
3042 let bar_reg_path = registry_path().join(&bar_path);
3043 let old_index = fs::read_to_string(&bar_reg_path).unwrap();
3044 Package::new("bar", "0.1.1").publish();
3045 p.cargo("tree")
3046 .with_stderr(
3047 "\
3048[UPDATING] `dummy-registry` index
3049[DOWNLOADING] crates ...
3050[DOWNLOADED] bar v0.1.1 (registry `dummy-registry`)
3051",
3052 )
3053 .with_stdout(
3054 "\
3055foo v0.1.0 ([ROOT]/foo)
3056└── bar v0.1.1
3057",
3058 )
3059 .run();
3060
3061 // Remove 0.1.1
3062 fs::remove_file(paths::root().join("dl/bar/0.1.1/download")).unwrap();
3063 let repo = git2::Repository::open(registry_path()).unwrap();
3064 let mut index = repo.index().unwrap();
3065 fs::write(&bar_reg_path, &old_index).unwrap();
3066 index.add_path(&bar_path).unwrap();
3067 index.write().unwrap();
3068 git::commit(&repo);
3069
3070 // With `Cargo.lock` unchanged, it shouldn't have an impact.
3071 p.cargo("tree")
3072 .with_stderr("")
3073 .with_stdout(
3074 "\
3075foo v0.1.0 ([ROOT]/foo)
3076└── bar v0.1.1
3077",
3078 )
3079 .run();
3080
3081 // Regenerating Cargo.lock should switch to old version.
3082 fs::remove_file(p.root().join("Cargo.lock")).unwrap();
3083 p.cargo("tree")
3084 .with_stderr(
3085 "\
3086[UPDATING] `dummy-registry` index
3087[DOWNLOADING] crates ...
3088[DOWNLOADED] bar v0.1.0 (registry `dummy-registry`)
3089",
3090 )
3091 .with_stdout(
3092 "\
3093foo v0.1.0 ([ROOT]/foo)
3094└── bar v0.1.0
3095",
3096 )
3097 .run();
3098
3099 // Remove the package entirely.
3100 fs::remove_file(paths::root().join("dl/bar/0.1.0/download")).unwrap();
3101 let mut index = repo.index().unwrap();
3102 index.remove(&bar_path, 0).unwrap();
3103 index.write().unwrap();
3104 git::commit(&repo);
3105 fs::remove_file(&bar_reg_path).unwrap();
3106
3107 // With `Cargo.lock` unchanged, it shouldn't have an impact.
3108 p.cargo("tree")
3109 .with_stderr("")
3110 .with_stdout(
3111 "\
3112foo v0.1.0 ([ROOT]/foo)
3113└── bar v0.1.0
3114",
3115 )
3116 .run();
3117
3118 // Regenerating Cargo.lock should fail.
3119 fs::remove_file(p.root().join("Cargo.lock")).unwrap();
3120 p.cargo("tree")
3121 .with_stderr(
3122 "\
3123[UPDATING] `dummy-registry` index
3124error: no matching package named `bar` found
3125location searched: registry `crates-io`
3126required by package `foo v0.1.0 ([ROOT]/foo)`
3127",
3128 )
3129 .with_status(101)
3130 .run();
3131}
3132
3133#[cargo_test]
3134fn corrupted_ok_overwritten() {
3135 // Checks what happens if .cargo-ok gets truncated, such as if the file is
3136 // created, but the flush/close is interrupted.
3137 Package::new("bar", "1.0.0").publish();
3138 let p = project()
3139 .file(
3140 "Cargo.toml",
3141 r#"
3142 [package]
3143 name = "foo"
3144 version = "0.1.0"
3145
3146 [dependencies]
3147 bar = "1"
3148 "#,
3149 )
3150 .file("src/lib.rs", "")
3151 .build();
3152 p.cargo("fetch")
3153 .with_stderr(
3154 "\
3155[UPDATING] `dummy-registry` index
3156[DOWNLOADING] crates ...
3157[DOWNLOADED] bar v1.0.0 (registry `dummy-registry`)
3158",
3159 )
3160 .run();
3161 let ok = glob::glob(
3162 paths::home()
3163 .join(".cargo/registry/src/*/bar-1.0.0/.cargo-ok")
3164 .to_str()
3165 .unwrap(),
3166 )
3167 .unwrap()
3168 .next()
3169 .unwrap()
3170 .unwrap();
3171 // Simulate cargo being interrupted, or filesystem corruption.
3172 fs::write(&ok, "").unwrap();
3173 assert_eq!(fs::read_to_string(&ok).unwrap(), "");
3174 p.cargo("fetch").with_stderr("").run();
49aad941 3175 assert_eq!(fs::read_to_string(&ok).unwrap(), r#"{"v":1}"#);
0a29b90c
FG
3176}
3177
3178#[cargo_test]
3179fn not_found_permutations() {
3180 // Test for querying permutations for a missing dependency.
3181 let misses = Arc::new(Mutex::new(Vec::new()));
3182 let misses2 = misses.clone();
3183 let _registry = RegistryBuilder::new()
3184 .http_index()
3185 .not_found_handler(move |req, _server| {
3186 let mut misses = misses2.lock().unwrap();
3187 misses.push(req.url.path().to_string());
3188 Response {
3189 code: 404,
3190 headers: vec![],
3191 body: b"not found".to_vec(),
3192 }
3193 })
3194 .build();
3195
3196 let p = project()
3197 .file(
3198 "Cargo.toml",
3199 r#"
3200 [package]
3201 name = "foo"
3202 version = "0.0.1"
3203 authors = []
3204
3205 [dependencies]
49aad941 3206 a-b_c = "1.0"
0a29b90c
FG
3207 "#,
3208 )
3209 .file("src/lib.rs", "")
3210 .build();
3211
3212 p.cargo("check")
3213 .with_status(101)
3214 .with_stderr(
3215 "\
3216[UPDATING] `dummy-registry` index
49aad941 3217error: no matching package named `a-b_c` found
0a29b90c
FG
3218location searched: registry `crates-io`
3219required by package `foo v0.0.1 ([ROOT]/foo)`
3220",
3221 )
3222 .run();
3223 let mut misses = misses.lock().unwrap();
3224 misses.sort();
3225 assert_eq!(
3226 &*misses,
3227 &[
3228 "/index/a-/b-/a-b-c",
3229 "/index/a-/b_/a-b_c",
0a29b90c
FG
3230 "/index/a_/b_/a_b_c"
3231 ]
3232 );
3233}
3234
3235#[cargo_test]
3236fn default_auth_error() {
3237 // Check for the error message for an authentication error when default is set.
3238 let crates_io = RegistryBuilder::new().http_api().build();
3239 let _alternative = RegistryBuilder::new().http_api().alternative().build();
3240
3241 paths::home().join(".cargo/credentials.toml").rm_rf();
3242
3243 let p = project()
3244 .file(
3245 "Cargo.toml",
3246 r#"
3247 [package]
3248 name = "foo"
3249 version = "0.1.0"
3250 license = "MIT"
3251 description = "foo"
3252 "#,
3253 )
3254 .file("src/lib.rs", "")
3255 .build();
3256
3257 // Test output before setting the default.
3258 p.cargo("publish --no-verify")
3259 .replace_crates_io(crates_io.index_url())
3260 .with_stderr(
3261 "\
3262[UPDATING] crates.io index
3263error: no token found, please run `cargo login`
3264or use environment variable CARGO_REGISTRY_TOKEN
3265",
3266 )
3267 .with_status(101)
3268 .run();
3269
3270 p.cargo("publish --no-verify --registry alternative")
3271 .replace_crates_io(crates_io.index_url())
3272 .with_stderr(
3273 "\
3274[UPDATING] `alternative` index
3275error: no token found for `alternative`, please run `cargo login --registry alternative`
3276or use environment variable CARGO_REGISTRIES_ALTERNATIVE_TOKEN
3277",
3278 )
3279 .with_status(101)
3280 .run();
3281
3282 // Test the output with the default.
3283 cargo_util::paths::append(
3284 &cargo_home().join("config"),
3285 br#"
3286 [registry]
3287 default = "alternative"
3288 "#,
3289 )
3290 .unwrap();
3291
3292 p.cargo("publish --no-verify")
3293 .replace_crates_io(crates_io.index_url())
3294 .with_stderr(
3295 "\
3296[UPDATING] `alternative` index
3297error: no token found for `alternative`, please run `cargo login --registry alternative`
3298or use environment variable CARGO_REGISTRIES_ALTERNATIVE_TOKEN
3299",
3300 )
3301 .with_status(101)
3302 .run();
3303
3304 p.cargo("publish --no-verify --registry crates-io")
3305 .replace_crates_io(crates_io.index_url())
3306 .with_stderr(
3307 "\
3308[UPDATING] crates.io index
3309error: no token found, please run `cargo login --registry crates-io`
3310or use environment variable CARGO_REGISTRY_TOKEN
3311",
3312 )
3313 .with_status(101)
3314 .run();
3315}
3316
3317const SAMPLE_HEADERS: &[&str] = &[
3318 "x-amz-cf-pop: SFO53-P2",
3319 "x-amz-cf-id: vEc3osJrCAXVaciNnF4Vev-hZFgnYwmNZtxMKRJ5bF6h9FTOtbTMnA==",
3320 "x-cache: Hit from cloudfront",
3321 "server: AmazonS3",
3322 "x-amz-version-id: pvsJYY_JGsWiSETZvLJKb7DeEW5wWq1W",
3323 "x-amz-server-side-encryption: AES256",
3324 "content-type: text/plain",
3325 "via: 1.1 bcbc5b46216015493e082cfbcf77ef10.cloudfront.net (CloudFront)",
3326];
3327
3328#[cargo_test]
3329fn debug_header_message_index() {
3330 // The error message should include some headers for debugging purposes.
3331 let _server = RegistryBuilder::new()
3332 .http_index()
3333 .add_responder("/index/3/b/bar", |_, _| Response {
3334 code: 503,
3335 headers: SAMPLE_HEADERS.iter().map(|s| s.to_string()).collect(),
3336 body: b"Please slow down".to_vec(),
3337 })
3338 .build();
3339 Package::new("bar", "1.0.0").publish();
3340
3341 let p = project()
3342 .file(
3343 "Cargo.toml",
3344 r#"
3345 [package]
3346 name = "foo"
3347 version = "0.1.0"
3348
3349 [dependencies]
3350 bar = "1.0"
3351 "#,
3352 )
3353 .file("src/lib.rs", "")
3354 .build();
3355 p.cargo("fetch").with_status(101).with_stderr("\
3356[UPDATING] `dummy-registry` index
3357warning: spurious network error (3 tries remaining): \
3358 failed to get successful HTTP response from `http://127.0.0.1:[..]/index/3/b/bar` (127.0.0.1), got 503
3359body:
3360Please slow down
3361warning: spurious network error (2 tries remaining): \
3362 failed to get successful HTTP response from `http://127.0.0.1:[..]/index/3/b/bar` (127.0.0.1), got 503
3363body:
3364Please slow down
3365warning: spurious network error (1 tries remaining): \
3366 failed to get successful HTTP response from `http://127.0.0.1:[..]/index/3/b/bar` (127.0.0.1), got 503
3367body:
3368Please slow down
3369error: failed to get `bar` as a dependency of package `foo v0.1.0 ([ROOT]/foo)`
3370
3371Caused by:
3372 failed to query replaced source registry `crates-io`
3373
3374Caused by:
3375 download of 3/b/bar failed
3376
3377Caused by:
3378 failed to get successful HTTP response from `http://127.0.0.1:[..]/index/3/b/bar` (127.0.0.1), got 503
3379 debug headers:
3380 x-amz-cf-pop: SFO53-P2
3381 x-amz-cf-id: vEc3osJrCAXVaciNnF4Vev-hZFgnYwmNZtxMKRJ5bF6h9FTOtbTMnA==
3382 x-cache: Hit from cloudfront
3383 body:
3384 Please slow down
3385").run();
3386}
3387
3388#[cargo_test]
3389fn debug_header_message_dl() {
3390 // Same as debug_header_message_index, but for the dl endpoint which goes
3391 // through a completely different code path.
3392 let _server = RegistryBuilder::new()
3393 .http_index()
3394 .add_responder("/dl/bar/1.0.0/download", |_, _| Response {
3395 code: 503,
3396 headers: SAMPLE_HEADERS.iter().map(|s| s.to_string()).collect(),
3397 body: b"Please slow down".to_vec(),
3398 })
3399 .build();
3400 Package::new("bar", "1.0.0").publish();
3401 let p = project()
3402 .file(
3403 "Cargo.toml",
3404 r#"
3405 [package]
3406 name = "foo"
3407 version = "0.1.0"
3408
3409 [dependencies]
3410 bar = "1.0"
3411 "#,
3412 )
3413 .file("src/lib.rs", "")
3414 .build();
3415
3416 p.cargo("fetch").with_status(101).with_stderr("\
3417[UPDATING] `dummy-registry` index
3418[DOWNLOADING] crates ...
3419warning: spurious network error (3 tries remaining): \
3420 failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download` (127.0.0.1), got 503
3421body:
3422Please slow down
3423warning: spurious network error (2 tries remaining): \
3424 failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download` (127.0.0.1), got 503
3425body:
3426Please slow down
3427warning: spurious network error (1 tries remaining): \
3428 failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download` (127.0.0.1), got 503
3429body:
3430Please slow down
3431error: failed to download from `http://127.0.0.1:[..]/dl/bar/1.0.0/download`
3432
3433Caused by:
3434 failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download` (127.0.0.1), got 503
3435 debug headers:
3436 x-amz-cf-pop: SFO53-P2
3437 x-amz-cf-id: vEc3osJrCAXVaciNnF4Vev-hZFgnYwmNZtxMKRJ5bF6h9FTOtbTMnA==
3438 x-cache: Hit from cloudfront
3439 body:
3440 Please slow down
3441").run();
3442}
49aad941
FG
3443
3444#[cfg(unix)]
3445#[cargo_test]
3446fn set_mask_during_unpacking() {
3447 use std::os::unix::fs::MetadataExt;
3448
3449 Package::new("bar", "1.0.0")
3450 .file_with_mode("example.sh", 0o777, "#!/bin/sh")
3451 .file_with_mode("src/lib.rs", 0o666, "")
3452 .publish();
3453
3454 let p = project()
3455 .file(
3456 "Cargo.toml",
3457 r#"
3458 [package]
3459 name = "foo"
3460 version = "0.1.0"
3461
3462 [dependencies]
3463 bar = "1.0"
3464 "#,
3465 )
3466 .file("src/lib.rs", "")
3467 .build();
3468
3469 p.cargo("fetch")
3470 .with_stderr(
3471 "\
3472[UPDATING] `dummy-registry` index
3473[DOWNLOADING] crates ...
3474[DOWNLOADED] bar v1.0.0 (registry `dummy-registry`)
3475",
3476 )
3477 .run();
3478 let src_file_path = |path: &str| {
3479 glob::glob(
3480 paths::home()
3481 .join(".cargo/registry/src/*/bar-1.0.0/")
3482 .join(path)
3483 .to_str()
3484 .unwrap(),
3485 )
3486 .unwrap()
3487 .next()
3488 .unwrap()
3489 .unwrap()
3490 };
3491
3492 let umask = cargo::util::get_umask();
3493 let metadata = fs::metadata(src_file_path("src/lib.rs")).unwrap();
3494 assert_eq!(metadata.mode() & 0o777, 0o666 & !umask);
3495 let metadata = fs::metadata(src_file_path("example.sh")).unwrap();
3496 assert_eq!(metadata.mode() & 0o777, 0o777 & !umask);
3497}
3498
3499#[cargo_test]
3500fn unpack_again_when_cargo_ok_is_unrecognized() {
3501 Package::new("bar", "1.0.0").publish();
3502
3503 let p = project()
3504 .file(
3505 "Cargo.toml",
3506 r#"
3507 [package]
3508 name = "foo"
3509 version = "0.1.0"
3510
3511 [dependencies]
3512 bar = "1.0"
3513 "#,
3514 )
3515 .file("src/lib.rs", "")
3516 .build();
3517
3518 p.cargo("fetch")
3519 .with_stderr(
3520 "\
3521[UPDATING] `dummy-registry` index
3522[DOWNLOADING] crates ...
3523[DOWNLOADED] bar v1.0.0 (registry `dummy-registry`)
3524",
3525 )
3526 .run();
3527
3528 let src_file_path = |path: &str| {
3529 glob::glob(
3530 paths::home()
3531 .join(".cargo/registry/src/*/bar-1.0.0/")
3532 .join(path)
3533 .to_str()
3534 .unwrap(),
3535 )
3536 .unwrap()
3537 .next()
3538 .unwrap()
3539 .unwrap()
3540 };
3541
3542 // Change permissions to simulate the old behavior not respecting umask.
3543 let lib_rs = src_file_path("src/lib.rs");
3544 let cargo_ok = src_file_path(".cargo-ok");
3545 let mut perms = fs::metadata(&lib_rs).unwrap().permissions();
3546 assert!(!perms.readonly());
3547 perms.set_readonly(true);
3548 fs::set_permissions(&lib_rs, perms).unwrap();
3549 let ok = fs::read_to_string(&cargo_ok).unwrap();
3550 assert_eq!(&ok, r#"{"v":1}"#);
3551
3552 p.cargo("fetch").with_stderr("").run();
3553
3554 // Without changing `.cargo-ok`, a unpack won't be triggered.
3555 let perms = fs::metadata(&lib_rs).unwrap().permissions();
3556 assert!(perms.readonly());
3557
3558 // Write "ok" to simulate the old behavior and trigger the unpack again.
3559 fs::write(&cargo_ok, "ok").unwrap();
3560
3561 p.cargo("fetch").with_stderr("").run();
3562
3563 // Permission has been restored and `.cargo-ok` is in the new format.
3564 let perms = fs::metadata(lib_rs).unwrap().permissions();
3565 assert!(!perms.readonly());
3566 let ok = fs::read_to_string(&cargo_ok).unwrap();
3567 assert_eq!(&ok, r#"{"v":1}"#);
3568}
add651ee
FG
3569
3570#[cargo_test]
3571fn differ_only_by_metadata() {
3572 let p = project()
3573 .file(
3574 "Cargo.toml",
3575 r#"
3576 [package]
3577 name = "foo"
3578 version = "0.0.1"
3579 authors = []
3580
3581 [dependencies]
3582 baz = "=0.0.1"
3583 "#,
3584 )
3585 .file("src/main.rs", "fn main() {}")
3586 .build();
3587
3588 Package::new("baz", "0.0.1+b").publish();
3589 Package::new("baz", "0.0.1+c").yanked(true).publish();
3590
3591 p.cargo("check")
3592 .with_stderr(
3593 "\
3594[UPDATING] `dummy-registry` index
3595[DOWNLOADING] crates ...
3596[DOWNLOADED] [..] v0.0.1+b (registry `dummy-registry`)
3597[CHECKING] baz v0.0.1+b
3598[CHECKING] foo v0.0.1 ([CWD])
3599[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
3600",
3601 )
3602 .run();
3603}