]> git.proxmox.com Git - rustc.git/blob - src/tools/cargotest/main.rs
New upstream version 1.64.0+dfsg1
[rustc.git] / src / tools / cargotest / main.rs
1 use std::env;
2 use std::fs;
3 use std::path::{Path, PathBuf};
4 use std::process::Command;
5
6 struct Test {
7 repo: &'static str,
8 name: &'static str,
9 sha: &'static str,
10 lock: Option<&'static str>,
11 packages: &'static [&'static str],
12 features: Option<&'static [&'static str]>,
13 manifest_path: Option<&'static str>,
14 /// `filters` are passed to libtest (i.e., after a `--` in the `cargo test` invocation).
15 filters: &'static [&'static str],
16 }
17
18 const TEST_REPOS: &[Test] = &[
19 Test {
20 name: "iron",
21 repo: "https://github.com/iron/iron",
22 sha: "cf056ea5e8052c1feea6141e40ab0306715a2c33",
23 lock: None,
24 packages: &[],
25 features: None,
26 manifest_path: None,
27 filters: &[],
28 },
29 Test {
30 name: "ripgrep",
31 repo: "https://github.com/BurntSushi/ripgrep",
32 sha: "ced5b92aa93eb47e892bd2fd26ab454008721730",
33 lock: None,
34 packages: &[],
35 features: None,
36 manifest_path: None,
37 filters: &[],
38 },
39 Test {
40 name: "tokei",
41 repo: "https://github.com/XAMPPRocky/tokei",
42 sha: "fdf3f8cb279a7aeac0696c87e5d8b0cd946e4f9e",
43 lock: None,
44 packages: &[],
45 features: None,
46 manifest_path: None,
47 filters: &[],
48 },
49 Test {
50 name: "xsv",
51 repo: "https://github.com/BurntSushi/xsv",
52 sha: "3de6c04269a7d315f7e9864b9013451cd9580a08",
53 lock: None,
54 packages: &[],
55 features: None,
56 manifest_path: None,
57 // Many tests here use quickcheck and some of them can fail randomly, so only run deterministic tests.
58 filters: &[
59 "test_flatten::",
60 "test_fmt::",
61 "test_headers::",
62 "test_index::",
63 "test_join::",
64 "test_partition::",
65 "test_search::",
66 "test_select::",
67 "test_slice::",
68 "test_split::",
69 "test_stats::",
70 "test_table::",
71 ],
72 },
73 Test {
74 name: "servo",
75 repo: "https://github.com/servo/servo",
76 sha: "caac107ae8145ef2fd20365e2b8fadaf09c2eb3b",
77 lock: None,
78 // Only test Stylo a.k.a. Quantum CSS, the parts of Servo going into Firefox.
79 // This takes much less time to build than all of Servo and supports stable Rust.
80 packages: &["selectors"],
81 features: None,
82 manifest_path: None,
83 filters: &[],
84 },
85 Test {
86 name: "diesel",
87 repo: "https://github.com/diesel-rs/diesel",
88 sha: "91493fe47175076f330ce5fc518f0196c0476f56",
89 lock: None,
90 packages: &[],
91 // Test the embedded sqlite variant of diesel
92 // This does not require any dependency to be present,
93 // sqlite will be compiled as part of the build process
94 features: Some(&["sqlite", "libsqlite3-sys/bundled"]),
95 // We are only interested in testing diesel itself
96 // not any other crate present in the diesel workspace
97 // (This is required to set the feature flags above)
98 manifest_path: Some("diesel/Cargo.toml"),
99 filters: &[],
100 },
101 ];
102
103 fn main() {
104 let args = env::args().collect::<Vec<_>>();
105 let cargo = &args[1];
106 let out_dir = Path::new(&args[2]);
107 let cargo = &Path::new(cargo);
108
109 for test in TEST_REPOS.iter().rev() {
110 if args[3..].is_empty() || args[3..].iter().any(|s| s.contains(test.name)) {
111 test_repo(cargo, out_dir, test);
112 }
113 }
114 }
115
116 fn test_repo(cargo: &Path, out_dir: &Path, test: &Test) {
117 println!("testing {}", test.repo);
118 let dir = clone_repo(test, out_dir);
119 if let Some(lockfile) = test.lock {
120 fs::write(&dir.join("Cargo.lock"), lockfile).unwrap();
121 }
122 if !run_cargo_test(cargo, &dir, test.packages, test.features, test.manifest_path, test.filters)
123 {
124 panic!("tests failed for {}", test.repo);
125 }
126 }
127
128 fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
129 let out_dir = out_dir.join(test.name);
130
131 if !out_dir.join(".git").is_dir() {
132 let status = Command::new("git").arg("init").arg(&out_dir).status().unwrap();
133 assert!(status.success());
134 }
135
136 // Try progressively deeper fetch depths to find the commit
137 let mut found = false;
138 for depth in &[0, 1, 10, 100, 1000, 100000] {
139 if *depth > 0 {
140 let status = Command::new("git")
141 .arg("fetch")
142 .arg(test.repo)
143 .arg("master")
144 .arg(&format!("--depth={}", depth))
145 .current_dir(&out_dir)
146 .status()
147 .unwrap();
148 assert!(status.success());
149 }
150
151 let status = Command::new("git")
152 .arg("reset")
153 .arg(test.sha)
154 .arg("--hard")
155 .current_dir(&out_dir)
156 .status()
157 .unwrap();
158
159 if status.success() {
160 found = true;
161 break;
162 }
163 }
164
165 if !found {
166 panic!("unable to find commit {}", test.sha)
167 }
168 let status =
169 Command::new("git").arg("clean").arg("-fdx").current_dir(&out_dir).status().unwrap();
170 assert!(status.success());
171
172 out_dir
173 }
174
175 fn run_cargo_test(
176 cargo_path: &Path,
177 crate_path: &Path,
178 packages: &[&str],
179 features: Option<&[&str]>,
180 manifest_path: Option<&str>,
181 filters: &[&str],
182 ) -> bool {
183 let mut command = Command::new(cargo_path);
184 command.arg("test");
185
186 if let Some(path) = manifest_path {
187 command.arg(format!("--manifest-path={}", path));
188 }
189
190 if let Some(features) = features {
191 command.arg("--no-default-features");
192 for feature in features {
193 command.arg(format!("--features={}", feature));
194 }
195 }
196
197 for name in packages {
198 command.arg("-p").arg(name);
199 }
200
201 command.arg("--");
202 command.args(filters);
203
204 let status = command
205 // Disable rust-lang/cargo's cross-compile tests
206 .env("CFG_DISABLE_CROSS_TESTS", "1")
207 // Relax #![deny(warnings)] in some crates
208 .env("RUSTFLAGS", "--cap-lints warn")
209 .current_dir(crate_path)
210 .status()
211 .unwrap();
212
213 status.success()
214 }