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