]> git.proxmox.com Git - rustc.git/blob - vendor/compiletest_rs/src/common.rs
New upstream version 1.57.0+dfsg1
[rustc.git] / vendor / compiletest_rs / src / common.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 pub use self::Mode::*;
11
12 use std::env;
13 use std::fmt;
14 use std::fs::{read_dir, remove_file};
15 use std::str::FromStr;
16 use std::path::PathBuf;
17 #[cfg(feature = "rustc")]
18 use rustc_session;
19
20 use test::ColorConfig;
21 use runtest::dylib_env_var;
22
23 #[derive(Clone, Copy, PartialEq, Debug)]
24 pub enum Mode {
25 CompileFail,
26 ParseFail,
27 RunFail,
28 RunPass,
29 RunPassValgrind,
30 Pretty,
31 DebugInfoGdb,
32 DebugInfoLldb,
33 Codegen,
34 Rustdoc,
35 CodegenUnits,
36 Incremental,
37 RunMake,
38 Ui,
39 MirOpt,
40 Assembly,
41 }
42
43 impl Mode {
44 pub fn disambiguator(self) -> &'static str {
45 // Run-pass and pretty run-pass tests could run concurrently, and if they do,
46 // they need to keep their output segregated. Same is true for debuginfo tests that
47 // can be run both on gdb and lldb.
48 match self {
49 Pretty => ".pretty",
50 DebugInfoGdb => ".gdb",
51 DebugInfoLldb => ".lldb",
52 _ => "",
53 }
54 }
55 }
56
57 impl FromStr for Mode {
58 type Err = ();
59 fn from_str(s: &str) -> Result<Mode, ()> {
60 match s {
61 "compile-fail" => Ok(CompileFail),
62 "parse-fail" => Ok(ParseFail),
63 "run-fail" => Ok(RunFail),
64 "run-pass" => Ok(RunPass),
65 "run-pass-valgrind" => Ok(RunPassValgrind),
66 "pretty" => Ok(Pretty),
67 "debuginfo-lldb" => Ok(DebugInfoLldb),
68 "debuginfo-gdb" => Ok(DebugInfoGdb),
69 "codegen" => Ok(Codegen),
70 "rustdoc" => Ok(Rustdoc),
71 "codegen-units" => Ok(CodegenUnits),
72 "incremental" => Ok(Incremental),
73 "run-make" => Ok(RunMake),
74 "ui" => Ok(Ui),
75 "mir-opt" => Ok(MirOpt),
76 "assembly" => Ok(Assembly),
77 _ => Err(()),
78 }
79 }
80 }
81
82 impl fmt::Display for Mode {
83 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84 fmt::Display::fmt(match *self {
85 CompileFail => "compile-fail",
86 ParseFail => "parse-fail",
87 RunFail => "run-fail",
88 RunPass => "run-pass",
89 RunPassValgrind => "run-pass-valgrind",
90 Pretty => "pretty",
91 DebugInfoGdb => "debuginfo-gdb",
92 DebugInfoLldb => "debuginfo-lldb",
93 Codegen => "codegen",
94 Rustdoc => "rustdoc",
95 CodegenUnits => "codegen-units",
96 Incremental => "incremental",
97 RunMake => "run-make",
98 Ui => "ui",
99 MirOpt => "mir-opt",
100 Assembly => "assembly",
101 },
102 f)
103 }
104 }
105
106 #[derive(Clone)]
107 pub struct Config {
108 /// `true` to overwrite stderr/stdout/fixed files instead of complaining about changes in output.
109 pub bless: bool,
110
111 /// The library paths required for running the compiler
112 pub compile_lib_path: PathBuf,
113
114 /// The library paths required for running compiled programs
115 pub run_lib_path: PathBuf,
116
117 /// The rustc executable
118 pub rustc_path: PathBuf,
119
120 /// The rustdoc executable
121 pub rustdoc_path: Option<PathBuf>,
122
123 /// The python executable to use for LLDB
124 pub lldb_python: String,
125
126 /// The python executable to use for htmldocck
127 pub docck_python: String,
128
129 /// The llvm FileCheck binary path
130 pub llvm_filecheck: Option<PathBuf>,
131
132 /// The valgrind path
133 pub valgrind_path: Option<String>,
134
135 /// Whether to fail if we can't run run-pass-valgrind tests under valgrind
136 /// (or, alternatively, to silently run them like regular run-pass tests).
137 pub force_valgrind: bool,
138
139 /// The directory containing the tests to run
140 pub src_base: PathBuf,
141
142 /// The directory where programs should be built
143 pub build_base: PathBuf,
144
145 /// The name of the stage being built (stage1, etc)
146 pub stage_id: String,
147
148 /// The test mode, compile-fail, run-fail, run-pass
149 pub mode: Mode,
150
151 /// Run ignored tests
152 pub run_ignored: bool,
153
154 /// Only run tests that match these filters
155 pub filters: Vec<String>,
156
157 /// Exactly match the filter, rather than a substring
158 pub filter_exact: bool,
159
160 /// Write out a parseable log of tests that were run
161 pub logfile: Option<PathBuf>,
162
163 /// A command line to prefix program execution with,
164 /// for running under valgrind
165 pub runtool: Option<String>,
166
167 /// Flags to pass to the compiler when building for the host
168 pub host_rustcflags: Option<String>,
169
170 /// Flags to pass to the compiler when building for the target
171 pub target_rustcflags: Option<String>,
172
173 /// Target system to be tested
174 pub target: String,
175
176 /// Host triple for the compiler being invoked
177 pub host: String,
178
179 /// Path to / name of the GDB executable
180 pub gdb: Option<String>,
181
182 /// Version of GDB, encoded as ((major * 1000) + minor) * 1000 + patch
183 pub gdb_version: Option<u32>,
184
185 /// Whether GDB has native rust support
186 pub gdb_native_rust: bool,
187
188 /// Version of LLDB
189 pub lldb_version: Option<String>,
190
191 /// Version of LLVM
192 pub llvm_version: Option<String>,
193
194 /// Is LLVM a system LLVM
195 pub system_llvm: bool,
196
197 /// Path to the android tools
198 pub android_cross_path: PathBuf,
199
200 /// Extra parameter to run adb on arm-linux-androideabi
201 pub adb_path: String,
202
203 /// Extra parameter to run test suite on arm-linux-androideabi
204 pub adb_test_dir: String,
205
206 /// status whether android device available or not
207 pub adb_device_status: bool,
208
209 /// the path containing LLDB's Python module
210 pub lldb_python_dir: Option<String>,
211
212 /// Explain what's going on
213 pub verbose: bool,
214
215 /// Print one character per test instead of one line
216 pub quiet: bool,
217
218 /// Whether to use colors in test.
219 pub color: ColorConfig,
220
221 /// where to find the remote test client process, if we're using it
222 pub remote_test_client: Option<PathBuf>,
223
224 /// If true, this will generate a coverage file with UI test files that run `MachineApplicable`
225 /// diagnostics but are missing `run-rustfix` annotations. The generated coverage file is
226 /// created in `/<build_base>/rustfix_missing_coverage.txt`
227 pub rustfix_coverage: bool,
228
229 // Configuration for various run-make tests frobbing things like C compilers
230 // or querying about various LLVM component information.
231 pub cc: String,
232 pub cxx: String,
233 pub cflags: String,
234 pub ar: String,
235 pub linker: Option<String>,
236 pub llvm_components: String,
237 pub llvm_cxxflags: String,
238 pub nodejs: Option<String>,
239 }
240
241 #[derive(Clone)]
242 pub struct TestPaths {
243 pub file: PathBuf, // e.g., compile-test/foo/bar/baz.rs
244 pub base: PathBuf, // e.g., compile-test, auxiliary
245 pub relative_dir: PathBuf, // e.g., foo/bar
246 }
247
248 /// Used by `ui` tests to generate things like `foo.stderr` from `foo.rs`.
249 pub fn expected_output_path(
250 testpaths: &TestPaths,
251 revision: Option<&str>,
252 kind: &str,
253 ) -> PathBuf {
254 assert!(UI_EXTENSIONS.contains(&kind));
255 let mut parts = Vec::new();
256
257 if let Some(x) = revision {
258 parts.push(x);
259 }
260 parts.push(kind);
261
262 let extension = parts.join(".");
263 testpaths.file.with_extension(extension)
264 }
265
266 pub const UI_EXTENSIONS: &[&str] = &[UI_STDERR, UI_STDOUT, UI_FIXED];
267 pub const UI_STDERR: &str = "stderr";
268 pub const UI_STDOUT: &str = "stdout";
269 pub const UI_FIXED: &str = "fixed";
270
271 impl Config {
272 /// Add rustc flags to link with the crate's dependencies in addition to the crate itself
273 pub fn link_deps(&mut self) {
274 let varname = dylib_env_var();
275
276 // Dependencies can be found in the environment variable. Throw everything there into the
277 // link flags
278 let lib_paths = env::var(varname).unwrap_or_else(|err| match err {
279 env::VarError::NotPresent => String::new(),
280 err => panic!("can't get {} environment variable: {}", varname, err),
281 });
282
283 // Append to current flags if any are set, otherwise make new String
284 let mut flags = self.target_rustcflags.take().unwrap_or_else(String::new);
285 if !lib_paths.is_empty() {
286 for p in env::split_paths(&lib_paths) {
287 flags += " -L ";
288 flags += p.to_str().unwrap(); // Can't fail. We already know this is unicode
289 }
290 }
291
292 self.target_rustcflags = Some(flags);
293 }
294
295 /// Remove rmeta files from target `deps` directory
296 ///
297 /// These files are created by `cargo check`, and conflict with
298 /// `cargo build` rlib files, causing E0464 for tests which use
299 /// the parent crate.
300 pub fn clean_rmeta(&self) {
301 if self.target_rustcflags.is_some() {
302 for directory in self.target_rustcflags
303 .as_ref()
304 .unwrap()
305 .split_whitespace()
306 .filter(|s| s.ends_with("/deps"))
307 {
308 if let Ok(mut entries) = read_dir(directory) {
309 while let Some(Ok(entry)) = entries.next() {
310 if entry.file_name().to_string_lossy().ends_with(".rmeta") {
311 let _ = remove_file(entry.path());
312 }
313 }
314 }
315 }
316 }
317 }
318
319 #[cfg(feature = "tmp")]
320 pub fn tempdir(mut self) -> ConfigWithTemp {
321 let tmp = tempfile::Builder::new().prefix("compiletest").tempdir()
322 .expect("failed to create temporary directory");
323 self.build_base = tmp.path().to_owned();
324 config_tempdir::ConfigWithTemp {
325 config: self,
326 tempdir: tmp,
327 }
328 }
329 }
330
331 #[cfg(feature = "tmp")]
332 mod config_tempdir {
333 use tempfile;
334 use std::ops;
335
336 pub struct ConfigWithTemp {
337 pub config: super::Config,
338 pub tempdir: tempfile::TempDir,
339 }
340
341 impl ops::Deref for ConfigWithTemp {
342 type Target = super::Config;
343
344 fn deref(&self) -> &Self::Target {
345 &self.config
346 }
347 }
348
349 impl ops::DerefMut for ConfigWithTemp {
350 fn deref_mut(&mut self) -> &mut Self::Target {
351 &mut self.config
352 }
353 }
354 }
355
356 #[cfg(feature = "tmp")]
357 pub use self::config_tempdir::ConfigWithTemp;
358
359
360 impl Default for Config {
361 fn default() -> Config {
362 #[cfg(feature = "rustc")]
363 let platform = rustc_session::config::host_triple().to_string();
364
365 Config {
366 bless: false,
367 compile_lib_path: PathBuf::from(""),
368 run_lib_path: PathBuf::from(""),
369 rustc_path: PathBuf::from("rustc"),
370 rustdoc_path: None,
371 lldb_python: "python".to_owned(),
372 docck_python: "docck-python".to_owned(),
373 valgrind_path: None,
374 force_valgrind: false,
375 llvm_filecheck: None,
376 src_base: PathBuf::from("tests/run-pass"),
377 build_base: env::temp_dir(),
378 stage_id: "stage-id".to_owned(),
379 mode: Mode::RunPass,
380 run_ignored: false,
381 filters: vec![],
382 filter_exact: false,
383 logfile: None,
384 runtool: None,
385 host_rustcflags: None,
386 target_rustcflags: None,
387 #[cfg(feature = "rustc")]
388 target: platform.clone(),
389 #[cfg(not(feature = "rustc"))]
390 target: env!("TARGET").to_string(),
391 #[cfg(feature = "rustc")]
392 host: platform.clone(),
393 #[cfg(not(feature = "rustc"))]
394 host: env!("HOST").to_string(),
395 rustfix_coverage: false,
396 gdb: None,
397 gdb_version: None,
398 gdb_native_rust: false,
399 lldb_version: None,
400 llvm_version: None,
401 system_llvm: false,
402 android_cross_path: PathBuf::from("android-cross-path"),
403 adb_path: "adb-path".to_owned(),
404 adb_test_dir: "adb-test-dir/target".to_owned(),
405 adb_device_status: false,
406 lldb_python_dir: None,
407 verbose: false,
408 quiet: false,
409 color: ColorConfig::AutoColor,
410 remote_test_client: None,
411 cc: "cc".to_string(),
412 cxx: "cxx".to_string(),
413 cflags: "cflags".to_string(),
414 ar: "ar".to_string(),
415 linker: None,
416 llvm_components: "llvm-components".to_string(),
417 llvm_cxxflags: "llvm-cxxflags".to_string(),
418 nodejs: None,
419 }
420 }
421 }