1 import argparse 2 import string 3 4 class TestGroup: 5 def __init__(self, name, parent = None): 6 self.parent = parent 7 self.name = name 8 self.testGroups = {} 9 self.testCases = {} 10 11 if parent: 12 assert not name in parent.testGroups 13 parent.testGroups[name] = self 14 15 def getName (self): 16 return self.name 17 18 def getPath (self): 19 if self.parent: 20 return self.parent.getPath() + "." + self.name 21 else: 22 return self.name 23 24 def hasGroup(self, groupName): 25 return groupName in self.testGroups 26 27 def getGroup(self, groupName): 28 return self.testGroups[groupName] 29 30 def hasTest(self, testName): 31 return testName in self.testCases 32 33 def getTest(self, testName): 34 return self.testCases[testName] 35 36 def hasTestCases(self): 37 return len(self.testCases) != 0 38 39 def hasTestGroups(self): 40 return len(self.testGroups) != 0 41 42 def getTestCases(self): 43 return self.testCases.values() 44 45 def getTestGroups(self): 46 return self.testGroups.values() 47 48 class TestCase: 49 def __init__(self, name, parent): 50 self.name = name 51 self.parent = parent 52 53 assert not name in self.parent.testCases 54 self.parent.testCases[name] = self 55 56 def getPath (self): 57 return self.parent.getPath() + "." + self.name 58 59 def getName(self): 60 return self.name 61 62 def addGroupToHierarchy(rootGroup, path): 63 pathComponents = string.split(path, ".") 64 currentGroup = rootGroup 65 66 assert pathComponents[0] == rootGroup.getName() 67 68 for i in range(1, len(pathComponents)): 69 component = pathComponents[i] 70 71 if currentGroup.hasGroup(component): 72 currentGroup = currentGroup.getGroup(component) 73 else: 74 currentGroup = TestGroup(component, parent=currentGroup) 75 76 def addTestToHierarchy(rootGroup, path): 77 pathComponents = string.split(path, ".") 78 currentGroup = rootGroup 79 80 assert pathComponents[0] == rootGroup.getName() 81 82 for i in range(1, len(pathComponents)): 83 component = pathComponents[i] 84 85 if i == len(pathComponents) - 1: 86 TestCase(component, currentGroup) 87 else: 88 if currentGroup.hasGroup(component): 89 currentGroup = currentGroup.getGroup(component) 90 else: 91 currentGroup = TestGroup(component, parent=currentGroup) 92 93 def loadTestHierarchy (input): 94 line = input.readline() 95 rootGroup = None 96 97 if line.startswith("GROUP: "): 98 groupName = line[len("GROUP: "):-1] 99 rootGroup = TestGroup(groupName) 100 else: 101 assert False 102 103 for line in input: 104 if line.startswith("GROUP: "): 105 groupPath = line[len("GROUP: "):-1]; 106 addGroupToHierarchy(rootGroup, groupPath) 107 elif line.startswith("TEST: "): 108 testPath = line[len("TEST: "):-1] 109 addTestToHierarchy(rootGroup, testPath) 110 else: 111 assert False 112 113 return rootGroup 114 115 def hasFilteredCases(group, includeTests): 116 for child in group.getTestCases(): 117 if child.getPath() in includeTests: 118 return True 119 120 for child in group.getTestGroups(): 121 if hasFilteredCases(child, includeTests): 122 return True 123 124 return False 125 126 def addFilteredTest(parent, group, includeTests): 127 for child in group.getTestGroups(): 128 if hasFilteredCases(child, includeTests): 129 newChild = TestGroup(child.getName(), parent) 130 addFilteredTest(newChild, child, includeTests) 131 132 for child in group.getTestCases(): 133 if child.getPath() in includeTests: 134 TestCase(child.getName(), parent) 135 136 def filterTests(includeTests, group): 137 root = TestGroup(group.getName()) 138 139 addFilteredTest(root, group, includeTests) 140 141 return root 142 143 def writeAndroidCTSTest(test, output): 144 output.write('<Test name="%s" />\n' % test.getName()) 145 146 def writeAndroidCTSTestCase(group, output): 147 assert group.hasTestCases() 148 assert not group.hasTestGroups() 149 150 output.write('<TestCase name="%s">\n' % group.getName()) 151 152 for testCase in group.getTestCases(): 153 writeAndroidCTSTest(testCase, output) 154 155 output.write('</TestCase>\n') 156 157 def writeAndroidCTSTestSuite(group, output): 158 output.write('<TestSuite name="%s">\n' % group.getName()) 159 160 for childGroup in group.getTestGroups(): 161 if childGroup.hasTestCases(): 162 assert not childGroup.hasTestGroups() 163 writeAndroidCTSTestCase(childGroup, output) 164 elif childGroup.hasTestGroups(): 165 writeAndroidCTSTestSuite(childGroup, output) 166 # \note Skips groups without testcases or child groups 167 168 output.write('</TestSuite>\n') 169 170 def writeAndroidCTSFile(rootGroup, output, mustpass, name="dEQP-GLES3", appPackageName="com.drawelements.deqp.gles3"): 171 output.write('<?xml version="1.0" encoding="UTF-8"?>\n') 172 output.write('<TestPackage name="%s" appPackageName="%s" testType="deqpTest">\n' % (name, appPackageName)) 173 174 writeAndroidCTSTestSuite(filterTests(mustpass, rootGroup), output) 175 176 output.write('</TestPackage>\n') 177 178 if __name__ == "__main__": 179 parser = argparse.ArgumentParser() 180 parser.add_argument('input', type=argparse.FileType('r'), help="Input dEQP test hierarchy in txt format.") 181 parser.add_argument('output', type=argparse.FileType('w'), help="Output file for Android CTS test file.") 182 parser.add_argument('--name', dest="name", type=str, required=True, help="Name of the test package") 183 parser.add_argument('--package', dest="package", type=str, required=True, help="Name of the app package") 184 parser.add_argument('--must-pass', dest="mustpass", type=argparse.FileType('r'), required=True, help="Must pass file") 185 186 args = parser.parse_args() 187 188 rootGroup = loadTestHierarchy(args.input) 189 writeAndroidCTSFile(rootGroup, args.output, name=args.name, appPackageName=args.package, mustpass=set(map(lambda x : x.rstrip(), args.mustpass.readlines()))) 190