Skip to content

Commit e41e49e

Browse files
authored
Unrolled build for rust-lang#119034
Rollup merge of rust-lang#119034 - Zalathar:ignore-mode, r=davidtwco Allow coverage tests to ignore test modes, and to enable color in coverage reports This PR adds two new header directives to compiletest, intended for use by coverage tests (and by rust-lang#119033 in particular). The new headers are: - `// ignore-mode-{mode}` causes a test to not be run in a particular compiletest mode (e.g. `ignore-mode-coverage-run`). - This can theoretically be used by any test, but coverage tests are currently the only ones that automatically run in multiple modes, so it's not very useful for other kinds of test. - `// llvm-cov-flags: --use-color` makes `coverage-run` tests pass the flag `--use-color` when generating coverage reports. - For most tests, non-coloured reports are easier to read and more portable across platforms. But for rust-lang#119033 specifically, we want to test that `llvm-cov` slices up source text correctly, which only happens when colour output is enabled.
2 parents 432fffa + 731ba80 commit e41e49e

File tree

14 files changed

+132
-14
lines changed

14 files changed

+132
-14
lines changed

src/bootstrap/src/core/build_steps/test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1976,7 +1976,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
19761976
}
19771977

19781978
if builder.config.profiler_enabled(target) {
1979-
cmd.env("RUSTC_PROFILER_SUPPORT", "1");
1979+
cmd.arg("--profiler-support");
19801980
}
19811981

19821982
cmd.env("RUST_TEST_TMPDIR", builder.tempdir());

src/tools/compiletest/src/common.rs

+4
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,10 @@ pub struct Config {
387387
// Needed both to construct build_helper::git::GitConfig
388388
pub git_repository: String,
389389
pub nightly_branch: String,
390+
391+
/// True if the profiler runtime is enabled for this target.
392+
/// Used by the "needs-profiler-support" header in test files.
393+
pub profiler_support: bool,
390394
}
391395

392396
impl Config {

src/tools/compiletest/src/header.rs

+25-9
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ pub struct TestProps {
178178
// Whether to tell `rustc` to remap the "src base" directory to a fake
179179
// directory.
180180
pub remap_src_base: bool,
181+
/// Extra flags to pass to `llvm-cov` when producing coverage reports.
182+
/// Only used by the "coverage-run" test mode.
183+
pub llvm_cov_flags: Vec<String>,
181184
}
182185

183186
mod directives {
@@ -216,6 +219,7 @@ mod directives {
216219
pub const MIR_UNIT_TEST: &'static str = "unit-test";
217220
pub const REMAP_SRC_BASE: &'static str = "remap-src-base";
218221
pub const COMPARE_OUTPUT_LINES_BY_SUBSET: &'static str = "compare-output-lines-by-subset";
222+
pub const LLVM_COV_FLAGS: &'static str = "llvm-cov-flags";
219223
// This isn't a real directive, just one that is probably mistyped often
220224
pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags";
221225
}
@@ -265,6 +269,7 @@ impl TestProps {
265269
stderr_per_bitwidth: false,
266270
mir_unit_test: None,
267271
remap_src_base: false,
272+
llvm_cov_flags: vec![],
268273
}
269274
}
270275

@@ -321,16 +326,23 @@ impl TestProps {
321326
|r| r,
322327
);
323328

324-
if let Some(flags) = config.parse_name_value_directive(ln, COMPILE_FLAGS) {
325-
self.compile_flags.extend(
326-
flags
327-
.split("'")
328-
.enumerate()
329-
.flat_map(|(i, f)| {
329+
fn split_flags(flags: &str) -> Vec<String> {
330+
// Individual flags can be single-quoted to preserve spaces; see
331+
// <https://github.com/rust-lang/rust/pull/115948/commits/957c5db6>.
332+
flags
333+
.split("'")
334+
.enumerate()
335+
.flat_map(
336+
|(i, f)| {
330337
if i % 2 == 1 { vec![f] } else { f.split_whitespace().collect() }
331-
})
332-
.map(|s| s.to_owned()),
333-
);
338+
},
339+
)
340+
.map(move |s| s.to_owned())
341+
.collect::<Vec<_>>()
342+
}
343+
344+
if let Some(flags) = config.parse_name_value_directive(ln, COMPILE_FLAGS) {
345+
self.compile_flags.extend(split_flags(&flags));
334346
}
335347
if config.parse_name_value_directive(ln, INCORRECT_COMPILER_FLAGS).is_some() {
336348
panic!("`compiler-flags` directive should be spelled `compile-flags`");
@@ -488,6 +500,10 @@ impl TestProps {
488500
COMPARE_OUTPUT_LINES_BY_SUBSET,
489501
&mut self.compare_output_lines_by_subset,
490502
);
503+
504+
if let Some(flags) = config.parse_name_value_directive(ln, LLVM_COV_FLAGS) {
505+
self.llvm_cov_flags.extend(split_flags(&flags));
506+
}
491507
});
492508
}
493509

