[foozzie] Make comparison before crash sensitive to single characters

The assumtion that V8 has no output differences within a single line
before a stack overflow, didn't hold. The prefix of e.g. console.info
can lead to a difference in a recursive call.

This change makes foozzie's output capping before a crash work on the
level of characters instead of lines to fix this.

No-Try: true
Bug: chromium:1050942
Change-Id: I13f747caf4f5848d40c31bd4232811285bab3c17
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2049844
Reviewed-by: Liviu Rau <liviurau@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66217}
This commit is contained in:
Michael Achenbach 2020-02-11 11:23:31 +01:00 committed by Commit Bot
parent f9b81189d5
commit 51cdea5def
2 changed files with 21 additions and 16 deletions

View File

@ -142,8 +142,8 @@ v8-foozzie source: foo
output1 = output(stdout1, is_crash1)
output2 = output(stdout2, is_crash2)
self.assertEquals(
(capped_lines1.splitlines(), capped_lines2.splitlines()),
v8_suppressions.get_lines_capped(output1, output2))
(capped_lines1, capped_lines2),
v8_suppressions.get_output_capped(output1, output2))
# No capping, already equal.
check('1\n2', '1\n2', True, True, '1\n2', '1\n2')
@ -153,15 +153,23 @@ v8-foozzie source: foo
# Cap smallest if all runs crash.
check('1\n2', '1\n2\n3', True, True, '1\n2', '1\n2')
check('1\n2\n3', '1\n2', True, True, '1\n2', '1\n2')
check('1\n2', '1\n23', True, True, '1\n2', '1\n2')
check('1\n23', '1\n2', True, True, '1\n2', '1\n2')
# Cap the non-crashy run.
check('1\n2\n3', '1\n2', False, True, '1\n2', '1\n2')
check('1\n2', '1\n2\n3', True, False, '1\n2', '1\n2')
check('1\n23', '1\n2', False, True, '1\n2', '1\n2')
check('1\n2', '1\n23', True, False, '1\n2', '1\n2')
# The crashy run has more output.
check('1\n2\n3', '1\n2', True, False, '1\n2\n3', '1\n2')
check('1\n2', '1\n2\n3', False, True, '1\n2', '1\n2\n3')
check('1\n23', '1\n2', True, False, '1\n23', '1\n2')
check('1\n2', '1\n23', False, True, '1\n2', '1\n23')
# Keep output difference when capping.
check('1\n2', '3\n4\n5', True, True, '1\n2', '3\n4')
check('1\n2\n3', '4\n5', True, True, '1\n2', '4\n5')
check('12', '345', True, True, '12', '34')
check('123', '45', True, True, '12', '45')
def cut_verbose_output(stdout):

View File

@ -136,32 +136,28 @@ IGNORE_LINES = [re.compile(exp) for exp in IGNORE_LINES]
ORIGINAL_SOURCE_PREFIX = 'v8-foozzie source: '
def get_lines_capped(output1, output2):
"""Returns a pair of stdout line lists.
def get_output_capped(output1, output2):
"""Returns a pair of stdout strings.
The lists are safely capped if at least one run has crashed. We assume
that output can never break off within the last line. If this assumption
turns out wrong, we need to add capping of the last line, too.
The strings are safely capped if at least one run has crashed.
"""
output1_lines = output1.stdout.splitlines()
output2_lines = output2.stdout.splitlines()
# No length difference or no crash -> no capping.
if (len(output1_lines) == len(output2_lines) or
if (len(output1.stdout) == len(output2.stdout) or
(not output1.HasCrashed() and not output2.HasCrashed())):
return output1_lines, output2_lines
return output1.stdout, output2.stdout
# Both runs have crashed, cap by the shorter output.
if output1.HasCrashed() and output2.HasCrashed():
cap = min(len(output1_lines), len(output2_lines))
cap = min(len(output1.stdout), len(output2.stdout))
# Only the first run has crashed, cap by its output length.
elif output1.HasCrashed():
cap = len(output1_lines)
cap = len(output1.stdout)
# Similar if only the second run has crashed.
else:
cap = len(output2_lines)
cap = len(output2.stdout)
return output1_lines[0:cap], output2_lines[0:cap]
return output1.stdout[0:cap], output2.stdout[0:cap]
def line_pairs(lines):
@ -297,7 +293,8 @@ class V8Suppression(Suppression):
def diff(self, output1, output2):
# Diff capped lines in the presence of crashes.
return self.diff_lines(*get_lines_capped(output1, output2))
return self.diff_lines(
*map(str.splitlines, get_output_capped(output1, output2)))
def diff_lines(self, output1_lines, output2_lines):
return diff_output(