Skip to content

Commit 5b79d55

Browse files
refackjasnell
authored andcommitted
tools,test: cleanup and dedup code
* Hoist common code to base class (`GetTestStatus`, and the `section` property to `TestConfiguration`) * Replace ListSet with the built in set * Remove ClassifiedTest * Inline PrintReport * How cases_to_run are filtered PR-URL: #23251 Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent 6445307 commit 5b79d55

File tree

4 files changed

+58
-124
lines changed

4 files changed

+58
-124
lines changed

test/message/testcfg.py

+1-10
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,6 @@ def GetSource(self):
108108

109109

110110
class MessageTestConfiguration(test.TestConfiguration):
111-
112-
def __init__(self, context, root):
113-
super(MessageTestConfiguration, self).__init__(context, root)
114-
115111
def Ls(self, path):
116112
if isdir(path):
117113
return [f for f in os.listdir(path)
@@ -135,11 +131,6 @@ def ListTests(self, current_path, path, arch, mode):
135131
def GetBuildRequirements(self):
136132
return ['sample', 'sample=shell']
137133

138-
def GetTestStatus(self, sections, defs):
139-
status_file = join(self.root, 'message.status')
140-
if exists(status_file):
141-
test.ReadConfigurationInto(status_file, sections, defs)
142-
143134

144135
def GetConfiguration(context, root):
145-
return MessageTestConfiguration(context, root)
136+
return MessageTestConfiguration(context, root, 'message')

test/pseudo-tty/testcfg.py

+1-10
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,6 @@ def RunCommand(self, command, env):
122122

123123

124124
class TTYTestConfiguration(test.TestConfiguration):
125-
126-
def __init__(self, context, root):
127-
super(TTYTestConfiguration, self).__init__(context, root)
128-
129125
def Ls(self, path):
130126
if isdir(path):
131127
return [f[:-3] for f in os.listdir(path) if f.endswith('.js')]
@@ -155,11 +151,6 @@ def ListTests(self, current_path, path, arch, mode):
155151
def GetBuildRequirements(self):
156152
return ['sample', 'sample=shell']
157153

158-
def GetTestStatus(self, sections, defs):
159-
status_file = join(self.root, 'pseudo-tty.status')
160-
if exists(status_file):
161-
test.ReadConfigurationInto(status_file, sections, defs)
162-
163154

164155
def GetConfiguration(context, root):
165-
return TTYTestConfiguration(context, root)
156+
return TTYTestConfiguration(context, root, 'pseudo-tty')

test/testpy/__init__.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,10 @@ def GetCommand(self):
9595
def GetSource(self):
9696
return open(self.file).read()
9797

98-
class SimpleTestConfiguration(test.TestConfiguration):
9998

99+
class SimpleTestConfiguration(test.TestConfiguration):
100100
def __init__(self, context, root, section, additional=None):
101-
super(SimpleTestConfiguration, self).__init__(context, root)
102-
self.section = section
101+
super(SimpleTestConfiguration, self).__init__(context, root, section)
103102
if additional is not None:
104103
self.additional_flags = additional
105104
else:
@@ -122,11 +121,6 @@ def ListTests(self, current_path, path, arch, mode):
122121
def GetBuildRequirements(self):
123122
return ['sample', 'sample=shell']
124123

125-
def GetTestStatus(self, sections, defs):
126-
status_file = join(self.root, '%s.status' % (self.section))
127-
if exists(status_file):
128-
test.ReadConfigurationInto(status_file, sections, defs)
129-
130124
class ParallelTestConfiguration(SimpleTestConfiguration):
131125
def __init__(self, context, root, section, additional=None):
132126
super(ParallelTestConfiguration, self).__init__(context, root, section,

tools/test.py

+54-96
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def RunSingle(self, parallel, thread_id):
131131
test = self.sequential_queue.get_nowait()
132132
except Empty:
133133
return
134-
case = test.case
134+
case = test
135135
case.thread_id = thread_id
136136
self.lock.acquire()
137137
self.AboutToRun(case)
@@ -780,10 +780,10 @@ def CarCdr(path):
780780

781781

782782
class TestConfiguration(object):
783-
784-
def __init__(self, context, root):
783+
def __init__(self, context, root, section):
785784
self.context = context
786785
self.root = root
786+
self.section = section
787787

788788
def Contains(self, path, file):
789789
if len(path) > len(file):
@@ -794,7 +794,9 @@ def Contains(self, path, file):
794794
return True
795795

796796
def GetTestStatus(self, sections, defs):
797-
pass
797+
status_file = join(self.root, '%s.status' % self.section)
798+
if exists(status_file):
799+
ReadConfigurationInto(status_file, sections, defs)
798800

799801

800802
class TestSuite(object):
@@ -934,6 +936,7 @@ def RunTestCases(cases_to_run, progress, tasks, flaky_tests_mode):
934936
# -------------------------------------------
935937

936938

939+
RUN = 'run'
937940
SKIP = 'skip'
938941
FAIL = 'fail'
939942
PASS = 'pass'
@@ -963,8 +966,8 @@ def __init__(self, name):
963966
self.name = name
964967

965968
def GetOutcomes(self, env, defs):
966-
if self.name in env: return ListSet([env[self.name]])
967-
else: return Nothing()
969+
if self.name in env: return set([env[self.name]])
970+
else: return set()
968971

969972

970973
class Outcome(Expression):
@@ -976,45 +979,7 @@ def GetOutcomes(self, env, defs):
976979
if self.name in defs:
977980
return defs[self.name].GetOutcomes(env, defs)
978981
else:
979-
return ListSet([self.name])
980-
981-
982-
class Set(object):
983-
pass
984-
985-
986-
class ListSet(Set):
987-
988-
def __init__(self, elms):
989-
self.elms = elms
990-
991-
def __str__(self):
992-
return "ListSet%s" % str(self.elms)
993-
994-
def Intersect(self, that):
995-
if not isinstance(that, ListSet):
996-
return that.Intersect(self)
997-
return ListSet([ x for x in self.elms if x in that.elms ])
998-
999-
def Union(self, that):
1000-
if not isinstance(that, ListSet):
1001-
return that.Union(self)
1002-
return ListSet(self.elms + [ x for x in that.elms if x not in self.elms ])
1003-
1004-
def IsEmpty(self):
1005-
return len(self.elms) == 0
1006-
1007-
1008-
class Nothing(Set):
1009-
1010-
def Intersect(self, that):
1011-
return self
1012-
1013-
def Union(self, that):
1014-
return that
1015-
1016-
def IsEmpty(self):
1017-
return True
982+
return set([self.name])
1018983

1019984

1020985
class Operation(Expression):
@@ -1030,21 +995,23 @@ def Evaluate(self, env, defs):
1030995
elif self.op == 'if':
1031996
return False
1032997
elif self.op == '==':
1033-
inter = self.left.GetOutcomes(env, defs).Intersect(self.right.GetOutcomes(env, defs))
1034-
return not inter.IsEmpty()
998+
inter = self.left.GetOutcomes(env, defs) & self.right.GetOutcomes(env, defs)
999+
return bool(inter)
10351000
else:
10361001
assert self.op == '&&'
10371002
return self.left.Evaluate(env, defs) and self.right.Evaluate(env, defs)
10381003

10391004
def GetOutcomes(self, env, defs):
10401005
if self.op == '||' or self.op == ',':
1041-
return self.left.GetOutcomes(env, defs).Union(self.right.GetOutcomes(env, defs))
1006+
return self.left.GetOutcomes(env, defs) | self.right.GetOutcomes(env, defs)
10421007
elif self.op == 'if':
1043-
if self.right.Evaluate(env, defs): return self.left.GetOutcomes(env, defs)
1044-
else: return Nothing()
1008+
if self.right.Evaluate(env, defs):
1009+
return self.left.GetOutcomes(env, defs)
1010+
else:
1011+
return set()
10451012
else:
10461013
assert self.op == '&&'
1047-
return self.left.GetOutcomes(env, defs).Intersect(self.right.GetOutcomes(env, defs))
1014+
return self.left.GetOutcomes(env, defs) & self.right.GetOutcomes(env, defs)
10481015

10491016

10501017
def IsAlpha(str):
@@ -1223,15 +1190,6 @@ def ParseCondition(expr):
12231190
return ast
12241191

12251192

1226-
class ClassifiedTest(object):
1227-
1228-
def __init__(self, case, outcomes):
1229-
self.case = case
1230-
self.outcomes = outcomes
1231-
self.parallel = self.case.parallel
1232-
self.disable_core_files = self.case.disable_core_files
1233-
1234-
12351193
class Configuration(object):
12361194
"""The parsed contents of a configuration file"""
12371195

@@ -1281,9 +1239,7 @@ def __init__(self, raw_path, path, value):
12811239
self.value = value
12821240

12831241
def GetOutcomes(self, env, defs):
1284-
set = self.value.GetOutcomes(env, defs)
1285-
assert isinstance(set, ListSet)
1286-
return set.elms
1242+
return self.value.GetOutcomes(env, defs)
12871243

12881244
def Contains(self, path):
12891245
if len(self.path) > len(path):
@@ -1428,6 +1384,7 @@ def ProcessOptions(options):
14281384
options.mode = options.mode.split(',')
14291385
options.run = options.run.split(',')
14301386
options.skip_tests = options.skip_tests.split(',')
1387+
options.skip_tests.remove("")
14311388
if options.run == [""]:
14321389
options.run = None
14331390
elif len(options.run) != 2:
@@ -1450,7 +1407,7 @@ def ProcessOptions(options):
14501407
# tends to exaggerate the number of available cpus/cores.
14511408
cores = os.environ.get('JOBS')
14521409
options.j = int(cores) if cores is not None else multiprocessing.cpu_count()
1453-
if options.flaky_tests not in ["run", "skip", "dontcare"]:
1410+
if options.flaky_tests not in [RUN, SKIP, DONTCARE]:
14541411
print "Unknown flaky-tests mode %s" % options.flaky_tests
14551412
return False
14561413
return True
@@ -1464,18 +1421,6 @@ def ProcessOptions(options):
14641421
* %(fail)4d tests are expected to fail that we should fix\
14651422
"""
14661423

1467-
def PrintReport(cases):
1468-
def IsFailOk(o):
1469-
return (len(o) == 2) and (FAIL in o) and (OKAY in o)
1470-
unskipped = [c for c in cases if not SKIP in c.outcomes]
1471-
print REPORT_TEMPLATE % {
1472-
'total': len(cases),
1473-
'skipped': len(cases) - len(unskipped),
1474-
'pass': len([t for t in unskipped if list(t.outcomes) == [PASS]]),
1475-
'fail_ok': len([t for t in unskipped if IsFailOk(t.outcomes)]),
1476-
'fail': len([t for t in unskipped if list(t.outcomes) == [FAIL]])
1477-
}
1478-
14791424

14801425
class Pattern(object):
14811426

@@ -1534,6 +1479,14 @@ def FormatTime(d):
15341479
return time.strftime("%M:%S.", time.gmtime(d)) + ("%03i" % millis)
15351480

15361481

1482+
def FormatTimedelta(td):
1483+
if hasattr(td.total, 'total_seconds'):
1484+
d = td.total_seconds()
1485+
else: # python2.6 compat
1486+
d = td.seconds + (td.microseconds / 10.0**6)
1487+
return FormatTime(d)
1488+
1489+
15371490
def PrintCrashed(code):
15381491
if utils.IsWindows():
15391492
return "CRASHED"
@@ -1713,25 +1666,32 @@ def Main():
17131666
print "Could not create the temporary directory", options.temp_dir
17141667
sys.exit(1)
17151668

1716-
if options.report:
1717-
PrintReport(all_cases)
1718-
1719-
result = None
1720-
def DoSkip(case):
1721-
# A list of tests that should be skipped can be provided. This is
1722-
# useful for tests that fail in some environments, e.g., under coverage.
1723-
if options.skip_tests != [""]:
1724-
if [ st for st in options.skip_tests if st in case.case.file ]:
1725-
return True
1726-
if SKIP in case.outcomes or SLOW in case.outcomes:
1669+
def should_keep(case):
1670+
if any((s in case.file) for s in options.skip_tests):
1671+
return False
1672+
elif SKIP in case.outcomes:
1673+
return False
1674+
elif (options.flaky_tests == SKIP) and (set([FLAKY]) & case.outcomes):
1675+
return False
1676+
else:
17271677
return True
1728-
return FLAKY in case.outcomes and options.flaky_tests == SKIP
1729-
cases_to_run = [ c for c in all_cases if not DoSkip(c) ]
1678+
1679+
cases_to_run = filter(should_keep, all_cases)
1680+
1681+
if options.report:
1682+
print(REPORT_TEMPLATE % {
1683+
'total': len(all_cases),
1684+
'skipped': len(all_cases) - len(cases_to_run),
1685+
'pass': len([t for t in cases_to_run if PASS in t.outcomes]),
1686+
'fail_ok': len([t for t in cases_to_run if t.outcomes == set([FAIL, OKAY])]),
1687+
'fail': len([t for t in cases_to_run if t.outcomes == set([FAIL])])
1688+
})
1689+
17301690
if options.run is not None:
17311691
# Must ensure the list of tests is sorted before selecting, to avoid
17321692
# silent errors if this file is changed to list the tests in a way that
17331693
# can be different in different machines
1734-
cases_to_run.sort(key=lambda c: (c.case.arch, c.case.mode, c.case.file))
1694+
cases_to_run.sort(key=lambda c: (c.arch, c.mode, c.file))
17351695
cases_to_run = [ cases_to_run[i] for i
17361696
in xrange(options.run[0],
17371697
len(cases_to_run),
@@ -1756,13 +1716,11 @@ def DoSkip(case):
17561716
# test output.
17571717
print
17581718
sys.stderr.write("--- Total time: %s ---\n" % FormatTime(duration))
1759-
timed_tests = [ t.case for t in cases_to_run if not t.case.duration is None ]
1719+
timed_tests = [ t for t in cases_to_run if not t.duration is None ]
17601720
timed_tests.sort(lambda a, b: a.CompareTime(b))
1761-
index = 1
1762-
for entry in timed_tests[:20]:
1763-
t = FormatTime(entry.duration.total_seconds())
1764-
sys.stderr.write("%4i (%s) %s\n" % (index, t, entry.GetLabel()))
1765-
index += 1
1721+
for i, entry in enumerate(timed_tests[:20], start=1):
1722+
t = FormatTimedelta(entry.duration)
1723+
sys.stderr.write("%4i (%s) %s\n" % (i, t, entry.GetLabel()))
17661724

17671725
return result
17681726

0 commit comments

Comments
 (0)