src/tools/compiletest/src/header/cfg.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::common::{CompareMode, Config, Debugger};
1+
use crate::common::{CompareMode, Config, Debugger, Mode};
22
use crate::header::IgnoreDecision;
33
use std::collections::HashSet;
44

@@ -208,6 +208,17 @@ pub(super) fn parse_cfg_name_directive<'a>(
208208
},
209209
message: "when comparing with {name}",
210210
}
211+
// Coverage tests run the same test file in multiple modes.
212+
// If a particular test should not be run in one of the modes, ignore it
213+
// with "ignore-mode-coverage-map" or "ignore-mode-coverage-run".
214+
condition! {
215+
name: format!("mode-{}", config.mode.to_str()),
216+
allowed_names: ContainsPrefixed {
217+
prefix: "mode-",
218+
inner: Mode::STR_VARIANTS,
219+
},
220+
message: "when the test mode is {name}",
221+
}
211222

212223
if prefix == "ignore" && outcome == MatchOutcome::Invalid {
213224
// Don't error out for ignore-tidy-* diretives, as those are not handled by compiletest.

src/tools/compiletest/src/header/needs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ impl CachedNeedsConditions {
238238
sanitizer_memtag: sanitizers.contains(&Sanitizer::Memtag),
239239
sanitizer_shadow_call_stack: sanitizers.contains(&Sanitizer::ShadowCallStack),
240240
sanitizer_safestack: sanitizers.contains(&Sanitizer::Safestack),
241-
profiler_support: std::env::var_os("RUSTC_PROFILER_SUPPORT").is_some(),
241+
profiler_support: config.profiler_support,
242242
xray: config.target_cfg().xray,
243243

244244
// For tests using the `needs-rust-lld` directive (e.g. for `-Clink-self-contained=+linker`),

src/tools/compiletest/src/header/tests.rs

+42-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::io::Read;
22
use std::path::Path;
3+
use std::str::FromStr;
34

4-
use crate::common::{Config, Debugger};
5+
use crate::common::{Config, Debugger, Mode};
56
use crate::header::{parse_normalization_string, EarlyProps, HeadersCache};
67

78
fn make_test_description<R: Read>(
@@ -55,16 +56,23 @@ fn test_parse_normalization_string() {
5556

5657
#[derive(Default)]
5758
struct ConfigBuilder {
59+
mode: Option<String>,
5860
channel: Option<String>,
5961
host: Option<String>,
6062
target: Option<String>,
6163
stage_id: Option<String>,
6264
llvm_version: Option<String>,
6365
git_hash: bool,
6466
system_llvm: bool,
67+
profiler_support: bool,
6568
}
6669

6770
impl ConfigBuilder {
71+
fn mode(&mut self, s: &str) -> &mut Self {
72+
self.mode = Some(s.to_owned());
73+
self
74+
}
75+
6876
fn channel(&mut self, s: &str) -> &mut Self {
6977
self.channel = Some(s.to_owned());
7078
self
@@ -100,10 +108,16 @@ impl ConfigBuilder {
100108
self
101109
}
102110

111+
fn profiler_support(&mut self, s: bool) -> &mut Self {
112+
self.profiler_support = s;
113+
self
114+
}
115+
103116
fn build(&mut self) -> Config {
104117
let args = &[
105118
"compiletest",
106-
"--mode=ui",
119+
"--mode",
120+
self.mode.as_deref().unwrap_or("ui"),
107121
"--suite=ui",
108122
"--compile-lib-path=",
109123
"--run-lib-path=",
@@ -142,6 +156,9 @@ impl ConfigBuilder {
142156
if self.system_llvm {
143157
args.push("--system-llvm".to_owned());
144158
}
159+
if self.profiler_support {
160+
args.push("--profiler-support".to_owned());
161+
}
145162

146163
args.push("--rustc-path".to_string());
147164
// This is a subtle/fragile thing. On rust-lang CI, there is no global
@@ -340,6 +357,15 @@ fn sanitizers() {
340357
assert!(check_ignore(&config, "// needs-sanitizer-thread"));
341358
}
342359

360+
#[test]
361+
fn profiler_support() {
362+
let config: Config = cfg().profiler_support(false).build();
363+
assert!(check_ignore(&config, "// needs-profiler-support"));
364+
365+
let config: Config = cfg().profiler_support(true).build();
366+
assert!(!check_ignore(&config, "// needs-profiler-support"));
367+
}
368+
343369
#[test]
344370
fn asm_support() {
345371
let asms = [
@@ -530,3 +556,17 @@ fn families() {
530556
assert!(!check_ignore(&config, &format!("// ignore-{other}")));
531557
}
532558
}
559+
560+
#[test]
561+
fn ignore_mode() {
562+
for &mode in Mode::STR_VARIANTS {
563+
// Indicate profiler support so that "coverage-run" tests aren't skipped.
564+
let config: Config = cfg().mode(mode).profiler_support(true).build();
565+
let other = if mode == "coverage-run" { "coverage-map" } else { "coverage-run" };
566+
assert_ne!(mode, other);
567+
assert_eq!(config.mode, Mode::from_str(mode).unwrap());
568+
assert_ne!(config.mode, Mode::from_str(other).unwrap());
569+
assert!(check_ignore(&config, &format!("// ignore-mode-{mode}")));
570+
assert!(!check_ignore(&config, &format!("// ignore-mode-{other}")));
571+
}
572+
}

src/tools/compiletest/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
142142
.optflag("", "force-rerun", "rerun tests even if the inputs are unchanged")
143143
.optflag("", "only-modified", "only run tests that result been modified")
144144
.optflag("", "nocapture", "")
145+
.optflag("", "profiler-support", "is the profiler runtime enabled for this target")
145146
.optflag("h", "help", "show this message")
146147
.reqopt("", "channel", "current Rust channel", "CHANNEL")
147148
.optflag("", "git-hash", "run tests which rely on commit version being compiled into the binaries")
@@ -315,6 +316,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
315316

316317
git_repository: matches.opt_str("git-repository").unwrap(),
317318
nightly_branch: matches.opt_str("nightly-branch").unwrap(),
319+
320+
profiler_support: matches.opt_present("profiler-support"),
318321
}
319322
}
320323

src/tools/compiletest/src/runtest.rs

+2
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,8 @@ impl<'test> TestCx<'test> {
575575
cmd.arg("--object");
576576
cmd.arg(bin);
577577
}
578+
579+
cmd.args(&self.props.llvm_cov_flags);
578580
});
579581
if !proc_res.status.success() {
580582
self.fatal_proc_rec("llvm-cov show failed!", &proc_res);

tests/coverage/color.coverage

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
LL| |// edition: 2021
2+
LL| |// ignore-mode-coverage-map
3+
LL| |// ignore-windows
4+
LL| |// llvm-cov-flags: --use-color
5+
LL| |
6+
LL| |// Verify that telling `llvm-cov` to use colored output actually works.
7+
LL| |// Ignored on Windows because we can't tell the tool to use ANSI escapes.
8+
LL| |
9+
LL| 1|fn main() {
10+
LL| 1| for _i in 0..0 {}
11+
^0 ^0
12+
LL| 1|}
13+

tests/coverage/color.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// edition: 2021
2+
// ignore-mode-coverage-map
3+
// ignore-windows
4+
// llvm-cov-flags: --use-color
5+
6+
// Verify that telling `llvm-cov` to use colored output actually works.
7+
// Ignored on Windows because we can't tell the tool to use ANSI escapes.
8+
9+
fn main() {
10+
for _i in 0..0 {}
11+
}

tests/coverage/ignore_map.coverage

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
LL| |// ignore-mode-coverage-map
2+
LL| |
3+
LL| 1|fn main() {}
4+

tests/coverage/ignore_map.rs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// ignore-mode-coverage-map
2+
3+
fn main() {}

tests/coverage/ignore_run.cov-map

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Function name: ignore_run::main
2+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 03, 01, 00, 0d]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 13)
8+

tests/coverage/ignore_run.rs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// ignore-mode-coverage-run
2+
3+
fn main() {}

0 commit comments

Comments
 (0)