1*d83cc019SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*d83cc019SAndroid Build Coastguard Worker 3*d83cc019SAndroid Build Coastguard Worker# Copyright (C) 2020 The Android Open Source Project 4*d83cc019SAndroid Build Coastguard Worker 5*d83cc019SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*d83cc019SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*d83cc019SAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*d83cc019SAndroid Build Coastguard Worker# 9*d83cc019SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*d83cc019SAndroid Build Coastguard Worker# 11*d83cc019SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*d83cc019SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*d83cc019SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*d83cc019SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*d83cc019SAndroid Build Coastguard Worker# limitations under the License. 16*d83cc019SAndroid Build Coastguard Worker 17*d83cc019SAndroid Build Coastguard Workerimport os 18*d83cc019SAndroid Build Coastguard Workerimport unittest 19*d83cc019SAndroid Build Coastguard Workerfrom xml.etree import ElementTree 20*d83cc019SAndroid Build Coastguard Workerimport subprocess 21*d83cc019SAndroid Build Coastguard Workerimport sys 22*d83cc019SAndroid Build Coastguard Worker 23*d83cc019SAndroid Build Coastguard WorkerVERBOSE = True 24*d83cc019SAndroid Build Coastguard WorkerTEST_CONFIG = os.path.join(os.path.dirname(__file__), "test_igt_gpu_tools.xml") 25*d83cc019SAndroid Build Coastguard Worker 26*d83cc019SAndroid Build Coastguard Worker""" Extracts tests from AndroidTest.xml compatible file 27*d83cc019SAndroid Build Coastguard Worker param: xmlfile str containing path to AndroidTest.xml compatible xml file 28*d83cc019SAndroid Build Coastguard Worker""" 29*d83cc019SAndroid Build Coastguard Workerdef extract_tests_from_xml(xmlfile): 30*d83cc019SAndroid Build Coastguard Worker tree = ElementTree.parse(xmlfile) 31*d83cc019SAndroid Build Coastguard Worker root = tree.getroot() 32*d83cc019SAndroid Build Coastguard Worker return [(o.attrib['key'], o.attrib['value']) 33*d83cc019SAndroid Build Coastguard Worker for o in root.findall("./target_preparer/option") 34*d83cc019SAndroid Build Coastguard Worker if o.attrib['name'] == "push-file"] 35*d83cc019SAndroid Build Coastguard Worker 36*d83cc019SAndroid Build Coastguard Workerdef run_command(command): 37*d83cc019SAndroid Build Coastguard Worker serial_number = os.environ.get("ANDROID_SERIAL", "") 38*d83cc019SAndroid Build Coastguard Worker if not serial_number: 39*d83cc019SAndroid Build Coastguard Worker raise "$ANDROID_SERIAL is empty, device must be specified" 40*d83cc019SAndroid Build Coastguard Worker full_command = ["adb", "-s", serial_number, "shell"] + command 41*d83cc019SAndroid Build Coastguard Worker if VERBOSE: 42*d83cc019SAndroid Build Coastguard Worker print("+" + " ".join(full_command)) 43*d83cc019SAndroid Build Coastguard Worker ret = subprocess.run(full_command, capture_output=True, universal_newlines=True) 44*d83cc019SAndroid Build Coastguard Worker if VERBOSE: 45*d83cc019SAndroid Build Coastguard Worker print(ret.stdout) 46*d83cc019SAndroid Build Coastguard Worker return ret.stdout 47*d83cc019SAndroid Build Coastguard Worker 48*d83cc019SAndroid Build Coastguard Workerclass IGTGpuToolsBinary(): 49*d83cc019SAndroid Build Coastguard Worker """Harness object for a specific IGT GPU test binary. """ 50*d83cc019SAndroid Build Coastguard Worker 51*d83cc019SAndroid Build Coastguard Worker """ param: ondevice_test_path The IGT binary path on device """ 52*d83cc019SAndroid Build Coastguard Worker def __init__(self, ondevice_test_path): 53*d83cc019SAndroid Build Coastguard Worker self._path = ondevice_test_path 54*d83cc019SAndroid Build Coastguard Worker subtests = run_command([self._path, "--list-subtests"]) 55*d83cc019SAndroid Build Coastguard Worker self._subtests = list(filter(lambda x: x != "", subtests.split("\n"))) 56*d83cc019SAndroid Build Coastguard Worker 57*d83cc019SAndroid Build Coastguard Worker """lists subtests detected in tests. 58*d83cc019SAndroid Build Coastguard Worker return: list of strings indicating subtests found in binary. 59*d83cc019SAndroid Build Coastguard Worker """ 60*d83cc019SAndroid Build Coastguard Worker def subtests(self): 61*d83cc019SAndroid Build Coastguard Worker return self._subtests; 62*d83cc019SAndroid Build Coastguard Worker 63*d83cc019SAndroid Build Coastguard Worker """Runs a subtest. 64*d83cc019SAndroid Build Coastguard Worker 65*d83cc019SAndroid Build Coastguard Worker param: subtest_name One of the subtests listed by self.subtest() 66*d83cc019SAndroid Build Coastguard Worker return: a subprocess.CompletedProcess 67*d83cc019SAndroid Build Coastguard Worker """ 68*d83cc019SAndroid Build Coastguard Worker def run_subtest(self, subtest_name): 69*d83cc019SAndroid Build Coastguard Worker if subtest_name not in self._subtests: 70*d83cc019SAndroid Build Coastguard Worker error 71*d83cc019SAndroid Build Coastguard Worker return run_command([self._path, "--run-subtest", subtest_name]) 72*d83cc019SAndroid Build Coastguard Worker 73*d83cc019SAndroid Build Coastguard Workerclass IGTGpuToolsTest(unittest.TestCase): 74*d83cc019SAndroid Build Coastguard Worker """Tests for DRM/KMS using Intel Graphics Tests suite""" 75*d83cc019SAndroid Build Coastguard Worker 76*d83cc019SAndroid Build Coastguard Worker """ param: subtest A valid subtest for the binary 77*d83cc019SAndroid Build Coastguard Worker param: the IGT binary to run as a unit test. 78*d83cc019SAndroid Build Coastguard Worker """ 79*d83cc019SAndroid Build Coastguard Worker def __init__(self, subtest, binary): 80*d83cc019SAndroid Build Coastguard Worker self._subtest_name = subtest 81*d83cc019SAndroid Build Coastguard Worker self._test_binary = binary 82*d83cc019SAndroid Build Coastguard Worker setattr(self, self._subtest_name, self.runTest) 83*d83cc019SAndroid Build Coastguard Worker super(IGTGpuToolsTest, self).__init__(methodName=self._subtest_name) 84*d83cc019SAndroid Build Coastguard Worker 85*d83cc019SAndroid Build Coastguard Worker """ Runs the test set in the constructor """ 86*d83cc019SAndroid Build Coastguard Worker def runTest(self): 87*d83cc019SAndroid Build Coastguard Worker output = self._test_binary.run_subtest(self._subtest_name) 88*d83cc019SAndroid Build Coastguard Worker for line in output.split("\n"): 89*d83cc019SAndroid Build Coastguard Worker if "Subtest" not in line: 90*d83cc019SAndroid Build Coastguard Worker continue; 91*d83cc019SAndroid Build Coastguard Worker if "SKIP" in line: 92*d83cc019SAndroid Build Coastguard Worker self.skipTest("{} - skipped".format(self._subtest_name)) 93*d83cc019SAndroid Build Coastguard Worker break 94*d83cc019SAndroid Build Coastguard Worker if "SUCCESS" in line: 95*d83cc019SAndroid Build Coastguard Worker break 96*d83cc019SAndroid Build Coastguard Worker if "FAIL" in line: 97*d83cc019SAndroid Build Coastguard Worker self.fail(output) 98*d83cc019SAndroid Build Coastguard Worker break 99*d83cc019SAndroid Build Coastguard Worker self.fail("could not parse test output; test runner failure") 100*d83cc019SAndroid Build Coastguard Worker 101*d83cc019SAndroid Build Coastguard WorkerANDROID_RUNNER_REQUIRED_VERBOSITY = 2 102*d83cc019SAndroid Build Coastguard Worker 103*d83cc019SAndroid Build Coastguard Workerdef main(): 104*d83cc019SAndroid Build Coastguard Worker """main entrypoint for test runner""" 105*d83cc019SAndroid Build Coastguard Worker 106*d83cc019SAndroid Build Coastguard Worker runner = unittest.TextTestRunner(stream=sys.stderr, verbosity=ANDROID_RUNNER_REQUIRED_VERBOSITY) 107*d83cc019SAndroid Build Coastguard Worker suite = unittest.TestSuite() 108*d83cc019SAndroid Build Coastguard Worker for test, test_path in extract_tests_from_xml(TEST_CONFIG): 109*d83cc019SAndroid Build Coastguard Worker print("Found IGT-GPU-tools test {}".format(test)) 110*d83cc019SAndroid Build Coastguard Worker subsuite = unittest.TestSuite() 111*d83cc019SAndroid Build Coastguard Worker binary = IGTGpuToolsBinary(test_path) 112*d83cc019SAndroid Build Coastguard Worker for subtest in binary.subtests(): 113*d83cc019SAndroid Build Coastguard Worker print("\tFound subtest {}".format(subtest)) 114*d83cc019SAndroid Build Coastguard Worker subsuite.addTest(IGTGpuToolsTest(subtest, binary)) 115*d83cc019SAndroid Build Coastguard Worker suite.addTest(subsuite) 116*d83cc019SAndroid Build Coastguard Worker runner.run(suite) 117*d83cc019SAndroid Build Coastguard Worker 118*d83cc019SAndroid Build Coastguard Workerif __name__=="__main__": 119*d83cc019SAndroid Build Coastguard Worker main() 120