1e5c31af7Sopenharmony_ci# -*- coding: utf-8 -*- 2e5c31af7Sopenharmony_ciimport logging 3e5c31af7Sopenharmony_ci 4e5c31af7Sopenharmony_ci#------------------------------------------------------------------------- 5e5c31af7Sopenharmony_ci# drawElements Quality Program utilities 6e5c31af7Sopenharmony_ci# -------------------------------------- 7e5c31af7Sopenharmony_ci# 8e5c31af7Sopenharmony_ci# Copyright 2016 The Android Open Source Project 9e5c31af7Sopenharmony_ci# 10e5c31af7Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 11e5c31af7Sopenharmony_ci# you may not use this file except in compliance with the License. 12e5c31af7Sopenharmony_ci# You may obtain a copy of the License at 13e5c31af7Sopenharmony_ci# 14e5c31af7Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 15e5c31af7Sopenharmony_ci# 16e5c31af7Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 17e5c31af7Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 18e5c31af7Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19e5c31af7Sopenharmony_ci# See the License for the specific language governing permissions and 20e5c31af7Sopenharmony_ci# limitations under the License. 21e5c31af7Sopenharmony_ci# 22e5c31af7Sopenharmony_ci#------------------------------------------------------------------------- 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_cifrom ctsbuild.common import * 25e5c31af7Sopenharmony_cifrom ctsbuild.build import build 26e5c31af7Sopenharmony_cifrom build_caselists import Module, getModuleByName, getBuildConfig, genCaseList, getCaseListPath, DEFAULT_BUILD_DIR, DEFAULT_TARGET 27e5c31af7Sopenharmony_cifrom fnmatch import fnmatch 28e5c31af7Sopenharmony_cifrom copy import copy 29e5c31af7Sopenharmony_cifrom collections import defaultdict 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_ciimport argparse 32e5c31af7Sopenharmony_ciimport re 33e5c31af7Sopenharmony_ciimport xml.etree.cElementTree as ElementTree 34e5c31af7Sopenharmony_ciimport xml.dom.minidom as minidom 35e5c31af7Sopenharmony_ci 36e5c31af7Sopenharmony_ciGENERATED_FILE_WARNING = """ 37e5c31af7Sopenharmony_ci This file has been automatically generated. Edit with caution. 38e5c31af7Sopenharmony_ci """ 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ciclass Project: 41e5c31af7Sopenharmony_ci def __init__ (self, path, copyright = None): 42e5c31af7Sopenharmony_ci self.path = path 43e5c31af7Sopenharmony_ci self.copyright = copyright 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_ciclass Configuration: 46e5c31af7Sopenharmony_ci def __init__ (self, name, filters, glconfig = None, rotation = None, surfacetype = None, required = False, runtime = None, runByDefault = True, listOfGroupsToSplit = []): 47e5c31af7Sopenharmony_ci self.name = name 48e5c31af7Sopenharmony_ci self.glconfig = glconfig 49e5c31af7Sopenharmony_ci self.rotation = rotation 50e5c31af7Sopenharmony_ci self.surfacetype = surfacetype 51e5c31af7Sopenharmony_ci self.required = required 52e5c31af7Sopenharmony_ci self.filters = filters 53e5c31af7Sopenharmony_ci self.expectedRuntime = runtime 54e5c31af7Sopenharmony_ci self.runByDefault = runByDefault 55e5c31af7Sopenharmony_ci self.listOfGroupsToSplit = listOfGroupsToSplit 56e5c31af7Sopenharmony_ci 57e5c31af7Sopenharmony_ciclass Package: 58e5c31af7Sopenharmony_ci def __init__ (self, module, configurations): 59e5c31af7Sopenharmony_ci self.module = module 60e5c31af7Sopenharmony_ci self.configurations = configurations 61e5c31af7Sopenharmony_ci 62e5c31af7Sopenharmony_ciclass Mustpass: 63e5c31af7Sopenharmony_ci def __init__ (self, project, version, packages): 64e5c31af7Sopenharmony_ci self.project = project 65e5c31af7Sopenharmony_ci self.version = version 66e5c31af7Sopenharmony_ci self.packages = packages 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_ciclass Filter: 69e5c31af7Sopenharmony_ci TYPE_INCLUDE = 0 70e5c31af7Sopenharmony_ci TYPE_EXCLUDE = 1 71e5c31af7Sopenharmony_ci 72e5c31af7Sopenharmony_ci def __init__ (self, type, filenames): 73e5c31af7Sopenharmony_ci self.type = type 74e5c31af7Sopenharmony_ci self.filenames = filenames 75e5c31af7Sopenharmony_ci self.key = ",".join(filenames) 76e5c31af7Sopenharmony_ci 77e5c31af7Sopenharmony_ciclass TestRoot: 78e5c31af7Sopenharmony_ci def __init__ (self): 79e5c31af7Sopenharmony_ci self.children = [] 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_ciclass TestGroup: 82e5c31af7Sopenharmony_ci def __init__ (self, name): 83e5c31af7Sopenharmony_ci self.name = name 84e5c31af7Sopenharmony_ci self.children = [] 85e5c31af7Sopenharmony_ci 86e5c31af7Sopenharmony_ciclass TestCase: 87e5c31af7Sopenharmony_ci def __init__ (self, name): 88e5c31af7Sopenharmony_ci self.name = name 89e5c31af7Sopenharmony_ci self.configurations = [] 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_cidef getSrcDir (mustpass): 92e5c31af7Sopenharmony_ci return os.path.join(mustpass.project.path, mustpass.version, "src") 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_cidef getModuleShorthand (module): 95e5c31af7Sopenharmony_ci assert module.name[:5] == "dEQP-" 96e5c31af7Sopenharmony_ci return module.name[5:].lower() 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_cidef getCaseListFileName (package, configuration): 99e5c31af7Sopenharmony_ci return "%s-%s.txt" % (getModuleShorthand(package.module), configuration.name) 100e5c31af7Sopenharmony_ci 101e5c31af7Sopenharmony_cidef getDstCaseListPath (mustpass): 102e5c31af7Sopenharmony_ci return os.path.join(mustpass.project.path, mustpass.version) 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_cidef getCommandLine (config): 105e5c31af7Sopenharmony_ci cmdLine = "" 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ci if config.glconfig != None: 108e5c31af7Sopenharmony_ci cmdLine += "--deqp-gl-config-name=%s " % config.glconfig 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ci if config.rotation != None: 111e5c31af7Sopenharmony_ci cmdLine += "--deqp-screen-rotation=%s " % config.rotation 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci if config.surfacetype != None: 114e5c31af7Sopenharmony_ci cmdLine += "--deqp-surface-type=%s " % config.surfacetype 115e5c31af7Sopenharmony_ci 116e5c31af7Sopenharmony_ci cmdLine += "--deqp-watchdog=enable" 117e5c31af7Sopenharmony_ci 118e5c31af7Sopenharmony_ci return cmdLine 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ciclass CaseList: 121e5c31af7Sopenharmony_ci def __init__(self, filePath, sortedLines): 122e5c31af7Sopenharmony_ci self.filePath = filePath 123e5c31af7Sopenharmony_ci self.sortedLines = sortedLines 124e5c31af7Sopenharmony_ci 125e5c31af7Sopenharmony_cidef readAndSortCaseList (buildCfg, generator, module): 126e5c31af7Sopenharmony_ci build(buildCfg, generator, [module.binName]) 127e5c31af7Sopenharmony_ci genCaseList(buildCfg, generator, module, "txt") 128e5c31af7Sopenharmony_ci filePath = getCaseListPath(buildCfg, module, "txt") 129e5c31af7Sopenharmony_ci with open(filePath, 'r') as first_file: 130e5c31af7Sopenharmony_ci lines = first_file.readlines() 131e5c31af7Sopenharmony_ci lines.sort() 132e5c31af7Sopenharmony_ci caseList = CaseList(filePath, lines) 133e5c31af7Sopenharmony_ci return caseList 134e5c31af7Sopenharmony_ci 135e5c31af7Sopenharmony_cidef readPatternList (filename, patternList): 136e5c31af7Sopenharmony_ci with open(filename, 'rt') as f: 137e5c31af7Sopenharmony_ci for line in f: 138e5c31af7Sopenharmony_ci line = line.strip() 139e5c31af7Sopenharmony_ci if len(line) > 0 and line[0] != '#': 140e5c31af7Sopenharmony_ci patternList.append(line) 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_cidef include (*filenames): 143e5c31af7Sopenharmony_ci return Filter(Filter.TYPE_INCLUDE, filenames) 144e5c31af7Sopenharmony_ci 145e5c31af7Sopenharmony_cidef exclude (*filenames): 146e5c31af7Sopenharmony_ci return Filter(Filter.TYPE_EXCLUDE, filenames) 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_cidef insertXMLHeaders (mustpass, doc): 149e5c31af7Sopenharmony_ci if mustpass.project.copyright != None: 150e5c31af7Sopenharmony_ci doc.insert(0, ElementTree.Comment(mustpass.project.copyright)) 151e5c31af7Sopenharmony_ci doc.insert(1, ElementTree.Comment(GENERATED_FILE_WARNING)) 152e5c31af7Sopenharmony_ci 153e5c31af7Sopenharmony_cidef prettifyXML (doc): 154e5c31af7Sopenharmony_ci uglyString = ElementTree.tostring(doc, 'utf-8') 155e5c31af7Sopenharmony_ci reparsed = minidom.parseString(uglyString) 156e5c31af7Sopenharmony_ci return reparsed.toprettyxml(indent='\t', encoding='utf-8') 157e5c31af7Sopenharmony_ci 158e5c31af7Sopenharmony_cidef genSpecXML (mustpass): 159e5c31af7Sopenharmony_ci mustpassElem = ElementTree.Element("Mustpass", version = mustpass.version) 160e5c31af7Sopenharmony_ci insertXMLHeaders(mustpass, mustpassElem) 161e5c31af7Sopenharmony_ci 162e5c31af7Sopenharmony_ci for package in mustpass.packages: 163e5c31af7Sopenharmony_ci packageElem = ElementTree.SubElement(mustpassElem, "TestPackage", name = package.module.name) 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci for config in package.configurations: 166e5c31af7Sopenharmony_ci configElem = ElementTree.SubElement(packageElem, "Configuration", 167e5c31af7Sopenharmony_ci caseListFile = getCaseListFileName(package, config), 168e5c31af7Sopenharmony_ci commandLine = getCommandLine(config), 169e5c31af7Sopenharmony_ci name = config.name) 170e5c31af7Sopenharmony_ci 171e5c31af7Sopenharmony_ci return mustpassElem 172e5c31af7Sopenharmony_ci 173e5c31af7Sopenharmony_cidef addOptionElement (parent, optionName, optionValue): 174e5c31af7Sopenharmony_ci ElementTree.SubElement(parent, "option", name=optionName, value=optionValue) 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_cidef genAndroidTestXml (mustpass): 177e5c31af7Sopenharmony_ci RUNNER_CLASS = "com.drawelements.deqp.runner.DeqpTestRunner" 178e5c31af7Sopenharmony_ci configElement = ElementTree.Element("configuration") 179e5c31af7Sopenharmony_ci 180e5c31af7Sopenharmony_ci # have the deqp package installed on the device for us 181e5c31af7Sopenharmony_ci preparerElement = ElementTree.SubElement(configElement, "target_preparer") 182e5c31af7Sopenharmony_ci preparerElement.set("class", "com.android.tradefed.targetprep.suite.SuiteApkInstaller") 183e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "cleanup-apks", "true") 184e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "test-file-name", "com.drawelements.deqp.apk") 185e5c31af7Sopenharmony_ci 186e5c31af7Sopenharmony_ci # Target preparer for incremental dEQP 187e5c31af7Sopenharmony_ci preparerElement = ElementTree.SubElement(configElement, "target_preparer") 188e5c31af7Sopenharmony_ci preparerElement.set("class", "com.android.compatibility.common.tradefed.targetprep.FilePusher") 189e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "cleanup", "true") 190e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "disable", "true") 191e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "push", "deqp-binary32->/data/local/tmp/deqp-binary32") 192e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "push", "deqp-binary64->/data/local/tmp/deqp-binary64") 193e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "push", "gles2->/data/local/tmp/gles2") 194e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "push", "gles3->/data/local/tmp/gles3") 195e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "push", "gles3-incremental-deqp.txt->/data/local/tmp/gles3-incremental-deqp.txt") 196e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "push", "gles31->/data/local/tmp/gles31") 197e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "push", "internal->/data/local/tmp/internal") 198e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "push", "vk-incremental-deqp.txt->/data/local/tmp/vk-incremental-deqp.txt") 199e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "push", "vulkan->/data/local/tmp/vulkan") 200e5c31af7Sopenharmony_ci preparerElement = ElementTree.SubElement(configElement, "target_preparer") 201e5c31af7Sopenharmony_ci preparerElement.set("class", "com.android.compatibility.common.tradefed.targetprep.IncrementalDeqpPreparer") 202e5c31af7Sopenharmony_ci addOptionElement(preparerElement, "disable", "true") 203e5c31af7Sopenharmony_ci 204e5c31af7Sopenharmony_ci # add in metadata option for component name 205e5c31af7Sopenharmony_ci ElementTree.SubElement(configElement, "option", name="test-suite-tag", value="cts") 206e5c31af7Sopenharmony_ci ElementTree.SubElement(configElement, "option", key="component", name="config-descriptor:metadata", value="deqp") 207e5c31af7Sopenharmony_ci ElementTree.SubElement(configElement, "option", key="parameter", name="config-descriptor:metadata", value="not_instant_app") 208e5c31af7Sopenharmony_ci ElementTree.SubElement(configElement, "option", key="parameter", name="config-descriptor:metadata", value="multi_abi") 209e5c31af7Sopenharmony_ci ElementTree.SubElement(configElement, "option", key="parameter", name="config-descriptor:metadata", value="secondary_user") 210e5c31af7Sopenharmony_ci ElementTree.SubElement(configElement, "option", key="parameter", name="config-descriptor:metadata", value="no_foldable_states") 211e5c31af7Sopenharmony_ci controllerElement = ElementTree.SubElement(configElement, "object") 212e5c31af7Sopenharmony_ci controllerElement.set("class", "com.android.tradefed.testtype.suite.module.TestFailureModuleController") 213e5c31af7Sopenharmony_ci controllerElement.set("type", "module_controller") 214e5c31af7Sopenharmony_ci addOptionElement(controllerElement, "screenshot-on-failure", "false") 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ci for package in mustpass.packages: 217e5c31af7Sopenharmony_ci for config in package.configurations: 218e5c31af7Sopenharmony_ci if not config.runByDefault: 219e5c31af7Sopenharmony_ci continue 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci testElement = ElementTree.SubElement(configElement, "test") 222e5c31af7Sopenharmony_ci testElement.set("class", RUNNER_CLASS) 223e5c31af7Sopenharmony_ci addOptionElement(testElement, "deqp-package", package.module.name) 224e5c31af7Sopenharmony_ci caseListFile = getCaseListFileName(package,config) 225e5c31af7Sopenharmony_ci addOptionElement(testElement, "deqp-caselist-file", caseListFile) 226e5c31af7Sopenharmony_ci if caseListFile.startswith("gles3"): 227e5c31af7Sopenharmony_ci addOptionElement(testElement, "incremental-deqp-include-file", "gles3-incremental-deqp.txt") 228e5c31af7Sopenharmony_ci elif caseListFile.startswith("vk"): 229e5c31af7Sopenharmony_ci addOptionElement(testElement, "incremental-deqp-include-file", "vk-incremental-deqp.txt") 230e5c31af7Sopenharmony_ci # \todo [2015-10-16 kalle]: Replace with just command line? - requires simplifications in the runner/tests as well. 231e5c31af7Sopenharmony_ci if config.glconfig != None: 232e5c31af7Sopenharmony_ci addOptionElement(testElement, "deqp-gl-config-name", config.glconfig) 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_ci if config.surfacetype != None: 235e5c31af7Sopenharmony_ci addOptionElement(testElement, "deqp-surface-type", config.surfacetype) 236e5c31af7Sopenharmony_ci 237e5c31af7Sopenharmony_ci if config.rotation != None: 238e5c31af7Sopenharmony_ci addOptionElement(testElement, "deqp-screen-rotation", config.rotation) 239e5c31af7Sopenharmony_ci 240e5c31af7Sopenharmony_ci if config.expectedRuntime != None: 241e5c31af7Sopenharmony_ci addOptionElement(testElement, "runtime-hint", config.expectedRuntime) 242e5c31af7Sopenharmony_ci 243e5c31af7Sopenharmony_ci if config.required: 244e5c31af7Sopenharmony_ci addOptionElement(testElement, "deqp-config-required", "true") 245e5c31af7Sopenharmony_ci 246e5c31af7Sopenharmony_ci insertXMLHeaders(mustpass, configElement) 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_ci return configElement 249e5c31af7Sopenharmony_ci 250e5c31af7Sopenharmony_ciclass PatternSet: 251e5c31af7Sopenharmony_ci def __init__(self): 252e5c31af7Sopenharmony_ci self.namedPatternsTree = {} 253e5c31af7Sopenharmony_ci self.namedPatternsDict = {} 254e5c31af7Sopenharmony_ci self.wildcardPatternsDict = {} 255e5c31af7Sopenharmony_ci 256e5c31af7Sopenharmony_cidef readPatternSets (mustpass): 257e5c31af7Sopenharmony_ci patternSets = {} 258e5c31af7Sopenharmony_ci for package in mustpass.packages: 259e5c31af7Sopenharmony_ci for cfg in package.configurations: 260e5c31af7Sopenharmony_ci for filter in cfg.filters: 261e5c31af7Sopenharmony_ci if not filter.key in patternSets: 262e5c31af7Sopenharmony_ci patternList = [] 263e5c31af7Sopenharmony_ci for filename in filter.filenames: 264e5c31af7Sopenharmony_ci readPatternList(os.path.join(getSrcDir(mustpass), filename), patternList) 265e5c31af7Sopenharmony_ci patternSet = PatternSet() 266e5c31af7Sopenharmony_ci for pattern in patternList: 267e5c31af7Sopenharmony_ci if pattern.find('*') == -1: 268e5c31af7Sopenharmony_ci patternSet.namedPatternsDict[pattern] = 0 269e5c31af7Sopenharmony_ci t = patternSet.namedPatternsTree 270e5c31af7Sopenharmony_ci parts = pattern.split('.') 271e5c31af7Sopenharmony_ci for part in parts: 272e5c31af7Sopenharmony_ci t = t.setdefault(part, {}) 273e5c31af7Sopenharmony_ci else: 274e5c31af7Sopenharmony_ci # We use regex instead of fnmatch because it's faster 275e5c31af7Sopenharmony_ci patternSet.wildcardPatternsDict[re.compile("^" + pattern.replace(".", r"\.").replace("*", ".*?") + "$")] = 0 276e5c31af7Sopenharmony_ci patternSets[filter.key] = patternSet 277e5c31af7Sopenharmony_ci return patternSets 278e5c31af7Sopenharmony_ci 279e5c31af7Sopenharmony_cidef genMustpassFromLists (mustpass, moduleCaseLists): 280e5c31af7Sopenharmony_ci print("Generating mustpass '%s'" % mustpass.version) 281e5c31af7Sopenharmony_ci patternSets = readPatternSets(mustpass) 282e5c31af7Sopenharmony_ci 283e5c31af7Sopenharmony_ci for package in mustpass.packages: 284e5c31af7Sopenharmony_ci currentCaseList = moduleCaseLists[package.module] 285e5c31af7Sopenharmony_ci logging.debug("Reading " + currentCaseList.filePath) 286e5c31af7Sopenharmony_ci 287e5c31af7Sopenharmony_ci for config in package.configurations: 288e5c31af7Sopenharmony_ci # construct components of path to main destination file 289e5c31af7Sopenharmony_ci mainDstFileDir = getDstCaseListPath(mustpass) 290e5c31af7Sopenharmony_ci mainDstFileName = getCaseListFileName(package, config) 291e5c31af7Sopenharmony_ci mainDstFilePath = os.path.join(mainDstFileDir, mainDstFileName) 292e5c31af7Sopenharmony_ci mainGroupSubDir = mainDstFileName[:-4] 293e5c31af7Sopenharmony_ci 294e5c31af7Sopenharmony_ci if not os.path.exists(mainDstFileDir): 295e5c31af7Sopenharmony_ci os.makedirs(mainDstFileDir) 296e5c31af7Sopenharmony_ci mainDstFile = open(mainDstFilePath, 'w') 297e5c31af7Sopenharmony_ci print(mainDstFilePath) 298e5c31af7Sopenharmony_ci output_files = {} 299e5c31af7Sopenharmony_ci def openAndStoreFile(filePath, testFilePath, parentFile): 300e5c31af7Sopenharmony_ci if filePath not in output_files: 301e5c31af7Sopenharmony_ci try: 302e5c31af7Sopenharmony_ci print(" " + filePath) 303e5c31af7Sopenharmony_ci parentFile.write(mainGroupSubDir + "/" + testFilePath + "\n") 304e5c31af7Sopenharmony_ci currentDir = os.path.dirname(filePath) 305e5c31af7Sopenharmony_ci if not os.path.exists(currentDir): 306e5c31af7Sopenharmony_ci os.makedirs(currentDir) 307e5c31af7Sopenharmony_ci output_files[filePath] = open(filePath, 'w') 308e5c31af7Sopenharmony_ci 309e5c31af7Sopenharmony_ci except FileNotFoundError: 310e5c31af7Sopenharmony_ci print(f"File not found: {filePath}") 311e5c31af7Sopenharmony_ci return output_files[filePath] 312e5c31af7Sopenharmony_ci 313e5c31af7Sopenharmony_ci lastOutputFile = "" 314e5c31af7Sopenharmony_ci currentOutputFile = None 315e5c31af7Sopenharmony_ci for line in currentCaseList.sortedLines: 316e5c31af7Sopenharmony_ci if not line.startswith("TEST: "): 317e5c31af7Sopenharmony_ci continue 318e5c31af7Sopenharmony_ci caseName = line.replace("TEST: ", "").strip("\n") 319e5c31af7Sopenharmony_ci caseParts = caseName.split(".") 320e5c31af7Sopenharmony_ci keep = True 321e5c31af7Sopenharmony_ci # Do the includes with the complex patterns first 322e5c31af7Sopenharmony_ci for filter in config.filters: 323e5c31af7Sopenharmony_ci if filter.type == Filter.TYPE_INCLUDE: 324e5c31af7Sopenharmony_ci keep = False 325e5c31af7Sopenharmony_ci patterns = patternSets[filter.key].wildcardPatternsDict 326e5c31af7Sopenharmony_ci for pattern in patterns.keys(): 327e5c31af7Sopenharmony_ci keep = pattern.match(caseName) 328e5c31af7Sopenharmony_ci if keep: 329e5c31af7Sopenharmony_ci patterns[pattern] += 1 330e5c31af7Sopenharmony_ci break 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci if not keep: 333e5c31af7Sopenharmony_ci t = patternSets[filter.key].namedPatternsTree 334e5c31af7Sopenharmony_ci if len(t.keys()) == 0: 335e5c31af7Sopenharmony_ci continue 336e5c31af7Sopenharmony_ci for part in caseParts: 337e5c31af7Sopenharmony_ci if part in t: 338e5c31af7Sopenharmony_ci t = t[part] 339e5c31af7Sopenharmony_ci else: 340e5c31af7Sopenharmony_ci t = None # Not found 341e5c31af7Sopenharmony_ci break 342e5c31af7Sopenharmony_ci keep = t == {} 343e5c31af7Sopenharmony_ci if keep: 344e5c31af7Sopenharmony_ci patternSets[filter.key].namedPatternsDict[caseName] += 1 345e5c31af7Sopenharmony_ci 346e5c31af7Sopenharmony_ci # Do the excludes 347e5c31af7Sopenharmony_ci if filter.type == Filter.TYPE_EXCLUDE: 348e5c31af7Sopenharmony_ci patterns = patternSets[filter.key].wildcardPatternsDict 349e5c31af7Sopenharmony_ci for pattern in patterns.keys(): 350e5c31af7Sopenharmony_ci discard = pattern.match(caseName) 351e5c31af7Sopenharmony_ci if discard: 352e5c31af7Sopenharmony_ci patterns[pattern] += 1 353e5c31af7Sopenharmony_ci keep = False 354e5c31af7Sopenharmony_ci break 355e5c31af7Sopenharmony_ci if keep: 356e5c31af7Sopenharmony_ci t = patternSets[filter.key].namedPatternsTree 357e5c31af7Sopenharmony_ci if len(t.keys()) == 0: 358e5c31af7Sopenharmony_ci continue 359e5c31af7Sopenharmony_ci for part in caseParts: 360e5c31af7Sopenharmony_ci if part in t: 361e5c31af7Sopenharmony_ci t = t[part] 362e5c31af7Sopenharmony_ci else: 363e5c31af7Sopenharmony_ci t = None # Not found 364e5c31af7Sopenharmony_ci break 365e5c31af7Sopenharmony_ci if t == {}: 366e5c31af7Sopenharmony_ci patternSets[filter.key].namedPatternsDict[caseName] += 1 367e5c31af7Sopenharmony_ci keep = False 368e5c31af7Sopenharmony_ci if not keep: 369e5c31af7Sopenharmony_ci break 370e5c31af7Sopenharmony_ci if not keep: 371e5c31af7Sopenharmony_ci continue 372e5c31af7Sopenharmony_ci 373e5c31af7Sopenharmony_ci parts = caseName.split('.') 374e5c31af7Sopenharmony_ci if len(config.listOfGroupsToSplit) > 0: 375e5c31af7Sopenharmony_ci if len(parts) > 2: 376e5c31af7Sopenharmony_ci groupName = parts[1].replace("_", "-") 377e5c31af7Sopenharmony_ci for splitPattern in config.listOfGroupsToSplit: 378e5c31af7Sopenharmony_ci splitParts = splitPattern.split(".") 379e5c31af7Sopenharmony_ci if len(splitParts) > 1 and caseName.startswith(splitPattern + "."): 380e5c31af7Sopenharmony_ci groupName = groupName + "/" + parts[2].replace("_", "-") 381e5c31af7Sopenharmony_ci filePath = os.path.join(mainDstFileDir, mainGroupSubDir, groupName + ".txt") 382e5c31af7Sopenharmony_ci if lastOutputFile != filePath: 383e5c31af7Sopenharmony_ci currentOutputFile = openAndStoreFile(filePath, groupName + ".txt", mainDstFile) 384e5c31af7Sopenharmony_ci lastOutputFile = filePath 385e5c31af7Sopenharmony_ci currentOutputFile.write(caseName + "\n") 386e5c31af7Sopenharmony_ci else: 387e5c31af7Sopenharmony_ci mainDstFile.write(caseName + "\n") 388e5c31af7Sopenharmony_ci 389e5c31af7Sopenharmony_ci # Check that all patterns have been used in the filters 390e5c31af7Sopenharmony_ci # This check will help identifying typos and patterns becoming stale 391e5c31af7Sopenharmony_ci for filter in config.filters: 392e5c31af7Sopenharmony_ci if filter.type == Filter.TYPE_INCLUDE: 393e5c31af7Sopenharmony_ci patternSet = patternSets[filter.key] 394e5c31af7Sopenharmony_ci for pattern, usage in patternSet.namedPatternsDict.items(): 395e5c31af7Sopenharmony_ci if usage == 0: 396e5c31af7Sopenharmony_ci logging.warning("Case %s in file %s for module %s was never used!" % (pattern, filter.key, config.name)) 397e5c31af7Sopenharmony_ci for pattern, usage in patternSet.wildcardPatternsDict.items(): 398e5c31af7Sopenharmony_ci if usage == 0: 399e5c31af7Sopenharmony_ci logging.warning("Pattern %s in file %s for module %s was never used!" % (pattern, filter.key, config.name)) 400e5c31af7Sopenharmony_ci 401e5c31af7Sopenharmony_ci # Generate XML 402e5c31af7Sopenharmony_ci specXML = genSpecXML(mustpass) 403e5c31af7Sopenharmony_ci specFilename = os.path.join(mustpass.project.path, mustpass.version, "mustpass.xml") 404e5c31af7Sopenharmony_ci 405e5c31af7Sopenharmony_ci print(" Writing spec: " + specFilename) 406e5c31af7Sopenharmony_ci writeFile(specFilename, prettifyXML(specXML).decode()) 407e5c31af7Sopenharmony_ci 408e5c31af7Sopenharmony_ci # TODO: Which is the best selector mechanism? 409e5c31af7Sopenharmony_ci if (mustpass.version == "master"): 410e5c31af7Sopenharmony_ci androidTestXML = genAndroidTestXml(mustpass) 411e5c31af7Sopenharmony_ci androidTestFilename = os.path.join(mustpass.project.path, "AndroidTest.xml") 412e5c31af7Sopenharmony_ci 413e5c31af7Sopenharmony_ci print(" Writing AndroidTest.xml: " + androidTestFilename) 414e5c31af7Sopenharmony_ci writeFile(androidTestFilename, prettifyXML(androidTestXML).decode()) 415e5c31af7Sopenharmony_ci 416e5c31af7Sopenharmony_ci print("Done!") 417e5c31af7Sopenharmony_ci 418e5c31af7Sopenharmony_ci 419e5c31af7Sopenharmony_cidef genMustpassLists (mustpassLists, generator, buildCfg): 420e5c31af7Sopenharmony_ci moduleCaseLists = {} 421e5c31af7Sopenharmony_ci 422e5c31af7Sopenharmony_ci # Getting case lists involves invoking build, so we want to cache the results 423e5c31af7Sopenharmony_ci for mustpass in mustpassLists: 424e5c31af7Sopenharmony_ci for package in mustpass.packages: 425e5c31af7Sopenharmony_ci if not package.module in moduleCaseLists: 426e5c31af7Sopenharmony_ci moduleCaseLists[package.module] = readAndSortCaseList(buildCfg, generator, package.module) 427e5c31af7Sopenharmony_ci 428e5c31af7Sopenharmony_ci for mustpass in mustpassLists: 429e5c31af7Sopenharmony_ci genMustpassFromLists(mustpass, moduleCaseLists) 430e5c31af7Sopenharmony_ci 431e5c31af7Sopenharmony_cidef parseCmdLineArgs (): 432e5c31af7Sopenharmony_ci parser = argparse.ArgumentParser(description = "Build Android CTS mustpass", 433e5c31af7Sopenharmony_ci formatter_class=argparse.ArgumentDefaultsHelpFormatter) 434e5c31af7Sopenharmony_ci parser.add_argument("-b", 435e5c31af7Sopenharmony_ci "--build-dir", 436e5c31af7Sopenharmony_ci dest="buildDir", 437e5c31af7Sopenharmony_ci default=DEFAULT_BUILD_DIR, 438e5c31af7Sopenharmony_ci help="Temporary build directory") 439e5c31af7Sopenharmony_ci parser.add_argument("-t", 440e5c31af7Sopenharmony_ci "--build-type", 441e5c31af7Sopenharmony_ci dest="buildType", 442e5c31af7Sopenharmony_ci default="Debug", 443e5c31af7Sopenharmony_ci help="Build type") 444e5c31af7Sopenharmony_ci parser.add_argument("-c", 445e5c31af7Sopenharmony_ci "--deqp-target", 446e5c31af7Sopenharmony_ci dest="targetName", 447e5c31af7Sopenharmony_ci default=DEFAULT_TARGET, 448e5c31af7Sopenharmony_ci help="dEQP build target") 449e5c31af7Sopenharmony_ci return parser.parse_args() 450e5c31af7Sopenharmony_ci 451e5c31af7Sopenharmony_cidef parseBuildConfigFromCmdLineArgs (): 452e5c31af7Sopenharmony_ci args = parseCmdLineArgs() 453e5c31af7Sopenharmony_ci return getBuildConfig(args.buildDir, args.targetName, args.buildType) 454