about summary refs log tree commit diff
path: root/src/tools
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-01-28 16:25:35 +0000
committerbors <bors@rust-lang.org>2020-01-28 16:25:35 +0000
commitac2f3fa41ac5ae8425b959f955bb7433b7c57aea (patch)
tree4f273098c9783e2e3d9b92592131074cb78eb518 /src/tools
parentb181835a6bacfa449f55d46764a10e25d1c471dc (diff)
parent3c02afe965a2dcfecd42e27bb225f9d2af68e838 (diff)
downloadrust-ac2f3fa41ac5ae8425b959f955bb7433b7c57aea.tar.gz
rust-ac2f3fa41ac5ae8425b959f955bb7433b7c57aea.zip
Auto merge of #68533 - tmiasko:compiletest, r=nikomatsakis
compiletest: Unit tests for `EarlyProps` (+ small cleanup)

* Parse `EarlyProps` from a reader
* Add unit tests for `EarlyProps`
* Remove unused `llvm-cxxflags` option
* Remove unnecessary memory allocations in `iter_header`
* Update mode list displayed in `--help`
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/compiletest/src/common.rs1
-rw-r--r--src/tools/compiletest/src/header.rs236
-rw-r--r--src/tools/compiletest/src/header/tests.rs155
-rw-r--r--src/tools/compiletest/src/main.rs5
-rw-r--r--src/tools/compiletest/src/runtest.rs1
5 files changed, 279 insertions, 119 deletions
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 9cc19060cbd..64c0298c1fa 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -319,7 +319,6 @@ pub struct Config {
     pub ar: String,
     pub linker: Option<String>,
     pub llvm_components: String,
-    pub llvm_cxxflags: String,
 
     /// Path to a NodeJS executable. Used for JS doctests, emscripten and WASM tests
     pub nodejs: Option<String>,
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 34f9ac037b4..817705c0bd6 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -24,6 +24,7 @@ enum ParsedNameDirective {
 
 /// Properties which must be known very early, before actually running
 /// the test.
+#[derive(Default)]
 pub struct EarlyProps {
     pub ignore: bool,
     pub should_fail: bool,
@@ -34,18 +35,16 @@ pub struct EarlyProps {
 
 impl EarlyProps {
     pub fn from_file(config: &Config, testfile: &Path) -> Self {
-        let mut props = EarlyProps {
-            ignore: false,
-            should_fail: false,
-            aux: Vec::new(),
-            aux_crate: Vec::new(),
-            revisions: vec![],
-        };
+        let file = File::open(testfile).unwrap();
+        Self::from_reader(config, testfile, file)
+    }
 
+    pub fn from_reader<R: Read>(config: &Config, testfile: &Path, rdr: R) -> Self {
+        let mut props = EarlyProps::default();
         let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some();
         let rustc_has_sanitizer_support = env::var_os("RUSTC_SANITIZER_SUPPORT").is_some();
 
-        iter_header(testfile, None, &mut |ln| {
+        iter_header(testfile, None, rdr, &mut |ln| {
             // we should check if any only-<platform> exists and if it exists
             // and does not matches the current platform, skip the test
             if !props.ignore {
@@ -392,138 +391,143 @@ impl TestProps {
     /// `//[foo]`), then the property is ignored unless `cfg` is
     /// `Some("foo")`.
     fn load_from(&mut self, testfile: &Path, cfg: Option<&str>, config: &Config) {
-        iter_header(testfile, cfg, &mut |ln| {
-            if let Some(ep) = config.parse_error_pattern(ln) {
-                self.error_patterns.push(ep);
-            }
+        if !testfile.is_dir() {
+            let file = File::open(testfile).unwrap();
 
-            if let Some(flags) = config.parse_compile_flags(ln) {
-                self.compile_flags.extend(flags.split_whitespace().map(|s| s.to_owned()));
-            }
+            iter_header(testfile, cfg, file, &mut |ln| {
+                if let Some(ep) = config.parse_error_pattern(ln) {
+                    self.error_patterns.push(ep);
+                }
 
-            if let Some(edition) = config.parse_edition(ln) {
-                self.compile_flags.push(format!("--edition={}", edition));
-            }
+                if let Some(flags) = config.parse_compile_flags(ln) {
+                    self.compile_flags.extend(flags.split_whitespace().map(|s| s.to_owned()));
+                }
 
-            if let Some(r) = config.parse_revisions(ln) {
-                self.revisions.extend(r);
-            }
+                if let Some(edition) = config.parse_edition(ln) {
+                    self.compile_flags.push(format!("--edition={}", edition));
+                }
 
-            if self.run_flags.is_none() {
-                self.run_flags = config.parse_run_flags(ln);
-            }
+                if let Some(r) = config.parse_revisions(ln) {
+                    self.revisions.extend(r);
+                }
 
-            if self.pp_exact.is_none() {
-                self.pp_exact = config.parse_pp_exact(ln, testfile);
-            }
+                if self.run_flags.is_none() {
+                    self.run_flags = config.parse_run_flags(ln);
+                }
 
-            if !self.should_ice {
-                self.should_ice = config.parse_should_ice(ln);
-            }
+                if self.pp_exact.is_none() {
+                    self.pp_exact = config.parse_pp_exact(ln, testfile);
+                }
 
-            if !self.build_aux_docs {
-                self.build_aux_docs = config.parse_build_aux_docs(ln);
-            }
+                if !self.should_ice {
+                    self.should_ice = config.parse_should_ice(ln);
+                }
 
-            if !self.force_host {
-                self.force_host = config.parse_force_host(ln);
-            }
+                if !self.build_aux_docs {
+                    self.build_aux_docs = config.parse_build_aux_docs(ln);
+                }
 
-            if !self.check_stdout {
-                self.check_stdout = config.parse_check_stdout(ln);
-            }
+                if !self.force_host {
+                    self.force_host = config.parse_force_host(ln);
+                }
 
-            if !self.check_run_results {
-                self.check_run_results = config.parse_check_run_results(ln);
-            }
+                if !self.check_stdout {
+                    self.check_stdout = config.parse_check_stdout(ln);
+                }
 
-            if !self.dont_check_compiler_stdout {
-                self.dont_check_compiler_stdout = config.parse_dont_check_compiler_stdout(ln);
-            }
+                if !self.check_run_results {
+                    self.check_run_results = config.parse_check_run_results(ln);
+                }
 
-            if !self.dont_check_compiler_stderr {
-                self.dont_check_compiler_stderr = config.parse_dont_check_compiler_stderr(ln);
-            }
+                if !self.dont_check_compiler_stdout {
+                    self.dont_check_compiler_stdout = config.parse_dont_check_compiler_stdout(ln);
+                }
 
-            if !self.no_prefer_dynamic {
-                self.no_prefer_dynamic = config.parse_no_prefer_dynamic(ln);
-            }
+                if !self.dont_check_compiler_stderr {
+                    self.dont_check_compiler_stderr = config.parse_dont_check_compiler_stderr(ln);
+                }
 
-            if !self.pretty_expanded {
-                self.pretty_expanded = config.parse_pretty_expanded(ln);
-            }
+                if !self.no_prefer_dynamic {
+                    self.no_prefer_dynamic = config.parse_no_prefer_dynamic(ln);
+                }
 
-            if let Some(m) = config.parse_pretty_mode(ln) {
-                self.pretty_mode = m;
-            }
+                if !self.pretty_expanded {
+                    self.pretty_expanded = config.parse_pretty_expanded(ln);
+                }
 
-            if !self.pretty_compare_only {
-                self.pretty_compare_only = config.parse_pretty_compare_only(ln);
-            }
+                if let Some(m) = config.parse_pretty_mode(ln) {
+                    self.pretty_mode = m;
+                }
 
-            if let Some(ab) = config.parse_aux_build(ln) {
-                self.aux_builds.push(ab);
-            }
+                if !self.pretty_compare_only {
+                    self.pretty_compare_only = config.parse_pretty_compare_only(ln);
+                }
 
-            if let Some(ac) = config.parse_aux_crate(ln) {
-                self.aux_crates.push(ac);
-            }
+                if let Some(ab) = config.parse_aux_build(ln) {
+                    self.aux_builds.push(ab);
+                }
 
-            if let Some(ee) = config.parse_env(ln, "exec-env") {
-                self.exec_env.push(ee);
-            }
+                if let Some(ac) = config.parse_aux_crate(ln) {
+                    self.aux_crates.push(ac);
+                }
 
-            if let Some(ee) = config.parse_env(ln, "rustc-env") {
-                self.rustc_env.push(ee);
-            }
+                if let Some(ee) = config.parse_env(ln, "exec-env") {
+                    self.exec_env.push(ee);
+                }
 
-            if let Some(ev) = config.parse_name_value_directive(ln, "unset-rustc-env") {
-                self.unset_rustc_env.push(ev);
-            }
+                if let Some(ee) = config.parse_env(ln, "rustc-env") {
+                    self.rustc_env.push(ee);
+                }
 
-            if let Some(cl) = config.parse_check_line(ln) {
-                self.check_lines.push(cl);
-            }
+                if let Some(ev) = config.parse_name_value_directive(ln, "unset-rustc-env") {
+                    self.unset_rustc_env.push(ev);
+                }
 
-            if let Some(of) = config.parse_forbid_output(ln) {
-                self.forbid_output.push(of);
-            }
+                if let Some(cl) = config.parse_check_line(ln) {
+                    self.check_lines.push(cl);
+                }
 
-            if !self.check_test_line_numbers_match {
-                self.check_test_line_numbers_match = config.parse_check_test_line_numbers_match(ln);
-            }
+                if let Some(of) = config.parse_forbid_output(ln) {
+                    self.forbid_output.push(of);
+                }
 
-            self.update_pass_mode(ln, cfg, config);
-            self.update_fail_mode(ln, config);
+                if !self.check_test_line_numbers_match {
+                    self.check_test_line_numbers_match =
+                        config.parse_check_test_line_numbers_match(ln);
+                }
 
-            if !self.ignore_pass {
-                self.ignore_pass = config.parse_ignore_pass(ln);
-            }
+                self.update_pass_mode(ln, cfg, config);
+                self.update_fail_mode(ln, config);
 
-            if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stdout") {
-                self.normalize_stdout.push(rule);
-            }
-            if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stderr") {
-                self.normalize_stderr.push(rule);
-            }
+                if !self.ignore_pass {
+                    self.ignore_pass = config.parse_ignore_pass(ln);
+                }
 
-            if let Some(code) = config.parse_failure_status(ln) {
-                self.failure_status = code;
-            }
+                if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stdout") {
+                    self.normalize_stdout.push(rule);
+                }
+                if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stderr") {
+                    self.normalize_stderr.push(rule);
+                }
 
-            if !self.run_rustfix {
-                self.run_rustfix = config.parse_run_rustfix(ln);
-            }
+                if let Some(code) = config.parse_failure_status(ln) {
+                    self.failure_status = code;
+                }
 
-            if !self.rustfix_only_machine_applicable {
-                self.rustfix_only_machine_applicable =
-                    config.parse_rustfix_only_machine_applicable(ln);
-            }
+                if !self.run_rustfix {
+                    self.run_rustfix = config.parse_run_rustfix(ln);
+                }
 
-            if self.assembly_output.is_none() {
-                self.assembly_output = config.parse_assembly_output(ln);
-            }
-        });
+                if !self.rustfix_only_machine_applicable {
+                    self.rustfix_only_machine_applicable =
+                        config.parse_rustfix_only_machine_applicable(ln);
+                }
+
+                if self.assembly_output.is_none() {
+                    self.assembly_output = config.parse_assembly_output(ln);
+                }
+            });
+        }
 
         if self.failure_status == -1 {
             self.failure_status = match config.mode {
@@ -617,7 +621,7 @@ impl TestProps {
     }
 }
 
-fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
+fn iter_header<R: Read>(testfile: &Path, cfg: Option<&str>, rdr: R, it: &mut dyn FnMut(&str)) {
     if testfile.is_dir() {
         return;
     }
@@ -628,12 +632,18 @@ fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
     // It took me like 2 days to debug why compile-flags weren’t taken into account for my test :)
     let comment_with_brace = comment.to_string() + "[";
 
-    let rdr = BufReader::new(File::open(testfile).unwrap());
-    for ln in rdr.lines() {
+    let mut rdr = BufReader::new(rdr);
+    let mut ln = String::new();
+
+    loop {
+        ln.clear();
+        if rdr.read_line(&mut ln).unwrap() == 0 {
+            break;
+        }
+
         // Assume that any directives will be found before the first
         // module or function. This doesn't seem to be an optimization
         // with a warm page cache. Maybe with a cold one.
-        let ln = ln.unwrap();
         let ln = ln.trim();
         if ln.starts_with("fn") || ln.starts_with("mod") {
             return;
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index 2a1831d5ee8..38fa778219d 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -1,4 +1,7 @@
-use super::*;
+use std::path::Path;
+
+use crate::common::{Config, Debugger};
+use crate::header::{parse_normalization_string, EarlyProps};
 
 #[test]
 fn test_parse_normalization_string() {
@@ -25,3 +28,153 @@ fn test_parse_normalization_string() {
     assert_eq!(first, Some("something (32 bits)".to_owned()));
     assert_eq!(s, " -> \"something ($WORD bits).");
 }
+
+fn config() -> Config {
+    let args = &[
+        "compiletest",
+        "--mode=ui",
+        "--compile-lib-path=",
+        "--run-lib-path=",
+        "--rustc-path=",
+        "--lldb-python=",
+        "--docck-python=",
+        "--src-base=",
+        "--build-base=",
+        "--stage-id=stage2",
+        "--cc=c",
+        "--cxx=c++",
+        "--cflags=",
+        "--llvm-components=",
+        "--android-cross-path=",
+        "--target=x86_64-unknown-linux-gnu",
+    ];
+    let args = args.iter().map(ToString::to_string).collect();
+    crate::parse_config(args)
+}
+
+fn parse_rs(config: &Config, contents: &str) -> EarlyProps {
+    let bytes = contents.as_bytes();
+    EarlyProps::from_reader(config, Path::new("a.rs"), bytes)
+}
+
+fn parse_makefile(config: &Config, contents: &str) -> EarlyProps {
+    let bytes = contents.as_bytes();
+    EarlyProps::from_reader(config, Path::new("Makefile"), bytes)
+}
+
+#[test]
+fn should_fail() {
+    let config = config();
+
+    assert!(!parse_rs(&config, "").should_fail);
+    assert!(parse_rs(&config, "// should-fail").should_fail);
+}
+
+#[test]
+fn revisions() {
+    let config = config();
+
+    assert_eq!(parse_rs(&config, "// revisions: a b c").revisions, vec!["a", "b", "c"],);
+    assert_eq!(
+        parse_makefile(&config, "# revisions: hello there").revisions,
+        vec!["hello", "there"],
+    );
+}
+
+#[test]
+fn aux_build() {
+    let config = config();
+
+    assert_eq!(
+        parse_rs(
+            &config,
+            r"
+        // aux-build: a.rs
+        // aux-build: b.rs
+        "
+        )
+        .aux,
+        vec!["a.rs", "b.rs"],
+    );
+}
+
+#[test]
+fn no_system_llvm() {
+    let mut config = config();
+
+    config.system_llvm = false;
+    assert!(!parse_rs(&config, "// no-system-llvm").ignore);
+
+    config.system_llvm = true;
+    assert!(parse_rs(&config, "// no-system-llvm").ignore);
+}
+
+#[test]
+fn ignore_target() {
+    let mut config = config();
+    config.target = "x86_64-unknown-linux-gnu".to_owned();
+
+    assert!(parse_rs(&config, "// ignore-x86_64-unknown-linux-gnu").ignore);
+    assert!(parse_rs(&config, "// ignore-x86_64").ignore);
+    assert!(parse_rs(&config, "// ignore-linux").ignore);
+    assert!(parse_rs(&config, "// ignore-gnu").ignore);
+    assert!(parse_rs(&config, "// ignore-64bit").ignore);
+
+    assert!(!parse_rs(&config, "// ignore-i686").ignore);
+    assert!(!parse_rs(&config, "// ignore-windows").ignore);
+    assert!(!parse_rs(&config, "// ignore-msvc").ignore);
+    assert!(!parse_rs(&config, "// ignore-32bit").ignore);
+}
+
+#[test]
+fn only_target() {
+    let mut config = config();
+    config.target = "x86_64-pc-windows-gnu".to_owned();
+
+    assert!(parse_rs(&config, "// only-i686").ignore);
+    assert!(parse_rs(&config, "// only-linux").ignore);
+    assert!(parse_rs(&config, "// only-msvc").ignore);
+    assert!(parse_rs(&config, "// only-32bit").ignore);
+
+    assert!(!parse_rs(&config, "// only-x86_64-pc-windows-gnu").ignore);
+    assert!(!parse_rs(&config, "// only-x86_64").ignore);
+    assert!(!parse_rs(&config, "// only-windows").ignore);
+    assert!(!parse_rs(&config, "// only-gnu").ignore);
+    assert!(!parse_rs(&config, "// only-64bit").ignore);
+}
+
+#[test]
+fn stage() {
+    let mut config = config();
+    config.stage_id = "stage1".to_owned();
+
+    assert!(parse_rs(&config, "// ignore-stage1").ignore);
+    assert!(!parse_rs(&config, "// ignore-stage2").ignore);
+}
+
+#[test]
+fn cross_compile() {
+    let mut config = config();
+    config.host = "x86_64-apple-darwin".to_owned();
+    config.target = "wasm32-unknown-unknown".to_owned();
+    assert!(parse_rs(&config, "// ignore-cross-compile").ignore);
+
+    config.target = config.host.clone();
+    assert!(!parse_rs(&config, "// ignore-cross-compile").ignore);
+}
+
+#[test]
+fn debugger() {
+    let mut config = config();
+    config.debugger = None;
+    assert!(!parse_rs(&config, "// ignore-cdb").ignore);
+
+    config.debugger = Some(Debugger::Cdb);
+    assert!(parse_rs(&config, "// ignore-cdb").ignore);
+
+    config.debugger = Some(Debugger::Gdb);
+    assert!(parse_rs(&config, "// ignore-gdb").ignore);
+
+    config.debugger = Some(Debugger::Lldb);
+    assert!(parse_rs(&config, "// ignore-lldb").ignore);
+}
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 5f8aa01f4fc..a61b9403987 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -70,7 +70,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
             "",
             "mode",
             "which sort of compile tests to run",
-            "(compile-fail|run-fail|run-pass-valgrind|pretty|debug-info|incremental|mir-opt)",
+            "compile-fail | run-fail | run-pass-valgrind | pretty | debug-info | codegen | rustdoc \
+             codegen-units | incremental | run-make | ui | js-doc-test | mir-opt | assembly",
         )
         .optopt(
             "",
@@ -115,7 +116,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
         .optopt("", "ar", "path to an archiver", "PATH")
         .optopt("", "linker", "path to a linker", "PATH")
         .reqopt("", "llvm-components", "list of LLVM components built in", "LIST")
-        .reqopt("", "llvm-cxxflags", "C++ flags for LLVM", "FLAGS")
         .optopt("", "llvm-bin-dir", "Path to LLVM's `bin` directory", "PATH")
         .optopt("", "nodejs", "the name of nodejs", "PATH")
         .optopt("", "remote-test-client", "path to the remote test client", "PATH")
@@ -239,7 +239,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
         ar: matches.opt_str("ar").unwrap_or("ar".into()),
         linker: matches.opt_str("linker"),
         llvm_components: matches.opt_str("llvm-components").unwrap(),
-        llvm_cxxflags: matches.opt_str("llvm-cxxflags").unwrap(),
         nodejs: matches.opt_str("nodejs"),
     }
 }
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index be66c9ab2db..1c5bda252cd 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2651,7 +2651,6 @@ impl<'test> TestCx<'test> {
             .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path))
             .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path))
             .env("LLVM_COMPONENTS", &self.config.llvm_components)
-            .env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags)
             // We for sure don't want these tests to run in parallel, so make
             // sure they don't have access to these vars if we run via `make`
             // at the top level