1 # -*- coding: utf-8 -*-
3 #-------------------------------------------------------------------------
4 # drawElements Quality Program utilities
5 # --------------------------------------
7 # Copyright 2015 The Android Open Source Project
9 # Licensed under the Apache License, Version 2.0 (the "License");
10 # you may not use this file except in compliance with the License.
11 # You may obtain a copy of the License at
13 # http://www.apache.org/licenses/LICENSE-2.0
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 # See the License for the specific language governing permissions and
19 # limitations under the License.
21 #-------------------------------------------------------------------------
27 from optparse import OptionParser
29 def all (results, predicate):
30 for result in results:
31 if not predicate(result):
35 def any (results, predicate):
36 for result in results:
42 def __init__ (self, name, description, filters):
44 self.description = description
45 self.filters = filters
48 def __init__ (self, name, results):
50 self.results = results
53 def __init__ (self, name):
57 def readCaseList (filename):
58 f = open(filename, 'rb')
61 if line[:6] == "TEST: ":
62 case = line[6:].strip()
67 def toResultList (caselist):
70 results.append(TestCaseResult(case, []))
73 def addResultsToCaseList (caselist, results):
75 caseListRes = toResultList(caselist)
77 for res in caseListRes:
78 resultMap[res.name] = res
80 for result in results:
81 if result.name in resultMap:
82 resultMap[result.name].results += result.results
86 def readTestResults (filename):
87 f = open(filename, 'rb')
89 csvLines = csvData.splitlines()
94 for line in csvLines[1:]:
95 args = line.split(',')
99 results.append(TestCaseResult(args[0], args[1:]))
101 if len(results) == 0:
102 raise Exception("Empty result list")
104 # Sanity check for results
105 numResultItems = len(results[0].results)
107 for result in results:
108 if result.name in seenResults:
109 raise Exception("Duplicate result row for test case '%s'" % result.name)
110 if len(result.results) != numResultItems:
111 raise Exception("Found %d results for test case '%s', expected %d" % (len(result.results), result.name, numResultItems))
112 seenResults.add(result.name)
116 def readGroupList (filename):
117 f = open(filename, 'rb')
125 def createGroups (results, groupNames):
129 for groupName in groupNames:
130 group = Group(groupName)
133 prefix = groupName + "."
134 prefixLen = len(prefix)
136 if case.name[:prefixLen] == prefix:
138 die("Case '%s' matched by multiple groups (when processing '%s')" % (case.name, group.name))
139 group.cases.append(case)
144 def createLeafGroups (results):
149 parts = case.name.split('.')
150 groupName = string.join(parts[:-1], ".")
152 if not groupName in groupMap:
153 group = Group(groupName)
155 groupMap[groupName] = group
157 group = groupMap[groupName]
159 group.cases.append(case)
163 def filterList (results, condition):
166 if condition(case.results):
167 filtered.append(case)
170 def getFilter (list, name):
172 if filter.name == name:
176 def getNumCasesInGroups (groups):
179 numCases += len(group.cases)
182 def getCasesInSet (results, caseSet):
186 filtered.append(case)
189 def selectCasesInGroups (results, groups):
190 casesInGroups = set()
192 for case in group.cases:
193 casesInGroups.add(case)
194 return getCasesInSet(results, casesInGroups)
196 def selectRandomSubset (results, groups, limit, seed):
197 selectedCases = set()
198 numSelect = min(limit, getNumCasesInGroups(groups))
201 random.shuffle(groups)
204 while len(selectedCases) < numSelect:
205 group = groups[groupNdx]
206 if len(group.cases) == 0:
208 if groupNdx == len(groups):
212 selected = random.choice(group.cases)
213 selectedCases.add(selected)
214 group.cases.remove(selected)
216 groupNdx = (groupNdx + 1) % len(groups)
218 return getCasesInSet(results, selectedCases)
226 FilterRule("all", "No filtering", []),
227 FilterRule("all-pass", "All results must be 'Pass'", [lambda l: all(l, lambda r: r == 'Pass')]),
228 FilterRule("any-pass", "Any of results is 'Pass'", [lambda l: any(l, lambda r: r == 'Pass')]),
229 FilterRule("any-fail", "Any of results is not 'Pass' or 'NotSupported'", [lambda l: not all(l, lambda r: r == 'Pass' or r == 'NotSupported')]),
230 FilterRule("prev-failing", "Any except last result is failure", [lambda l: l[-1] == 'Pass' and not all(l[:-1], lambda r: r == 'Pass')]),
231 FilterRule("prev-passing", "Any except last result is 'Pass'", [lambda l: l[-1] != 'Pass' and any(l[:-1], lambda r: r == 'Pass')])
234 if __name__ == "__main__":
235 parser = OptionParser(usage = "usage: %prog [options] [caselist] [result csv file]")
236 parser.add_option("-f", "--filter", dest="filter", default="all", help="filter rule name")
237 parser.add_option("-l", "--list", action="store_true", dest="list", default=False, help="list available rules")
238 parser.add_option("-n", "--num", dest="limit", default=0, help="limit number of cases")
239 parser.add_option("-s", "--seed", dest="seed", default=0, help="use selected seed for random selection")
240 parser.add_option("-g", "--groups", dest="groups_file", default=None, help="select cases based on group list file")
242 (options, args) = parser.parse_args()
245 print("Available filter rules:")
246 for filter in FILTER_RULES:
247 print(" %s: %s" % (filter.name, filter.description))
251 die("No input files specified")
253 die("Too many arguments")
256 filter = getFilter(FILTER_RULES, options.filter)
258 die("Unknown filter '%s'" % options.filter)
261 caselist = readCaseList(args[0])
263 results = readTestResults(args[1])
264 results = addResultsToCaseList(caselist, results)
266 results = toResultList(caselist)
268 # Execute filters for results
269 for rule in filter.filters:
270 results = filterList(results, rule)
272 if options.limit != 0:
273 if options.groups_file != None:
274 groups = createGroups(results, readGroupList(options.groups_file))
276 groups = createLeafGroups(results)
277 results = selectRandomSubset(results, groups, int(options.limit), int(options.seed))
278 elif options.groups_file != None:
279 groups = createGroups(results, readGroupList(options.groups_file))
280 results = selectCasesInGroups(results, groups)
283 for result in results: