Skip to content

Commit 0cfd3be

Browse files
orangemocharvagg
authored andcommitted
test: runner support for flaky tests
Adding --flaky-tests option, to allow regarding flaky tests failures as non-fatal. Currently only observed by the TapProgressIndicator, which will add a # TODO directive to tests classified as flaky. According to the TAP specification, the test harness is supposed to treat failures that have a # TODO directive as non-fatal. Ported from nodejs/node-v0.x-archive@df3a2b2 PR-URL: #2424 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: João Reis <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]>
1 parent 1bc4468 commit 0cfd3be

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

tools/test.py

+30-14
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@
6161

6262
class ProgressIndicator(object):
6363

64-
def __init__(self, cases):
64+
def __init__(self, cases, flaky_tests_mode):
6565
self.cases = cases
66+
self.flaky_tests_mode = flaky_tests_mode
6667
self.parallel_queue = Queue(len(cases))
6768
self.sequential_queue = Queue(len(cases))
6869
for case in cases:
@@ -251,7 +252,10 @@ def HasRun(self, output):
251252
self._done += 1
252253
command = basename(output.command[-1])
253254
if output.UnexpectedOutput():
254-
logger.info('not ok %i - %s' % (self._done, command))
255+
status_line = 'not ok %i - %s' % (self._done, command)
256+
if FLAKY in output.test.outcomes and self.flaky_tests_mode == DONTCARE:
257+
status_line = status_line + ' # TODO : Fix flaky test'
258+
logger.info(status_line)
255259
for l in output.output.stderr.splitlines():
256260
logger.info('#' + l)
257261
for l in output.output.stdout.splitlines():
@@ -262,7 +266,10 @@ def HasRun(self, output):
262266
logger.info(
263267
'ok %i - %s # skip %s' % (self._done, command, skip.group(1)))
264268
else:
265-
logger.info('ok %i - %s' % (self._done, command))
269+
status_line = 'ok %i - %s' % (self._done, command)
270+
if FLAKY in output.test.outcomes:
271+
status_line = status_line + ' # TODO : Fix flaky test'
272+
logger.info(status_line)
266273

267274
duration = output.test.duration
268275

@@ -280,8 +287,8 @@ def Done(self):
280287

281288
class CompactProgressIndicator(ProgressIndicator):
282289

283-
def __init__(self, cases, templates):
284-
super(CompactProgressIndicator, self).__init__(cases)
290+
def __init__(self, cases, flaky_tests_mode, templates):
291+
super(CompactProgressIndicator, self).__init__(cases, flaky_tests_mode)
285292
self.templates = templates
286293
self.last_status_length = 0
287294
self.start_time = time.time()
@@ -336,29 +343,29 @@ def PrintProgress(self, name):
336343

337344
class ColorProgressIndicator(CompactProgressIndicator):
338345

339-
def __init__(self, cases):
346+
def __init__(self, cases, flaky_tests_mode):
340347
templates = {
341348
'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",
342349
'stdout': "\033[1m%s\033[0m",
343350
'stderr': "\033[31m%s\033[0m",
344351
}
345-
super(ColorProgressIndicator, self).__init__(cases, templates)
352+
super(ColorProgressIndicator, self).__init__(cases, flaky_tests_mode, templates)
346353

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

350357

351358
class MonochromeProgressIndicator(CompactProgressIndicator):
352359

353-
def __init__(self, cases):
360+
def __init__(self, cases, flaky_tests_mode):
354361
templates = {
355362
'status_line': "[%(mins)02i:%(secs)02i|%%%(remaining) 4d|+%(passed) 4d|-%(failed) 4d]: %(test)s",
356363
'stdout': '%s',
357364
'stderr': '%s',
358365
'clear': lambda last_line_length: ("\r" + (" " * last_line_length) + "\r"),
359366
'max_length': 78
360367
}
361-
super(MonochromeProgressIndicator, self).__init__(cases, templates)
368+
super(MonochromeProgressIndicator, self).__init__(cases, flaky_tests_mode, templates)
362369

363370
def ClearLine(self, last_line_length):
364371
print ("\r" + (" " * last_line_length) + "\r"),
@@ -780,8 +787,8 @@ def GetVmFlags(self, testcase, mode):
780787
def GetTimeout(self, mode):
781788
return self.timeout * TIMEOUT_SCALEFACTOR[ARCH_GUESS or 'ia32'][mode]
782789

783-
def RunTestCases(cases_to_run, progress, tasks):
784-
progress = PROGRESS_INDICATORS[progress](cases_to_run)
790+
def RunTestCases(cases_to_run, progress, tasks, flaky_tests_mode):
791+
progress = PROGRESS_INDICATORS[progress](cases_to_run, flaky_tests_mode)
785792
return progress.Run(tasks)
786793

787794

@@ -805,7 +812,8 @@ def BuildRequirements(context, requirements, mode, scons_flags):
805812
TIMEOUT = 'timeout'
806813
CRASH = 'crash'
807814
SLOW = 'slow'
808-
815+
FLAKY = 'flaky'
816+
DONTCARE = 'dontcare'
809817

810818
class Expression(object):
811819
pass
@@ -1253,6 +1261,9 @@ def BuildOptions():
12531261
default=False, action="store_true")
12541262
result.add_option("--cat", help="Print the source of the tests",
12551263
default=False, action="store_true")
1264+
result.add_option("--flaky-tests",
1265+
help="Regard tests marked as flaky (run|skip|dontcare)",
1266+
default="run")
12561267
result.add_option("--warn-unused", help="Report unused rules",
12571268
default=False, action="store_true")
12581269
result.add_option("-j", help="The number of parallel tasks to run",
@@ -1303,6 +1314,9 @@ def ProcessOptions(options):
13031314
return False
13041315
if options.J:
13051316
options.j = multiprocessing.cpu_count()
1317+
if options.flaky_tests not in ["run", "skip", "dontcare"]:
1318+
print "Unknown flaky-tests mode %s" % options.flaky_tests
1319+
return False
13061320
return True
13071321

13081322

@@ -1505,7 +1519,9 @@ def Main():
15051519

15061520
result = None
15071521
def DoSkip(case):
1508-
return SKIP in case.outcomes or SLOW in case.outcomes
1522+
if SKIP in case.outcomes or SLOW in case.outcomes:
1523+
return True
1524+
return FLAKY in case.outcomes and options.flaky_tests == SKIP
15091525
cases_to_run = [ c for c in all_cases if not DoSkip(c) ]
15101526
if options.run is not None:
15111527
# Must ensure the list of tests is sorted before selecting, to avoid
@@ -1522,7 +1538,7 @@ def DoSkip(case):
15221538
else:
15231539
try:
15241540
start = time.time()
1525-
if RunTestCases(cases_to_run, options.progress, options.j):
1541+
if RunTestCases(cases_to_run, options.progress, options.j, options.flaky_tests):
15261542
result = 0
15271543
else:
15281544
result = 1

0 commit comments

Comments
 (0)