Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Support for regarding flaky tests failures as non-fatal #8689

Merged
merged 2 commits into from
Dec 4, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions test/internet/internet.status
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
prefix internet

test-dns : PASS,FLAKY

[$system==solaris]
test-http-dns-fail : PASS,FLAKY
16 changes: 16 additions & 0 deletions test/simple/simple.status
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
prefix simple

test-crypto-domains : PASS,FLAKY

[$system==win32]
test-timers-first-fire : PASS,FLAKY

[$system==linux]
test-fs-readfile-error : PASS,FLAKY
test-net-GH-5504 : PASS,FLAKY
test-stdin-script-child : PASS,FLAKY
test-util-debug : PASS,FLAKY

[$system==macos]

[$system==solaris]
test-debug-signal-cluster : PASS,FLAKY
46 changes: 32 additions & 14 deletions tools/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@

class ProgressIndicator(object):

def __init__(self, cases):
def __init__(self, cases, flaky_tests_mode):
self.cases = cases
self.flaky_tests_mode = flaky_tests_mode
self.queue = Queue(len(cases))
for case in cases:
self.queue.put_nowait(case)
Expand Down Expand Up @@ -234,13 +235,19 @@ def HasRun(self, output):
self._done += 1
command = basename(output.command[-1])
if output.UnexpectedOutput():
print 'not ok %i - %s' % (self._done, command)
status_line = 'not ok %i - %s' % (self._done, command)
if FLAKY in output.test.outcomes and self.flaky_tests_mode == "dontcare":
status_line = status_line + " # TODO : Fix flaky test"
print status_line
for l in output.output.stderr.splitlines():
print '#' + l
for l in output.output.stdout.splitlines():
print '#' + l
else:
print 'ok %i - %s' % (self._done, command)
status_line = 'ok %i - %s' % (self._done, command)
if FLAKY in output.test.outcomes:
status_line = status_line + " # TODO : Fix flaky test"
print status_line

duration = output.test.duration

Expand All @@ -258,8 +265,8 @@ def Done(self):

class CompactProgressIndicator(ProgressIndicator):

def __init__(self, cases, templates):
super(CompactProgressIndicator, self).__init__(cases)
def __init__(self, cases, flaky_tests_mode, templates):
super(CompactProgressIndicator, self).__init__(cases, flaky_tests_mode)
self.templates = templates
self.last_status_length = 0
self.start_time = time.time()
Expand Down Expand Up @@ -314,29 +321,29 @@ def PrintProgress(self, name):

class ColorProgressIndicator(CompactProgressIndicator):

def __init__(self, cases):
def __init__(self, cases, flaky_tests_mode):
templates = {
'status_line': "[%(mins)02i:%(secs)02i|\033[34m%%%(remaining) 4d\033[0m|\033[32m+%(passed) 4d\033[0m|\033[31m-%(failed) 4d\033[0m]: %(test)s",
'stdout': "\033[1m%s\033[0m",
'stderr': "\033[31m%s\033[0m",
}
super(ColorProgressIndicator, self).__init__(cases, templates)
super(ColorProgressIndicator, self).__init__(cases, flaky_tests_mode, templates)

def ClearLine(self, last_line_length):
print "\033[1K\r",


class MonochromeProgressIndicator(CompactProgressIndicator):

def __init__(self, cases):
def __init__(self, cases, flaky_tests_mode):
templates = {
'status_line': "[%(mins)02i:%(secs)02i|%%%(remaining) 4d|+%(passed) 4d|-%(failed) 4d]: %(test)s",
'stdout': '%s',
'stderr': '%s',
'clear': lambda last_line_length: ("\r" + (" " * last_line_length) + "\r"),
'max_length': 78
}
super(MonochromeProgressIndicator, self).__init__(cases, templates)
super(MonochromeProgressIndicator, self).__init__(cases, flaky_tests_mode, templates)

def ClearLine(self, last_line_length):
print ("\r" + (" " * last_line_length) + "\r"),
Expand Down Expand Up @@ -738,8 +745,8 @@ def GetVmFlags(self, testcase, mode):
def GetTimeout(self, mode):
return self.timeout * TIMEOUT_SCALEFACTOR[mode]

def RunTestCases(cases_to_run, progress, tasks):
progress = PROGRESS_INDICATORS[progress](cases_to_run)
def RunTestCases(cases_to_run, progress, tasks, flaky_tests_mode):
progress = PROGRESS_INDICATORS[progress](cases_to_run, flaky_tests_mode)
return progress.Run(tasks)


Expand All @@ -763,6 +770,7 @@ def BuildRequirements(context, requirements, mode, scons_flags):
TIMEOUT = 'timeout'
CRASH = 'crash'
SLOW = 'slow'
FLAKY = 'flaky'


class Expression(object):
Expand Down Expand Up @@ -1212,6 +1220,9 @@ def BuildOptions():
default=False, action="store_true")
result.add_option("--cat", help="Print the source of the tests",
default=False, action="store_true")
result.add_option("--flaky-tests",
help="Regard tests marked as flaky (run|skip|dontcare)",
default="run")
result.add_option("--warn-unused", help="Report unused rules",
default=False, action="store_true")
result.add_option("-j", help="The number of parallel tasks to run",
Expand Down Expand Up @@ -1258,6 +1269,13 @@ def ProcessOptions(options):
options.scons_flags.append("arch=" + options.arch)
if options.snapshot:
options.scons_flags.append("snapshot=on")
def CheckTestMode(name, option):
if not option in ["run", "skip", "dontcare"]:
print "Unknown %s mode %s" % (name, option)
return False
return True
if not CheckTestMode("--flaky-tests", options.flaky_tests):
return False
return True


Expand Down Expand Up @@ -1457,15 +1475,15 @@ def wrap(processor):

result = None
def DoSkip(case):
return SKIP in case.outcomes or SLOW in case.outcomes
return SKIP in case.outcomes or SLOW in case.outcomes or (FLAKY in case.outcomes and options.flaky_tests == "skip")
cases_to_run = [ c for c in all_cases if not DoSkip(c) ]
if len(cases_to_run) == 0:
print "No tests to run."
return 0
return 1
else:
try:
start = time.time()
if RunTestCases(cases_to_run, options.progress, options.j):
if RunTestCases(cases_to_run, options.progress, options.j, options.flaky_tests):
result = 0
else:
result = 1
Expand Down