]> git.lizzy.rs Git - rust.git/blob - src/tools/compiletest/src/common.rs
Auto merge of #79790 - LeSeulArtichaut:issue-79683, r=lcnr
[rust.git] / src / tools / compiletest / src / common.rs
1 pub use self::Mode::*;
2
3 use std::ffi::OsString;
4 use std::fmt;
5 use std::path::{Path, PathBuf};
6 use std::str::FromStr;
7
8 use crate::util::PathBufExt;
9 use test::ColorConfig;
10
11 #[derive(Clone, Copy, PartialEq, Debug)]
12 pub enum Mode {
13     CompileFail,
14     RunFail,
15     RunPassValgrind,
16     Pretty,
17     DebugInfo,
18     Codegen,
19     Rustdoc,
20     RustdocJson,
21     CodegenUnits,
22     Incremental,
23     RunMake,
24     Ui,
25     JsDocTest,
26     MirOpt,
27     Assembly,
28 }
29
30 impl Mode {
31     pub fn disambiguator(self) -> &'static str {
32         // Pretty-printing tests could run concurrently, and if they do,
33         // they need to keep their output segregated.
34         match self {
35             Pretty => ".pretty",
36             _ => "",
37         }
38     }
39 }
40
41 impl FromStr for Mode {
42     type Err = ();
43     fn from_str(s: &str) -> Result<Mode, ()> {
44         match s {
45             "compile-fail" => Ok(CompileFail),
46             "run-fail" => Ok(RunFail),
47             "run-pass-valgrind" => Ok(RunPassValgrind),
48             "pretty" => Ok(Pretty),
49             "debuginfo" => Ok(DebugInfo),
50             "codegen" => Ok(Codegen),
51             "rustdoc" => Ok(Rustdoc),
52             "rustdoc-json" => Ok(RustdocJson),
53             "codegen-units" => Ok(CodegenUnits),
54             "incremental" => Ok(Incremental),
55             "run-make" => Ok(RunMake),
56             "ui" => Ok(Ui),
57             "js-doc-test" => Ok(JsDocTest),
58             "mir-opt" => Ok(MirOpt),
59             "assembly" => Ok(Assembly),
60             _ => Err(()),
61         }
62     }
63 }
64
65 impl fmt::Display for Mode {
66     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67         let s = match *self {
68             CompileFail => "compile-fail",
69             RunFail => "run-fail",
70             RunPassValgrind => "run-pass-valgrind",
71             Pretty => "pretty",
72             DebugInfo => "debuginfo",
73             Codegen => "codegen",
74             Rustdoc => "rustdoc",
75             RustdocJson => "rustdoc-json",
76             CodegenUnits => "codegen-units",
77             Incremental => "incremental",
78             RunMake => "run-make",
79             Ui => "ui",
80             JsDocTest => "js-doc-test",
81             MirOpt => "mir-opt",
82             Assembly => "assembly",
83         };
84         fmt::Display::fmt(s, f)
85     }
86 }
87
88 #[derive(Clone, Copy, PartialEq, Debug, Hash)]
89 pub enum PassMode {
90     Check,
91     Build,
92     Run,
93 }
94
95 impl FromStr for PassMode {
96     type Err = ();
97     fn from_str(s: &str) -> Result<Self, ()> {
98         match s {
99             "check" => Ok(PassMode::Check),
100             "build" => Ok(PassMode::Build),
101             "run" => Ok(PassMode::Run),
102             _ => Err(()),
103         }
104     }
105 }
106
107 impl fmt::Display for PassMode {
108     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109         let s = match *self {
110             PassMode::Check => "check",
111             PassMode::Build => "build",
112             PassMode::Run => "run",
113         };
114         fmt::Display::fmt(s, f)
115     }
116 }
117
118 #[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
119 pub enum FailMode {
120     Check,
121     Build,
122     Run,
123 }
124
125 #[derive(Clone, Debug, PartialEq)]
126 pub enum CompareMode {
127     Nll,
128     Polonius,
129     Chalk,
130     SplitDwarf,
131     SplitDwarfSingle,
132 }
133
134 impl CompareMode {
135     pub(crate) fn to_str(&self) -> &'static str {
136         match *self {
137             CompareMode::Nll => "nll",
138             CompareMode::Polonius => "polonius",
139             CompareMode::Chalk => "chalk",
140             CompareMode::SplitDwarf => "split-dwarf",
141             CompareMode::SplitDwarfSingle => "split-dwarf-single",
142         }
143     }
144
145     pub fn parse(s: String) -> CompareMode {
146         match s.as_str() {
147             "nll" => CompareMode::Nll,
148             "polonius" => CompareMode::Polonius,
149             "chalk" => CompareMode::Chalk,
150             "split-dwarf" => CompareMode::SplitDwarf,
151             "split-dwarf-single" => CompareMode::SplitDwarfSingle,
152             x => panic!("unknown --compare-mode option: {}", x),
153         }
154     }
155 }
156
157 #[derive(Clone, Copy, Debug, PartialEq)]
158 pub enum Debugger {
159     Cdb,
160     Gdb,
161     Lldb,
162 }
163
164 impl Debugger {
165     fn to_str(&self) -> &'static str {
166         match self {
167             Debugger::Cdb => "cdb",
168             Debugger::Gdb => "gdb",
169             Debugger::Lldb => "lldb",
170         }
171     }
172 }
173
174 impl fmt::Display for Debugger {
175     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176         fmt::Display::fmt(self.to_str(), f)
177     }
178 }
179
180 /// Configuration for compiletest
181 #[derive(Debug, Clone)]
182 pub struct Config {
183     /// `true` to to overwrite stderr/stdout files instead of complaining about changes in output.
184     pub bless: bool,
185
186     /// The library paths required for running the compiler.
187     pub compile_lib_path: PathBuf,
188
189     /// The library paths required for running compiled programs.
190     pub run_lib_path: PathBuf,
191
192     /// The rustc executable.
193     pub rustc_path: PathBuf,
194
195     /// The rustdoc executable.
196     pub rustdoc_path: Option<PathBuf>,
197
198     /// The rust-demangler executable.
199     pub rust_demangler_path: Option<PathBuf>,
200
201     /// The Python executable to use for LLDB.
202     pub lldb_python: String,
203
204     /// The Python executable to use for htmldocck.
205     pub docck_python: String,
206
207     /// The LLVM `FileCheck` binary path.
208     pub llvm_filecheck: Option<PathBuf>,
209
210     /// Path to LLVM's bin directory.
211     pub llvm_bin_dir: Option<PathBuf>,
212
213     /// The valgrind path.
214     pub valgrind_path: Option<String>,
215
216     /// Whether to fail if we can't run run-pass-valgrind tests under valgrind
217     /// (or, alternatively, to silently run them like regular run-pass tests).
218     pub force_valgrind: bool,
219
220     /// The path to the Clang executable to run Clang-based tests with. If
221     /// `None` then these tests will be ignored.
222     pub run_clang_based_tests_with: Option<String>,
223
224     /// The directory containing the tests to run
225     pub src_base: PathBuf,
226
227     /// The directory where programs should be built
228     pub build_base: PathBuf,
229
230     /// The name of the stage being built (stage1, etc)
231     pub stage_id: String,
232
233     /// The test mode, compile-fail, run-fail, ui
234     pub mode: Mode,
235
236     /// The test suite (essentially which directory is running, but without the
237     /// directory prefix such as src/test)
238     pub suite: String,
239
240     /// The debugger to use in debuginfo mode. Unset otherwise.
241     pub debugger: Option<Debugger>,
242
243     /// Run ignored tests
244     pub run_ignored: bool,
245
246     /// Only run tests that match this filter
247     pub filter: Option<String>,
248
249     /// Exactly match the filter, rather than a substring
250     pub filter_exact: bool,
251
252     /// Force the pass mode of a check/build/run-pass test to this mode.
253     pub force_pass_mode: Option<PassMode>,
254
255     /// Write out a parseable log of tests that were run
256     pub logfile: Option<PathBuf>,
257
258     /// A command line to prefix program execution with,
259     /// for running under valgrind
260     pub runtool: Option<String>,
261
262     /// Flags to pass to the compiler when building for the host
263     pub host_rustcflags: Option<String>,
264
265     /// Flags to pass to the compiler when building for the target
266     pub target_rustcflags: Option<String>,
267
268     /// Target system to be tested
269     pub target: String,
270
271     /// Host triple for the compiler being invoked
272     pub host: String,
273
274     /// Path to / name of the Microsoft Console Debugger (CDB) executable
275     pub cdb: Option<OsString>,
276
277     /// Version of CDB
278     pub cdb_version: Option<[u16; 4]>,
279
280     /// Path to / name of the GDB executable
281     pub gdb: Option<String>,
282
283     /// Version of GDB, encoded as ((major * 1000) + minor) * 1000 + patch
284     pub gdb_version: Option<u32>,
285
286     /// Whether GDB has native rust support
287     pub gdb_native_rust: bool,
288
289     /// Version of LLDB
290     pub lldb_version: Option<u32>,
291
292     /// Whether LLDB has native rust support
293     pub lldb_native_rust: bool,
294
295     /// Version of LLVM
296     pub llvm_version: Option<u32>,
297
298     /// Is LLVM a system LLVM
299     pub system_llvm: bool,
300
301     /// Path to the android tools
302     pub android_cross_path: PathBuf,
303
304     /// Extra parameter to run adb on arm-linux-androideabi
305     pub adb_path: String,
306
307     /// Extra parameter to run test suite on arm-linux-androideabi
308     pub adb_test_dir: String,
309
310     /// status whether android device available or not
311     pub adb_device_status: bool,
312
313     /// the path containing LLDB's Python module
314     pub lldb_python_dir: Option<String>,
315
316     /// Explain what's going on
317     pub verbose: bool,
318
319     /// Print one character per test instead of one line
320     pub quiet: bool,
321
322     /// Whether to use colors in test.
323     pub color: ColorConfig,
324
325     /// where to find the remote test client process, if we're using it
326     pub remote_test_client: Option<PathBuf>,
327
328     /// mode describing what file the actual ui output will be compared to
329     pub compare_mode: Option<CompareMode>,
330
331     /// If true, this will generate a coverage file with UI test files that run `MachineApplicable`
332     /// diagnostics but are missing `run-rustfix` annotations. The generated coverage file is
333     /// created in `/<build_base>/rustfix_missing_coverage.txt`
334     pub rustfix_coverage: bool,
335
336     /// whether to run `tidy` when a rustdoc test fails
337     pub has_tidy: bool,
338
339     // Configuration for various run-make tests frobbing things like C compilers
340     // or querying about various LLVM component information.
341     pub cc: String,
342     pub cxx: String,
343     pub cflags: String,
344     pub ar: String,
345     pub linker: Option<String>,
346     pub llvm_components: String,
347
348     /// Path to a NodeJS executable. Used for JS doctests, emscripten and WASM tests
349     pub nodejs: Option<String>,
350 }
351
352 #[derive(Debug, Clone)]
353 pub struct TestPaths {
354     pub file: PathBuf,         // e.g., compile-test/foo/bar/baz.rs
355     pub relative_dir: PathBuf, // e.g., foo/bar
356 }
357
358 /// Used by `ui` tests to generate things like `foo.stderr` from `foo.rs`.
359 pub fn expected_output_path(
360     testpaths: &TestPaths,
361     revision: Option<&str>,
362     compare_mode: &Option<CompareMode>,
363     kind: &str,
364 ) -> PathBuf {
365     assert!(UI_EXTENSIONS.contains(&kind));
366     let mut parts = Vec::new();
367
368     if let Some(x) = revision {
369         parts.push(x);
370     }
371     if let Some(ref x) = *compare_mode {
372         parts.push(x.to_str());
373     }
374     parts.push(kind);
375
376     let extension = parts.join(".");
377     testpaths.file.with_extension(extension)
378 }
379
380 pub const UI_EXTENSIONS: &[&str] = &[UI_STDERR, UI_STDOUT, UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT];
381 pub const UI_STDERR: &str = "stderr";
382 pub const UI_STDOUT: &str = "stdout";
383 pub const UI_FIXED: &str = "fixed";
384 pub const UI_RUN_STDERR: &str = "run.stderr";
385 pub const UI_RUN_STDOUT: &str = "run.stdout";
386
387 /// Absolute path to the directory where all output for all tests in the given
388 /// `relative_dir` group should reside. Example:
389 ///   /path/to/build/host-triple/test/ui/relative/
390 /// This is created early when tests are collected to avoid race conditions.
391 pub fn output_relative_path(config: &Config, relative_dir: &Path) -> PathBuf {
392     config.build_base.join(relative_dir)
393 }
394
395 /// Generates a unique name for the test, such as `testname.revision.mode`.
396 pub fn output_testname_unique(
397     config: &Config,
398     testpaths: &TestPaths,
399     revision: Option<&str>,
400 ) -> PathBuf {
401     let mode = config.compare_mode.as_ref().map_or("", |m| m.to_str());
402     let debugger = config.debugger.as_ref().map_or("", |m| m.to_str());
403     PathBuf::from(&testpaths.file.file_stem().unwrap())
404         .with_extra_extension(revision.unwrap_or(""))
405         .with_extra_extension(mode)
406         .with_extra_extension(debugger)
407 }
408
409 /// Absolute path to the directory where all output for the given
410 /// test/revision should reside. Example:
411 ///   /path/to/build/host-triple/test/ui/relative/testname.revision.mode/
412 pub fn output_base_dir(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> PathBuf {
413     output_relative_path(config, &testpaths.relative_dir)
414         .join(output_testname_unique(config, testpaths, revision))
415 }
416
417 /// Absolute path to the base filename used as output for the given
418 /// test/revision. Example:
419 ///   /path/to/build/host-triple/test/ui/relative/testname.revision.mode/testname
420 pub fn output_base_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> PathBuf {
421     output_base_dir(config, testpaths, revision).join(testpaths.file.file_stem().unwrap())
422 }