Skip to content

Commit 3141177

Browse files
committed
Copy most of tests/run-coverage into tests/coverage-map/status-quo
The output of these tests is too complicated to comfortably verify by hand, but we can still use them to observe changes to the underlying mappings produced by codegen/LLVM. If these tests fail due to non-coverage changes (e.g. in HIR-to-MIR lowering or MIR optimizations), it should usually be OK to just `--bless` them, as long as the `run-coverage` test suite still works.
1 parent 004db47 commit 3141177

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+5527
-0
lines changed

tests/coverage-map/README.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
The tests in `./status-quo` were copied from `tests/run-coverage` in order to
2+
capture the current behavior of the instrumentor on non-trivial programs.
3+
The actual mappings have not been closely inspected.
4+
5+
## Maintenance note
6+
7+
These tests can be sensitive to small changes in MIR spans or MIR control flow,
8+
especially in HIR-to-MIR lowering or MIR optimizations.
9+
10+
If you haven't touched the coverage code directly, and the `run-coverage` test
11+
suite still works, then it should usually be OK to just `--bless` these
12+
coverage mapping tests as necessary, without worrying too much about the exact
13+
changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
Function name: abort::main
2+
Raw bytes (105): 0x[01, 01, 12, 01, 47, 05, 09, 03, 0d, 42, 11, 03, 0d, 11, 3e, 42, 11, 03, 0d, 3b, 15, 11, 3e, 42, 11, 03, 0d, 15, 36, 3b, 15, 11, 3e, 42, 11, 03, 0d, 05, 09, 0d, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 42, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 3e, 02, 0a, 00, 0b, 3b, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 36, 00, 31, 00, 32, 33, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 31, 00, 32, 47, 01, 09, 00, 17, 0d, 02, 05, 01, 02]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 18
6+
- expression 0 operands: lhs = Counter(0), rhs = Expression(17, Add)
7+
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
8+
- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
9+
- expression 3 operands: lhs = Expression(16, Sub), rhs = Counter(4)
10+
- expression 4 operands: lhs = Expression(0, Add), rhs = Counter(3)
11+
- expression 5 operands: lhs = Counter(4), rhs = Expression(15, Sub)
12+
- expression 6 operands: lhs = Expression(16, Sub), rhs = Counter(4)
13+
- expression 7 operands: lhs = Expression(0, Add), rhs = Counter(3)
14+
- expression 8 operands: lhs = Expression(14, Add), rhs = Counter(5)
15+
- expression 9 operands: lhs = Counter(4), rhs = Expression(15, Sub)
16+
- expression 10 operands: lhs = Expression(16, Sub), rhs = Counter(4)
17+
- expression 11 operands: lhs = Expression(0, Add), rhs = Counter(3)
18+
- expression 12 operands: lhs = Counter(5), rhs = Expression(13, Sub)
19+
- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(5)
20+
- expression 14 operands: lhs = Counter(4), rhs = Expression(15, Sub)
21+
- expression 15 operands: lhs = Expression(16, Sub), rhs = Counter(4)
22+
- expression 16 operands: lhs = Expression(0, Add), rhs = Counter(3)
23+
- expression 17 operands: lhs = Counter(1), rhs = Counter(2)
24+
Number of file 0 mappings: 13
25+
- Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27)
26+
- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24)
27+
= (c0 + (c1 + c2))
28+
- Code(Expression(16, Sub)) at (prev + 1, 12) to (start + 0, 25)
29+
= ((c0 + (c1 + c2)) - c3)
30+
- Code(Counter(4)) at (prev + 0, 26) to (start + 2, 10)
31+
- Code(Expression(15, Sub)) at (prev + 2, 10) to (start + 0, 11)
32+
= (((c0 + (c1 + c2)) - c3) - c4)
33+
- Code(Expression(14, Add)) at (prev + 2, 12) to (start + 0, 25)
34+
= (c4 + (((c0 + (c1 + c2)) - c3) - c4))
35+
- Code(Counter(5)) at (prev + 0, 26) to (start + 0, 49)
36+
- Code(Expression(13, Sub)) at (prev + 0, 49) to (start + 0, 50)
37+
= ((c4 + (((c0 + (c1 + c2)) - c3) - c4)) - c5)
38+
- Code(Expression(12, Add)) at (prev + 4, 12) to (start + 0, 25)
39+
= (c5 + ((c4 + (((c0 + (c1 + c2)) - c3) - c4)) - c5))
40+
- Code(Counter(1)) at (prev + 0, 26) to (start + 0, 49)
41+
- Code(Counter(2)) at (prev + 0, 49) to (start + 0, 50)
42+
- Code(Expression(17, Add)) at (prev + 1, 9) to (start + 0, 23)
43+
= (c1 + c2)
44+
- Code(Counter(3)) at (prev + 2, 5) to (start + 1, 2)
45+
46+
Function name: abort::might_abort
47+
Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 01, 14, 05, 02, 09, 01, 24, 02, 02, 0c, 03, 02]
48+
Number of files: 1
49+
- file 0 => global file 1
50+
Number of expressions: 1
51+
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
52+
Number of file 0 mappings: 3
53+
- Code(Counter(0)) at (prev + 4, 1) to (start + 1, 20)
54+
- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 36)
55+
- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 3, 2)
56+
= (c0 - c1)
57+
+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#![feature(c_unwind)]
2+
#![allow(unused_assignments)]
3+
4+
extern "C" fn might_abort(should_abort: bool) {
5+
if should_abort {
6+
println!("aborting...");
7+
panic!("panics and aborts");
8+
} else {
9+
println!("Don't Panic");
10+
}
11+
}
12+
13+
fn main() -> Result<(), u8> {
14+
let mut countdown = 10;
15+
while countdown > 0 {
16+
if countdown < 5 {
17+
might_abort(false);
18+
}
19+
// See discussion (below the `Notes` section) on coverage results for the closing brace.
20+
if countdown < 5 { might_abort(false); } // Counts for different regions on one line.
21+
// For the following example, the closing brace is the last character on the line.
22+
// This shows the character after the closing brace is highlighted, even if that next
23+
// character is a newline.
24+
if countdown < 5 { might_abort(false); }
25+
countdown -= 1;
26+
}
27+
Ok(())
28+
}
29+
30+
// Notes:
31+
// 1. Compare this program and its coverage results to those of the similar tests
32+
// `panic_unwind.rs` and `try_error_result.rs`.
33+
// 2. This test confirms the coverage generated when a program includes `UnwindAction::Terminate`.
34+
// 3. The test does not invoke the abort. By executing to a successful completion, the coverage
35+
// results show where the program did and did not execute.
36+
// 4. If the program actually aborted, the coverage counters would not be saved (which "works as
37+
// intended"). Coverage results would show no executed coverage regions.
38+
// 6. If `should_abort` is `true` and the program aborts, the program exits with a `132` status
39+
// (on Linux at least).
40+
41+
/*
42+
43+
Expect the following coverage results:
44+
45+
```text
46+
16| 11| while countdown > 0 {
47+
17| 10| if countdown < 5 {
48+
18| 4| might_abort(false);
49+
19| 6| }
50+
```
51+
52+
This is actually correct.
53+
54+
The condition `countdown < 5` executed 10 times (10 loop iterations).
55+
56+
It evaluated to `true` 4 times, and executed the `might_abort()` call.
57+
58+
It skipped the body of the `might_abort()` call 6 times. If an `if` does not include an explicit
59+
`else`, the coverage implementation injects a counter, at the character immediately after the `if`s
60+
closing brace, to count the "implicit" `else`. This is the only way to capture the coverage of the
61+
non-true condition.
62+
63+
As another example of why this is important, say the condition was `countdown < 50`, which is always
64+
`true`. In that case, we wouldn't have a test for what happens if `might_abort()` is not called.
65+
The closing brace would have a count of `0`, highlighting the missed coverage.
66+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
Function name: assert::main
2+
Raw bytes (65): 0x[01, 01, 08, 01, 1b, 05, 1f, 09, 0d, 03, 11, 16, 05, 03, 11, 05, 1f, 09, 0d, 09, 01, 09, 01, 01, 1b, 03, 02, 0b, 00, 18, 16, 01, 0c, 00, 1a, 05, 00, 1b, 02, 0a, 12, 02, 13, 00, 20, 09, 00, 21, 02, 0a, 0d, 02, 0a, 00, 0b, 1b, 01, 09, 00, 17, 11, 02, 05, 01, 02]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 8
6+
- expression 0 operands: lhs = Counter(0), rhs = Expression(6, Add)
7+
- expression 1 operands: lhs = Counter(1), rhs = Expression(7, Add)
8+
- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
9+
- expression 3 operands: lhs = Expression(0, Add), rhs = Counter(4)
10+
- expression 4 operands: lhs = Expression(5, Sub), rhs = Counter(1)
11+
- expression 5 operands: lhs = Expression(0, Add), rhs = Counter(4)
12+
- expression 6 operands: lhs = Counter(1), rhs = Expression(7, Add)
13+
- expression 7 operands: lhs = Counter(2), rhs = Counter(3)
14+
Number of file 0 mappings: 9
15+
- Code(Counter(0)) at (prev + 9, 1) to (start + 1, 27)
16+
- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24)
17+
= (c0 + (c1 + (c2 + c3)))
18+
- Code(Expression(5, Sub)) at (prev + 1, 12) to (start + 0, 26)
19+
= ((c0 + (c1 + (c2 + c3))) - c4)
20+
- Code(Counter(1)) at (prev + 0, 27) to (start + 2, 10)
21+
- Code(Expression(4, Sub)) at (prev + 2, 19) to (start + 0, 32)
22+
= (((c0 + (c1 + (c2 + c3))) - c4) - c1)
23+
- Code(Counter(2)) at (prev + 0, 33) to (start + 2, 10)
24+
- Code(Counter(3)) at (prev + 2, 10) to (start + 0, 11)
25+
- Code(Expression(6, Add)) at (prev + 1, 9) to (start + 0, 23)
26+
= (c1 + (c2 + c3))
27+
- Code(Counter(4)) at (prev + 2, 5) to (start + 1, 2)
28+
29+
Function name: assert::might_fail_assert
30+
Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 02, 0f, 02, 02, 25, 00, 3d, 05, 01, 01, 00, 02]
31+
Number of files: 1
32+
- file 0 => global file 1
33+
Number of expressions: 1
34+
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
35+
Number of file 0 mappings: 3
36+
- Code(Counter(0)) at (prev + 4, 1) to (start + 2, 15)
37+
- Code(Expression(0, Sub)) at (prev + 2, 37) to (start + 0, 61)
38+
= (c0 - c1)
39+
- Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
40+
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#![allow(unused_assignments)]
2+
// failure-status: 101
3+
4+
fn might_fail_assert(one_plus_one: u32) {
5+
println!("does 1 + 1 = {}?", one_plus_one);
6+
assert_eq!(1 + 1, one_plus_one, "the argument was wrong");
7+
}
8+
9+
fn main() -> Result<(), u8> {
10+
let mut countdown = 10;
11+
while countdown > 0 {
12+
if countdown == 1 {
13+
might_fail_assert(3);
14+
} else if countdown < 5 {
15+
might_fail_assert(2);
16+
}
17+
countdown -= 1;
18+
}
19+
Ok(())
20+
}
21+
22+
// Notes:
23+
// 1. Compare this program and its coverage results to those of the very similar test
24+
// `panic_unwind.rs`, and similar tests `abort.rs` and `try_error_result.rs`.
25+
// 2. This test confirms the coverage generated when a program passes or fails an `assert!()` or
26+
// related `assert_*!()` macro.
27+
// 3. Notably, the `assert` macros *do not* generate `TerminatorKind::Assert`. The macros produce
28+
// conditional expressions, `TerminatorKind::SwitchInt` branches, and a possible call to
29+
// `begin_panic_fmt()` (that begins a panic unwind, if the assertion test fails).
30+
// 4. `TerminatoKind::Assert` is, however, also present in the MIR generated for this test
31+
// (and in many other coverage tests). The `Assert` terminator is typically generated by the
32+
// Rust compiler to check for runtime failures, such as numeric overflows.

0 commit comments

Comments
 (0)