| ... |
... |
@@ -1861,6 +1861,7 @@ async def do_test(name: TestName, |
|
1861
|
1861
|
stdout=result.stdout,
|
|
1862
|
1862
|
stderr=result.stderr,
|
|
1863
|
1863
|
diff=result.diff,
|
|
|
1864
|
+ diff_label=result.diff_label,
|
|
1864
|
1865
|
runtime=runtime))
|
|
1865
|
1866
|
elif result.passed:
|
|
1866
|
1867
|
if _expect_pass(way):
|
| ... |
... |
@@ -1884,6 +1885,7 @@ async def do_test(name: TestName, |
|
1884
|
1885
|
stdout=result.stdout,
|
|
1885
|
1886
|
stderr=result.stderr,
|
|
1886
|
1887
|
diff=result.diff,
|
|
|
1888
|
+ diff_label=result.diff_label,
|
|
1887
|
1889
|
runtime=runtime)
|
|
1888
|
1890
|
t.unexpected_failures.append(tr)
|
|
1889
|
1891
|
else:
|
| ... |
... |
@@ -2070,7 +2072,8 @@ async def do_compile(name: TestName, |
|
2070
|
2072
|
"whitespace_normaliser",
|
|
2071
|
2073
|
normalise_whitespace))
|
|
2072
|
2074
|
if not stderr_match:
|
|
2073
|
|
- return failBecause('stderr mismatch', diff=stderr_match.diff)
|
|
|
2075
|
+ return failBecause('stderr mismatch', diff=stderr_match.diff,
|
|
|
2076
|
+ diff_label=stderr_match.diff_label)
|
|
2074
|
2077
|
|
|
2075
|
2078
|
opts = getTestOpts()
|
|
2076
|
2079
|
if isGenericStatsTest():
|
| ... |
... |
@@ -2491,13 +2494,15 @@ async def simple_run(name: TestName, way: WayName, prog: str, extra_run_opts: st |
|
2491
|
2494
|
return failBecause('bad stderr',
|
|
2492
|
2495
|
stderr=None if stderr_match.diff else read_stderr(name),
|
|
2493
|
2496
|
stdout=read_stdout(name),
|
|
2494
|
|
- diff=stderr_match.diff)
|
|
|
2497
|
+ diff=stderr_match.diff,
|
|
|
2498
|
+ diff_label=stderr_match.diff_label)
|
|
2495
|
2499
|
stdout_match = CompareOutput(True) if opts.ignore_stdout else await stdout_ok(name, way)
|
|
2496
|
2500
|
if not stdout_match:
|
|
2497
|
2501
|
return failBecause('bad stdout',
|
|
2498
|
2502
|
stderr=read_stderr(name),
|
|
2499
|
2503
|
stdout=None if stdout_match.diff else read_stdout(name),
|
|
2500
|
|
- diff=stdout_match.diff)
|
|
|
2504
|
+ diff=stdout_match.diff,
|
|
|
2505
|
+ diff_label=stdout_match.diff_label)
|
|
2501
|
2506
|
|
|
2502
|
2507
|
check_hp = '-hT' in my_rts_flags and opts.check_hp
|
|
2503
|
2508
|
check_prof = '-p' in my_rts_flags
|
| ... |
... |
@@ -2610,7 +2615,8 @@ async def interpreter_run(name: TestName, |
|
2610
|
2615
|
return failBecause('bad stderr',
|
|
2611
|
2616
|
stderr=None if stderr_match.diff else read_stderr(name),
|
|
2612
|
2617
|
stdout=read_stdout(name),
|
|
2613
|
|
- diff=stderr_match.diff)
|
|
|
2618
|
+ diff=stderr_match.diff,
|
|
|
2619
|
+ diff_label=stderr_match.diff_label)
|
|
2614
|
2620
|
stdout_match = CompareOutput(True) if opts.ignore_stdout else await stdout_ok(name, way)
|
|
2615
|
2621
|
if not stdout_match:
|
|
2616
|
2622
|
if _expect_pass(way):
|
| ... |
... |
@@ -2618,7 +2624,8 @@ async def interpreter_run(name: TestName, |
|
2618
|
2624
|
return failBecause('bad stdout',
|
|
2619
|
2625
|
stderr=read_stderr(name),
|
|
2620
|
2626
|
stdout=None if stdout_match.diff else read_stdout(name),
|
|
2621
|
|
- diff=stdout_match.diff)
|
|
|
2627
|
+ diff=stdout_match.diff,
|
|
|
2628
|
+ diff_label=stdout_match.diff_label)
|
|
2622
|
2629
|
return passed()
|
|
2623
|
2630
|
|
|
2624
|
2631
|
def split_file(in_fn: Path, delimiter: str, out1_fn: Path, out2_fn: Path):
|
| ... |
... |
@@ -2651,10 +2658,12 @@ def get_compiler_flags() -> List[str]: |
|
2651
|
2658
|
return flags
|
|
2652
|
2659
|
|
|
2653
|
2660
|
class CompareOutput:
|
|
2654
|
|
- __slots__ = 'ok', 'diff'
|
|
2655
|
|
- def __init__(self, ok: bool, diff: Optional[str]=None) -> None:
|
|
|
2661
|
+ __slots__ = 'ok', 'diff', 'diff_label'
|
|
|
2662
|
+ def __init__(self, ok: bool, diff: Optional[str]=None,
|
|
|
2663
|
+ diff_label: Optional[str]=None) -> None:
|
|
2656
|
2664
|
self.ok = ok
|
|
2657
|
2665
|
self.diff = diff
|
|
|
2666
|
+ self.diff_label = diff_label
|
|
2658
|
2667
|
def __bool__(self) -> bool:
|
|
2659
|
2668
|
return self.ok
|
|
2660
|
2669
|
|
| ... |
... |
@@ -2945,16 +2954,41 @@ def run_filecheck(way: WayName, |
|
2945
|
2954
|
# CQ[filecheck-platform-prefixes]
|
|
2946
|
2955
|
# Q: WS32/WS64 are always enabled, mirroring the -ws-NN golden suffixes;
|
|
2947
|
2956
|
# should OS/arch prefixes follow (cf. find_expected_file's platform chain)?
|
|
2948
|
|
- opts = Options(match_filename=str(in_srcdir(check_file)),
|
|
|
2957
|
+ prefixes = prefixes + ['WS' + config.wordsize]
|
|
|
2958
|
+ opts = Options(match_filename=os.path.relpath(in_srcdir(check_file)),
|
|
2949
|
2959
|
input_file=str(actual_path),
|
|
2950
|
|
- check_prefixes=prefixes + ['WS' + config.wordsize])
|
|
|
2960
|
+ check_prefixes=prefixes)
|
|
2951
|
2961
|
matcher = Matcher.from_opts(opts)
|
|
2952
|
2962
|
matcher.stderr = io.StringIO()
|
|
2953
|
|
- ok = matcher.run() == 0
|
|
2954
|
|
- report = matcher.stderr.getvalue()
|
|
2955
|
|
- if not ok and config.verbose >= 1 and _expect_pass(way):
|
|
|
2963
|
+ if matcher.run() == 0:
|
|
|
2964
|
+ return CompareOutput(True)
|
|
|
2965
|
+ report = matcher.stderr.getvalue() + filecheck_input_window(matcher, prefixes)
|
|
|
2966
|
+ if config.verbose >= 1 and _expect_pass(way):
|
|
2956
|
2967
|
print(report)
|
|
2957
|
|
- return CompareOutput(ok, None if ok else report)
|
|
|
2968
|
+ return CompareOutput(False, report, 'FileCheck report:')
|
|
|
2969
|
+
|
|
|
2970
|
+# The input from where the failing check started looking, numbered like the
|
|
|
2971
|
+# tool's positions; a substitute for LLVM FileCheck's annotated input dump.
|
|
|
2972
|
+def filecheck_input_window(matcher, prefixes: List[str], max_lines: int=40) -> str:
|
|
|
2973
|
+ content = matcher.file.content
|
|
|
2974
|
+ lines = content.split('\n')
|
|
|
2975
|
+ if content.endswith('\n'):
|
|
|
2976
|
+ lines.pop()
|
|
|
2977
|
+ # CQ[filecheck-window-anchor]
|
|
|
2978
|
+ # Q: a failing CHECK-NOT raises from inside the deferred check, leaving
|
|
|
2979
|
+ # negative_matches_start set; is relying on that too fragile?
|
|
|
2980
|
+ start = matcher.ctx.negative_matches_start
|
|
|
2981
|
+ if start is None:
|
|
|
2982
|
+ start = matcher.file.range.start
|
|
|
2983
|
+ first = content.count('\n', 0, start)
|
|
|
2984
|
+ shown = lines[first:first + max_lines]
|
|
|
2985
|
+ out = ['Input from line {} of {}, checked with prefixes {}:'.format(
|
|
|
2986
|
+ first + 1, len(lines), ', '.join(prefixes))]
|
|
|
2987
|
+ out += ['{:4} | {}'.format(first + i + 1, l) for i, l in enumerate(shown)]
|
|
|
2988
|
+ omitted = len(lines) - first - len(shown)
|
|
|
2989
|
+ if omitted > 0:
|
|
|
2990
|
+ out.append('... ({} more lines)'.format(omitted))
|
|
|
2991
|
+ return '\n'.join(out) + '\n'
|
|
2958
|
2992
|
|
|
2959
|
2993
|
# Checks that each line from pattern_file is present in actual_file as
|
|
2960
|
2994
|
# a substring or regex pattern depending on is_substring.
|
| ... |
... |
@@ -3814,7 +3848,8 @@ def printTestOutputSummary(file: TextIO, |
|
3814
|
3848
|
result.testname, ', '.join(ways), result.directory + os.sep, result.reason)
|
|
3815
|
3849
|
file.write(colored_if(color, Color.RED, header) + '\n')
|
|
3816
|
3850
|
# See Note [Redundant output in test results] for why these don't overlap.
|
|
3817
|
|
- for label, contents in [('Output diff (expected vs actual):', diff),
|
|
|
3851
|
+ diff_label = result.diff_label or 'Output diff (expected vs actual):'
|
|
|
3852
|
+ for label, contents in [(diff_label, diff),
|
|
3818
|
3853
|
('Captured stdout:', result.stdout),
|
|
3819
|
3854
|
('Captured stderr:', result.stderr)]:
|
|
3820
|
3855
|
if contents and contents.strip():
|