]> git.lizzy.rs Git - rust.git/blob - src/tools/compiletest/src/common.rs
Rollup merge of #97837 - sunfishcode:sunfishcode/proc-self-mem, r=m-ou-se
[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     Polonius,
122     Chalk,
123     SplitDwarf,
124     SplitDwarfSingle,
125 }
126
127 impl CompareMode {
128     pub(crate) fn to_str(&self) -> &'static str {
129         match *self {
130             CompareMode::Polonius => "polonius",
131             CompareMode::Chalk => "chalk",
132             CompareMode::SplitDwarf => "split-dwarf",
133             CompareMode::SplitDwarfSingle => "split-dwarf-single",
134         }
135     }
136
137     pub fn parse(s: String) -> CompareMode {
138         match s.as_str() {
139             "polonius" => CompareMode::Polonius,
140             "chalk" => CompareMode::Chalk,
141             "split-dwarf" => CompareMode::SplitDwarf,
142             "split-dwarf-single" => CompareMode::SplitDwarfSingle,
143             x => panic!("unknown --compare-mode option: {}", x),
144         }
145     }
146 }
147
148 #[derive(Clone, Copy, Debug, PartialEq)]
149 pub enum Debugger {
150     Cdb,
151     Gdb,
152     Lldb,
153 }
154
155 impl Debugger {
156     fn to_str(&self) -> &'static str {
157         match self {
158             Debugger::Cdb => "cdb",
159             Debugger::Gdb => "gdb",
160             Debugger::Lldb => "lldb",
161         }
162     }
163 }
164
165 impl fmt::Display for Debugger {
166     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167         fmt::Display::fmt(self.to_str(), f)
168     }
169 }
170
171 #[derive(Clone, Copy, Debug, PartialEq)]
172 pub enum PanicStrategy {
173     Unwind,
174     Abort,
175 }
176
177 /// Configuration for compiletest
178 #[derive(Debug, Clone)]
179 pub struct Config {
180     /// `true` to overwrite stderr/stdout files instead of complaining about changes in output.
181     pub bless: bool,
182
183     /// The library paths required for running the compiler.
184     pub compile_lib_path: PathBuf,
185
186     /// The library paths required for running compiled programs.
187     pub run_lib_path: PathBuf,
188
189     /// The rustc executable.
190     pub rustc_path: PathBuf,
191
192     /// The rustdoc executable.
193     pub rustdoc_path: Option<PathBuf>,
194
195     /// The rust-demangler executable.
196     pub rust_demangler_path: Option<PathBuf>,
197
198     /// The Python executable to use for LLDB and htmldocck.
199     pub python: String,
200
201     /// The jsondocck executable.
202     pub jsondocck_path: Option<String>,
203
204     /// The LLVM `FileCheck` binary path.
205     pub llvm_filecheck: Option<PathBuf>,
206
207     /// Path to LLVM's bin directory.
208     pub llvm_bin_dir: Option<PathBuf>,
209
210     /// The valgrind path.
211     pub valgrind_path: Option<String>,
212
213     /// Whether to fail if we can't run run-pass-valgrind tests under valgrind
214     /// (or, alternatively, to silently run them like regular run-pass tests).
215     pub force_valgrind: bool,
216
217     /// The path to the Clang executable to run Clang-based tests with. If
218     /// `None` then these tests will be ignored.
219     pub run_clang_based_tests_with: Option<String>,
220
221     /// The directory containing the tests to run
222     pub src_base: PathBuf,
223
224     /// The directory where programs should be built
225     pub build_base: PathBuf,
226
227     /// The name of the stage being built (stage1, etc)
228     pub stage_id: String,
229
230     /// The test mode, e.g. ui or debuginfo.
231     pub mode: Mode,
232
233     /// The test suite (essentially which directory is running, but without the
234     /// directory prefix such as src/test)
235     pub suite: String,
236
237     /// The debugger to use in debuginfo mode. Unset otherwise.
238     pub debugger: Option<Debugger>,
239
240     /// Run ignored tests
241     pub run_ignored: bool,
242
243     /// Only run tests that match these filters
244     pub filters: Vec<String>,
245
246     /// Skip tests tests matching these substrings. Corresponds to
247     /// `test::TestOpts::skip`. `filter_exact` does not apply to these flags.
248     pub skip: Vec<String>,
249
250     /// Exactly match the filter, rather than a substring
251     pub filter_exact: bool,
252
253     /// Force the pass mode of a check/build/run-pass test to this mode.
254     pub force_pass_mode: Option<PassMode>,
255
256     /// Explicitly enable or disable running.
257     pub run: Option<bool>,
258
259     /// Write out a parseable log of tests that were run
260     pub logfile: Option<PathBuf>,
261
262     /// A command line to prefix program execution with,
263     /// for running under valgrind
264     pub runtool: Option<String>,
265
266     /// Flags to pass to the compiler when building for the host
267     pub host_rustcflags: Option<String>,
268
269     /// Flags to pass to the compiler when building for the target
270     pub target_rustcflags: Option<String>,
271
272     /// What panic strategy the target is built with.  Unwind supports Abort, but
273     /// not vice versa.
274     pub target_panic: PanicStrategy,
275
276     /// Target system to be tested
277     pub target: String,
278
279     /// Host triple for the compiler being invoked
280     pub host: String,
281
282     /// Path to / name of the Microsoft Console Debugger (CDB) executable
283     pub cdb: Option<OsString>,
284
285     /// Version of CDB
286     pub cdb_version: Option<[u16; 4]>,
287
288     /// Path to / name of the GDB executable
289     pub gdb: Option<String>,
290
291     /// Version of GDB, encoded as ((major * 1000) + minor) * 1000 + patch
292     pub gdb_version: Option<u32>,
293
294     /// Whether GDB has native rust support
295     pub gdb_native_rust: bool,
296
297     /// Version of LLDB
298     pub lldb_version: Option<u32>,
299
300     /// Whether LLDB has native rust support
301     pub lldb_native_rust: bool,
302
303     /// Version of LLVM
304     pub llvm_version: Option<u32>,
305
306     /// Is LLVM a system LLVM
307     pub system_llvm: bool,
308
309     /// Path to the android tools
310     pub android_cross_path: PathBuf,
311
312     /// Extra parameter to run adb on arm-linux-androideabi
313     pub adb_path: String,
314
315     /// Extra parameter to run test suite on arm-linux-androideabi
316     pub adb_test_dir: String,
317
318     /// status whether android device available or not
319     pub adb_device_status: bool,
320
321     /// the path containing LLDB's Python module
322     pub lldb_python_dir: Option<String>,
323
324     /// Explain what's going on
325     pub verbose: bool,
326
327     /// Print one character per test instead of one line
328     pub quiet: bool,
329
330     /// Whether to use colors in test.
331     pub color: ColorConfig,
332
333     /// where to find the remote test client process, if we're using it
334     pub remote_test_client: Option<PathBuf>,
335
336     /// mode describing what file the actual ui output will be compared to
337     pub compare_mode: Option<CompareMode>,
338
339     /// If true, this will generate a coverage file with UI test files that run `MachineApplicable`
340     /// diagnostics but are missing `run-rustfix` annotations. The generated coverage file is
341     /// created in `/<build_base>/rustfix_missing_coverage.txt`
342     pub rustfix_coverage: bool,
343
344     /// whether to run `tidy` when a rustdoc test fails
345     pub has_tidy: bool,
346
347     /// The current Rust channel
348     pub channel: String,
349
350     /// The default Rust edition
351     pub edition: Option<String>,
352
353     // Configuration for various run-make tests frobbing things like C compilers
354     // or querying about various LLVM component information.
355     pub cc: String,
356     pub cxx: String,
357     pub cflags: String,
358     pub cxxflags: String,
359     pub ar: String,
360     pub linker: Option<String>,
361     pub llvm_components: String,
362
363     /// Path to a NodeJS executable. Used for JS doctests, emscripten and WASM tests
364     pub nodejs: Option<String>,
365     /// Path to a npm executable. Used for rustdoc GUI tests
366     pub npm: Option<String>,
367
368     /// Whether to rerun tests even if the inputs are unchanged.
369     pub force_rerun: bool,
370 }
371
372 impl Config {
373     pub fn run_enabled(&self) -> bool {
374         self.run.unwrap_or_else(|| {
375             // Auto-detect whether to run based on the platform.
376             !self.target.ends_with("-fuchsia")
377         })
378     }
379 }
380
381 #[derive(Debug, Clone)]
382 pub struct TestPaths {
383     pub file: PathBuf,         // e.g., compile-test/foo/bar/baz.rs
384     pub relative_dir: PathBuf, // e.g., foo/bar
385 }
386
387 /// Used by `ui` tests to generate things like `foo.stderr` from `foo.rs`.
388 pub fn expected_output_path(
389     testpaths: &TestPaths,
390     revision: Option<&str>,
391     compare_mode: &Option<CompareMode>,
392     kind: &str,
393 ) -> PathBuf {
394     assert!(UI_EXTENSIONS.contains(&kind));
395     let mut parts = Vec::new();
396
397     if let Some(x) = revision {
398         parts.push(x);
399     }
400     if let Some(ref x) = *compare_mode {
401         parts.push(x.to_str());
402     }
403     parts.push(kind);
404
405     let extension = parts.join(".");
406     testpaths.file.with_extension(extension)
407 }
408
409 pub const UI_EXTENSIONS: &[&str] = &[
410     UI_STDERR,
411     UI_STDOUT,
412     UI_FIXED,
413     UI_RUN_STDERR,
414     UI_RUN_STDOUT,
415     UI_STDERR_64,
416     UI_STDERR_32,
417     UI_STDERR_16,
418 ];
419 pub const UI_STDERR: &str = "stderr";
420 pub const UI_STDOUT: &str = "stdout";
421 pub const UI_FIXED: &str = "fixed";
422 pub const UI_RUN_STDERR: &str = "run.stderr";
423 pub const UI_RUN_STDOUT: &str = "run.stdout";
424 pub const UI_STDERR_64: &str = "64bit.stderr";
425 pub const UI_STDERR_32: &str = "32bit.stderr";
426 pub const UI_STDERR_16: &str = "16bit.stderr";
427
428 /// Absolute path to the directory where all output for all tests in the given
429 /// `relative_dir` group should reside. Example:
430 ///   /path/to/build/host-triple/test/ui/relative/
431 /// This is created early when tests are collected to avoid race conditions.
432 pub fn output_relative_path(config: &Config, relative_dir: &Path) -> PathBuf {
433     config.build_base.join(relative_dir)
434 }
435
436 /// Generates a unique name for the test, such as `testname.revision.mode`.
437 pub fn output_testname_unique(
438     config: &Config,
439     testpaths: &TestPaths,
440     revision: Option<&str>,
441 ) -> PathBuf {
442     let mode = config.compare_mode.as_ref().map_or("", |m| m.to_str());
443     let debugger = config.debugger.as_ref().map_or("", |m| m.to_str());
444     PathBuf::from(&testpaths.file.file_stem().unwrap())
445         .with_extra_extension(revision.unwrap_or(""))
446         .with_extra_extension(mode)
447         .with_extra_extension(debugger)
448 }
449
450 /// Absolute path to the directory where all output for the given
451 /// test/revision should reside. Example:
452 ///   /path/to/build/host-triple/test/ui/relative/testname.revision.mode/
453 pub fn output_base_dir(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> PathBuf {
454     output_relative_path(config, &testpaths.relative_dir)
455         .join(output_testname_unique(config, testpaths, revision))
456 }
457
458 /// Absolute path to the base filename used as output for the given
459 /// test/revision. Example:
460 ///   /path/to/build/host-triple/test/ui/relative/testname.revision.mode/testname
461 pub fn output_base_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> PathBuf {
462     output_base_dir(config, testpaths, revision).join(testpaths.file.file_stem().unwrap())
463 }
464
465 /// Absolute path to the directory to use for incremental compilation. Example:
466 ///   /path/to/build/host-triple/test/ui/relative/testname.mode/testname.inc
467 pub fn incremental_dir(config: &Config, testpaths: &TestPaths) -> PathBuf {
468     output_base_name(config, testpaths, None).with_extension("inc")
469 }