about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2018-10-18 10:47:20 +0800
committerkennytm <kennytm@gmail.com>2018-10-18 12:54:49 +0800
commit43ac030d7e6848bf06298153471567525618f955 (patch)
tree8681feac3e5c0cde67647e38178fe100a123fc45
parentfd616f01705ddc580948279cb22f1f69b753acf4 (diff)
parentac66b04ccb04e264004189970c817eb3da208f4a (diff)
downloadrust-43ac030d7e6848bf06298153471567525618f955.tar.gz
rust-43ac030d7e6848bf06298153471567525618f955.zip
Rollup merge of #54964 - tromey:run-both-gdb-and-lldb-tests, r=nikomatsakis
Run both lldb and gdb tests

Currently lldb tests are run only on macOS, and gdb tests are only run
elsewhere.  This patch changes this to run tests depending on what is
available.

One test is changed, as it was previously marked as failing on macOS,
whereas really it is a generic failure with lldb.

Closes #54721
-rw-r--r--src/bootstrap/test.rs20
-rw-r--r--src/test/debuginfo/lexical-scope-with-macro.rs2
-rw-r--r--src/tools/compiletest/src/common.rs3
-rw-r--r--src/tools/compiletest/src/header.rs157
-rw-r--r--src/tools/compiletest/src/main.rs34
-rw-r--r--src/tools/compiletest/src/runtest.rs29
6 files changed, 183 insertions, 62 deletions
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 633c15b54b9..80c89b9ff38 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -812,8 +812,7 @@ default_test!(Incremental {
 
 default_test!(Debuginfo {
     path: "src/test/debuginfo",
-    // What this runs varies depending on the native platform being apple
-    mode: "debuginfo-XXX",
+    mode: "debuginfo",
     suite: "debuginfo"
 });
 
@@ -950,18 +949,11 @@ impl Step for Compiletest {
                 return;
             }
 
-            if mode == "debuginfo-XXX" {
-                return if builder.config.build.contains("apple") {
-                    builder.ensure(Compiletest {
-                        mode: "debuginfo-lldb",
-                        ..self
-                    });
-                } else {
-                    builder.ensure(Compiletest {
-                        mode: "debuginfo-gdb",
-                        ..self
-                    });
-                };
+            if mode == "debuginfo" {
+                return builder.ensure(Compiletest {
+                    mode: "debuginfo-both",
+                    ..self
+                });
             }
 
             builder.ensure(dist::DebuggerScripts {
diff --git a/src/test/debuginfo/lexical-scope-with-macro.rs b/src/test/debuginfo/lexical-scope-with-macro.rs
index 4e88f65ad1d..d11a42bb0ed 100644
--- a/src/test/debuginfo/lexical-scope-with-macro.rs
+++ b/src/test/debuginfo/lexical-scope-with-macro.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // min-lldb-version: 310
-// ignore-macos FIXME #48807
+// ignore-lldb FIXME #48807
 
 // compile-flags:-g -Zdebug-macros
 
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 7006fb9427e..fab2ea7ba6c 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -25,6 +25,7 @@ pub enum Mode {
     RunPass,
     RunPassValgrind,
     Pretty,
+    DebugInfoBoth,
     DebugInfoGdb,
     DebugInfoLldb,
     Codegen,
@@ -60,6 +61,7 @@ impl FromStr for Mode {
             "run-pass" => Ok(RunPass),
             "run-pass-valgrind" => Ok(RunPassValgrind),
             "pretty" => Ok(Pretty),
+            "debuginfo-both" => Ok(DebugInfoBoth),
             "debuginfo-lldb" => Ok(DebugInfoLldb),
             "debuginfo-gdb" => Ok(DebugInfoGdb),
             "codegen" => Ok(Codegen),
@@ -83,6 +85,7 @@ impl fmt::Display for Mode {
             RunPass => "run-pass",
             RunPassValgrind => "run-pass-valgrind",
             Pretty => "pretty",
+            DebugInfoBoth => "debuginfo-both",
             DebugInfoGdb => "debuginfo-gdb",
             DebugInfoLldb => "debuginfo-lldb",
             Codegen => "codegen",
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 688f2babe6e..06eeef61a19 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -19,10 +19,62 @@ use util;
 
 use extract_gdb_version;
 
+/// Whether to ignore the test.
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub enum Ignore {
+    /// Run it.
+    Run,
+    /// Ignore it totally.
+    Ignore,
+    /// Ignore only the gdb test, but run the lldb test.
+    IgnoreGdb,
+    /// Ignore only the lldb test, but run the gdb test.
+    IgnoreLldb,
+}
+
+impl Ignore {
+    pub fn can_run_gdb(&self) -> bool {
+        *self == Ignore::Run || *self == Ignore::IgnoreLldb
+    }
+
+    pub fn can_run_lldb(&self) -> bool {
+        *self == Ignore::Run || *self == Ignore::IgnoreGdb
+    }
+
+    pub fn no_gdb(&self) -> Ignore {
+        match *self {
+            Ignore::Run => Ignore::IgnoreGdb,
+            Ignore::IgnoreGdb => Ignore::IgnoreGdb,
+            _ => Ignore::Ignore,
+        }
+    }
+
+    pub fn no_lldb(&self) -> Ignore {
+        match *self {
+            Ignore::Run => Ignore::IgnoreLldb,
+            Ignore::IgnoreLldb => Ignore::IgnoreLldb,
+            _ => Ignore::Ignore,
+        }
+    }
+}
+
+/// The result of parse_cfg_name_directive.
+#[derive(Clone, Copy, PartialEq, Debug)]
+enum ParsedNameDirective {
+    /// No match.
+    NoMatch,
+    /// Match.
+    Match,
+    /// Mode was DebugInfoBoth and this matched gdb.
+    MatchGdb,
+    /// Mode was DebugInfoBoth and this matched lldb.
+    MatchLldb,
+}
+
 /// Properties which must be known very early, before actually running
 /// the test.
 pub struct EarlyProps {
-    pub ignore: bool,
+    pub ignore: Ignore,
     pub should_fail: bool,
     pub aux: Vec<String>,
     pub revisions: Vec<String>,
@@ -31,20 +83,55 @@ pub struct EarlyProps {
 impl EarlyProps {
     pub fn from_file(config: &Config, testfile: &Path) -> Self {
         let mut props = EarlyProps {
-            ignore: false,
+            ignore: Ignore::Run,
             should_fail: false,
             aux: Vec::new(),
             revisions: vec![],
         };
 
+        if config.mode == common::DebugInfoBoth {
+            if config.lldb_python_dir.is_none() {
+                props.ignore = props.ignore.no_lldb();
+            }
+            if config.gdb_version.is_none() {
+                props.ignore = props.ignore.no_gdb();
+            }
+        }
+
         iter_header(testfile, None, &mut |ln| {
             // we should check if any only-<platform> exists and if it exists
             // and does not matches the current platform, skip the test
-            props.ignore = props.ignore || config.parse_cfg_name_directive(ln, "ignore")
-                || (config.has_cfg_prefix(ln, "only")
-                    && !config.parse_cfg_name_directive(ln, "only"))
-                || ignore_gdb(config, ln) || ignore_lldb(config, ln)
-                || ignore_llvm(config, ln);
+            if props.ignore != Ignore::Ignore {
+                props.ignore = match config.parse_cfg_name_directive(ln, "ignore") {
+                    ParsedNameDirective::Match => Ignore::Ignore,
+                    ParsedNameDirective::NoMatch => props.ignore,
+                    ParsedNameDirective::MatchGdb => props.ignore.no_gdb(),
+                    ParsedNameDirective::MatchLldb => props.ignore.no_lldb(),
+                };
+
+                if config.has_cfg_prefix(ln, "only") {
+                    props.ignore = match config.parse_cfg_name_directive(ln, "only") {
+                        ParsedNameDirective::Match => props.ignore,
+                        ParsedNameDirective::NoMatch => Ignore::Ignore,
+                        ParsedNameDirective::MatchLldb => props.ignore.no_gdb(),
+                        ParsedNameDirective::MatchGdb => props.ignore.no_lldb(),
+                    };
+                }
+
+                if ignore_llvm(config, ln) {
+                    props.ignore = Ignore::Ignore;
+                }
+            }
+
+            if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoBoth) &&
+                props.ignore.can_run_gdb() && ignore_gdb(config, ln) {
+                props.ignore = props.ignore.no_gdb();
+            }
+
+            if (config.mode == common::DebugInfoLldb || config.mode == common::DebugInfoBoth) &&
+                props.ignore.can_run_lldb() && ignore_lldb(config, ln) {
+                props.ignore = props.ignore.no_lldb();
+            }
 
             if let Some(s) = config.parse_aux_build(ln) {
                 props.aux.push(s);
@@ -60,10 +147,6 @@ impl EarlyProps {
         return props;
 
         fn ignore_gdb(config: &Config, line: &str) -> bool {
-            if config.mode != common::DebugInfoGdb {
-                return false;
-            }
-
             if let Some(actual_version) = config.gdb_version {
                 if line.starts_with("min-gdb-version") {
                     let (start_ver, end_ver) = extract_gdb_version_range(line);
@@ -120,10 +203,6 @@ impl EarlyProps {
         }
 
         fn ignore_lldb(config: &Config, line: &str) -> bool {
-            if config.mode != common::DebugInfoLldb {
-                return false;
-            }
-
             if let Some(ref actual_version) = config.lldb_version {
                 if line.starts_with("min-lldb-version") {
                     let min_version = line.trim_right()
@@ -604,7 +683,7 @@ impl Config {
     }
 
     fn parse_custom_normalization(&self, mut line: &str, prefix: &str) -> Option<(String, String)> {
-        if self.parse_cfg_name_directive(line, prefix) {
+        if self.parse_cfg_name_directive(line, prefix) == ParsedNameDirective::Match {
             let from = match parse_normalization_string(&mut line) {
                 Some(s) => s,
                 None => return None,
@@ -620,35 +699,59 @@ impl Config {
     }
 
     /// Parses a name-value directive which contains config-specific information, e.g. `ignore-x86`
-    /// or `normalize-stderr-32bit`. Returns `true` if the line matches it.
-    fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> bool {
+    /// or `normalize-stderr-32bit`.
+    fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> ParsedNameDirective {
         if line.starts_with(prefix) && line.as_bytes().get(prefix.len()) == Some(&b'-') {
             let name = line[prefix.len() + 1..]
                 .split(&[':', ' '][..])
                 .next()
                 .unwrap();
 
-            name == "test" ||
+            if name == "test" ||
                 util::matches_os(&self.target, name) ||             // target
                 name == util::get_arch(&self.target) ||             // architecture
                 name == util::get_pointer_width(&self.target) ||    // pointer width
                 name == self.stage_id.split('-').next().unwrap() || // stage
                 Some(name) == util::get_env(&self.target) ||        // env
-                match self.mode {
-                    common::DebugInfoGdb => name == "gdb",
-                    common::DebugInfoLldb => name == "lldb",
-                    common::Pretty => name == "pretty",
-                    _ => false,
-                } ||
                 (self.target != self.host && name == "cross-compile") ||
                 match self.compare_mode {
                     Some(CompareMode::Nll) => name == "compare-mode-nll",
                     Some(CompareMode::Polonius) => name == "compare-mode-polonius",
                     None => false,
                 } ||
-                (cfg!(debug_assertions) && name == "debug")
+                (cfg!(debug_assertions) && name == "debug") {
+                ParsedNameDirective::Match
+            } else {
+                match self.mode {
+                    common::DebugInfoBoth => {
+                        if name == "gdb" {
+                            ParsedNameDirective::MatchGdb
+                        } else if name == "lldb" {
+                            ParsedNameDirective::MatchLldb
+                        } else {
+                            ParsedNameDirective::NoMatch
+                        }
+                    },
+                    common::DebugInfoGdb => if name == "gdb" {
+                        ParsedNameDirective::Match
+                    } else {
+                        ParsedNameDirective::NoMatch
+                    },
+                    common::DebugInfoLldb => if name == "lldb" {
+                        ParsedNameDirective::Match
+                    } else {
+                        ParsedNameDirective::NoMatch
+                    },
+                    common::Pretty => if name == "pretty" {
+                        ParsedNameDirective::Match
+                    } else {
+                        ParsedNameDirective::NoMatch
+                    },
+                    _ => ParsedNameDirective::NoMatch,
+                }
+            }
         } else {
-            false
+            ParsedNameDirective::NoMatch
         }
     }
 
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index f46e031d768..c931d3c0e30 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -32,7 +32,7 @@ extern crate rustfix;
 use common::CompareMode;
 use common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS};
 use common::{Config, TestPaths};
-use common::{DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
+use common::{DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
 use filetime::FileTime;
 use getopts::Options;
 use std::env;
@@ -44,7 +44,7 @@ use std::process::Command;
 use test::ColorConfig;
 use util::logv;
 
-use self::header::EarlyProps;
+use self::header::{EarlyProps, Ignore};
 
 pub mod common;
 pub mod errors;
@@ -425,7 +425,7 @@ pub fn opt_str2(maybestr: Option<String>) -> String {
 
 pub fn run_tests(config: &Config) {
     if config.target.contains("android") {
-        if let DebugInfoGdb = config.mode {
+        if config.mode == DebugInfoGdb || config.mode == DebugInfoBoth {
             println!(
                 "{} debug-info test uses tcp 5039 port.\
                  please reserve it",
@@ -443,7 +443,9 @@ pub fn run_tests(config: &Config) {
     }
 
     match config.mode {
-        DebugInfoLldb => {
+        // Note that we don't need to emit the gdb warning when
+        // DebugInfoBoth, so it is ok to list that here.
+        DebugInfoBoth | DebugInfoLldb => {
             if let Some(lldb_version) = config.lldb_version.as_ref() {
                 if is_blacklisted_lldb_version(&lldb_version[..]) {
                     println!(
@@ -647,15 +649,18 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> Vec<test::TestDescAn
         .into_iter()
         .map(|revision| {
             // Debugging emscripten code doesn't make sense today
-            let ignore = early_props.ignore
+            let ignore = early_props.ignore == Ignore::Ignore
                 || !up_to_date(
                     config,
                     testpaths,
                     &early_props,
                     revision.map(|s| s.as_str()),
                 )
-                || (config.mode == DebugInfoGdb || config.mode == DebugInfoLldb)
-                    && config.target.contains("emscripten");
+                || ((config.mode == DebugInfoBoth ||
+                     config.mode == DebugInfoGdb || config.mode == DebugInfoLldb)
+                    && config.target.contains("emscripten"))
+                || (config.mode == DebugInfoGdb && !early_props.ignore.can_run_gdb())
+                || (config.mode == DebugInfoLldb && !early_props.ignore.can_run_lldb());
             test::TestDescAndFn {
                 desc: test::TestDesc {
                     name: make_test_name(config, testpaths, revision),
@@ -663,7 +668,7 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> Vec<test::TestDescAn
                     should_panic,
                     allow_fail: false,
                 },
-                testfn: make_test_closure(config, testpaths, revision),
+                testfn: make_test_closure(config, early_props.ignore, testpaths, revision),
             }
         })
         .collect()
@@ -774,10 +779,21 @@ fn make_test_name(
 
 fn make_test_closure(
     config: &Config,
+    ignore: Ignore,
     testpaths: &TestPaths,
     revision: Option<&String>,
 ) -> test::TestFn {
-    let config = config.clone();
+    let mut config = config.clone();
+    if config.mode == DebugInfoBoth {
+        // If both gdb and lldb were ignored, then the test as a whole
+        // would be ignored.
+        if !ignore.can_run_gdb() {
+            config.mode = DebugInfoLldb;
+        } else if !ignore.can_run_lldb() {
+            config.mode = DebugInfoGdb;
+        }
+    }
+
     let testpaths = testpaths.clone();
     let revision = revision.cloned();
     test::DynTestFn(Box::new(move || {
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index c69956030c0..8c3b1bb4df3 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -11,7 +11,7 @@
 use common::CompareMode;
 use common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT};
 use common::{output_base_dir, output_base_name, output_testname_unique};
-use common::{Codegen, CodegenUnits, DebugInfoGdb, DebugInfoLldb, Rustdoc};
+use common::{Codegen, CodegenUnits, DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Rustdoc};
 use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
 use common::{Config, TestPaths};
 use common::{Incremental, MirOpt, RunMake, Ui};
@@ -225,19 +225,20 @@ pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
 pub fn compute_stamp_hash(config: &Config) -> String {
     let mut hash = DefaultHasher::new();
     config.stage_id.hash(&mut hash);
-    match config.mode {
-        DebugInfoGdb => match config.gdb {
+
+    if config.mode == DebugInfoGdb || config.mode == DebugInfoBoth {
+        match config.gdb {
             None => env::var_os("PATH").hash(&mut hash),
             Some(ref s) if s.is_empty() => env::var_os("PATH").hash(&mut hash),
             Some(ref s) => s.hash(&mut hash),
-        },
-        DebugInfoLldb => {
-            env::var_os("PATH").hash(&mut hash);
-            env::var_os("PYTHONPATH").hash(&mut hash);
-        },
+        };
+    }
+
+    if config.mode == DebugInfoLldb || config.mode == DebugInfoBoth {
+        env::var_os("PATH").hash(&mut hash);
+        env::var_os("PYTHONPATH").hash(&mut hash);
+    }
 
-        _ => {},
-    };
     format!("{:x}", hash.finish())
 }
 
@@ -268,6 +269,10 @@ impl<'test> TestCx<'test> {
             RunFail => self.run_rfail_test(),
             RunPassValgrind => self.run_valgrind_test(),
             Pretty => self.run_pretty_test(),
+            DebugInfoBoth => {
+                self.run_debuginfo_gdb_test();
+                self.run_debuginfo_lldb_test();
+            },
             DebugInfoGdb => self.run_debuginfo_gdb_test(),
             DebugInfoLldb => self.run_debuginfo_lldb_test(),
             Codegen => self.run_codegen_test(),
@@ -640,6 +645,7 @@ impl<'test> TestCx<'test> {
         let config = Config {
             target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
             host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
+            mode: DebugInfoGdb,
             ..self.config.clone()
         };
 
@@ -910,6 +916,7 @@ impl<'test> TestCx<'test> {
         let config = Config {
             target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
             host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
+            mode: DebugInfoLldb,
             ..self.config.clone()
         };
 
@@ -1774,7 +1781,7 @@ impl<'test> TestCx<'test> {
 
                 rustc.arg(dir_opt);
             }
-            RunFail | RunPassValgrind | Pretty | DebugInfoGdb | DebugInfoLldb
+            RunFail | RunPassValgrind | Pretty | DebugInfoBoth | DebugInfoGdb | DebugInfoLldb
             | Codegen | Rustdoc | RunMake | CodegenUnits => {
                 // do not use JSON output
             }