1*c2e18aaaSAndroid Build Coastguard Worker# Copyright 2024, The Android Open Source Project 2*c2e18aaaSAndroid Build Coastguard Worker# 3*c2e18aaaSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*c2e18aaaSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*c2e18aaaSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*c2e18aaaSAndroid Build Coastguard Worker# 7*c2e18aaaSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*c2e18aaaSAndroid Build Coastguard Worker# 9*c2e18aaaSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*c2e18aaaSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*c2e18aaaSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*c2e18aaaSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*c2e18aaaSAndroid Build Coastguard Worker# limitations under the License. 14*c2e18aaaSAndroid Build Coastguard Worker 15*c2e18aaaSAndroid Build Coastguard Worker"""Test runner invocation class.""" 16*c2e18aaaSAndroid Build Coastguard Worker 17*c2e18aaaSAndroid Build Coastguard Workerfrom __future__ import annotations 18*c2e18aaaSAndroid Build Coastguard Worker 19*c2e18aaaSAndroid Build Coastguard Workerimport time 20*c2e18aaaSAndroid Build Coastguard Workerimport traceback 21*c2e18aaaSAndroid Build Coastguard Workerfrom typing import Any, Dict, List, Set 22*c2e18aaaSAndroid Build Coastguard Worker 23*c2e18aaaSAndroid Build Coastguard Workerfrom atest import result_reporter 24*c2e18aaaSAndroid Build Coastguard Workerfrom atest.atest_enum import ExitCode 25*c2e18aaaSAndroid Build Coastguard Workerfrom atest.metrics import metrics 26*c2e18aaaSAndroid Build Coastguard Workerfrom atest.metrics import metrics_utils 27*c2e18aaaSAndroid Build Coastguard Workerfrom atest.test_finders import test_info 28*c2e18aaaSAndroid Build Coastguard Workerfrom atest.test_runners import test_runner_base 29*c2e18aaaSAndroid Build Coastguard Worker 30*c2e18aaaSAndroid Build Coastguard Worker 31*c2e18aaaSAndroid Build Coastguard Workerclass TestRunnerInvocation: 32*c2e18aaaSAndroid Build Coastguard Worker """An invocation executing tests based on given arguments.""" 33*c2e18aaaSAndroid Build Coastguard Worker 34*c2e18aaaSAndroid Build Coastguard Worker def __init__( 35*c2e18aaaSAndroid Build Coastguard Worker self, 36*c2e18aaaSAndroid Build Coastguard Worker *, 37*c2e18aaaSAndroid Build Coastguard Worker test_runner: test_runner_base.TestRunnerBase, 38*c2e18aaaSAndroid Build Coastguard Worker extra_args: Dict[str, Any], 39*c2e18aaaSAndroid Build Coastguard Worker test_infos: List[test_info.TestInfo], 40*c2e18aaaSAndroid Build Coastguard Worker ): 41*c2e18aaaSAndroid Build Coastguard Worker self._extra_args = extra_args 42*c2e18aaaSAndroid Build Coastguard Worker self._test_infos = test_infos 43*c2e18aaaSAndroid Build Coastguard Worker self._test_runner = test_runner 44*c2e18aaaSAndroid Build Coastguard Worker 45*c2e18aaaSAndroid Build Coastguard Worker @property 46*c2e18aaaSAndroid Build Coastguard Worker def test_infos(self): 47*c2e18aaaSAndroid Build Coastguard Worker return self._test_infos 48*c2e18aaaSAndroid Build Coastguard Worker 49*c2e18aaaSAndroid Build Coastguard Worker def __eq__(self, other): 50*c2e18aaaSAndroid Build Coastguard Worker return self.__dict__ == other.__dict__ 51*c2e18aaaSAndroid Build Coastguard Worker 52*c2e18aaaSAndroid Build Coastguard Worker def requires_device_update(self): 53*c2e18aaaSAndroid Build Coastguard Worker """Checks whether this invocation requires device update.""" 54*c2e18aaaSAndroid Build Coastguard Worker return self._test_runner.requires_device_update(self._test_infos) 55*c2e18aaaSAndroid Build Coastguard Worker 56*c2e18aaaSAndroid Build Coastguard Worker def get_test_runner_reqs(self) -> Set[str]: 57*c2e18aaaSAndroid Build Coastguard Worker """Returns the required build targets for this test runner invocation.""" 58*c2e18aaaSAndroid Build Coastguard Worker return self._test_runner.get_test_runner_build_reqs(self._test_infos) 59*c2e18aaaSAndroid Build Coastguard Worker 60*c2e18aaaSAndroid Build Coastguard Worker # pylint: disable=too-many-locals 61*c2e18aaaSAndroid Build Coastguard Worker def run_all_tests(self, reporter: result_reporter.ResultReporter) -> ExitCode: 62*c2e18aaaSAndroid Build Coastguard Worker """Runs all tests.""" 63*c2e18aaaSAndroid Build Coastguard Worker 64*c2e18aaaSAndroid Build Coastguard Worker test_start = time.time() 65*c2e18aaaSAndroid Build Coastguard Worker is_success = True 66*c2e18aaaSAndroid Build Coastguard Worker err_msg = None 67*c2e18aaaSAndroid Build Coastguard Worker try: 68*c2e18aaaSAndroid Build Coastguard Worker tests_ret_code = self._test_runner.run_tests( 69*c2e18aaaSAndroid Build Coastguard Worker self._test_infos, self._extra_args, reporter 70*c2e18aaaSAndroid Build Coastguard Worker ) 71*c2e18aaaSAndroid Build Coastguard Worker except Exception: # pylint: disable=broad-except 72*c2e18aaaSAndroid Build Coastguard Worker is_success = False 73*c2e18aaaSAndroid Build Coastguard Worker err_msg = traceback.format_exc() 74*c2e18aaaSAndroid Build Coastguard Worker 75*c2e18aaaSAndroid Build Coastguard Worker if not is_success: 76*c2e18aaaSAndroid Build Coastguard Worker reporter.runner_failure(self._test_runner.NAME, err_msg) 77*c2e18aaaSAndroid Build Coastguard Worker tests_ret_code = ExitCode.TEST_FAILURE 78*c2e18aaaSAndroid Build Coastguard Worker 79*c2e18aaaSAndroid Build Coastguard Worker run_time = metrics_utils.convert_duration(time.time() - test_start) 80*c2e18aaaSAndroid Build Coastguard Worker tests = [] 81*c2e18aaaSAndroid Build Coastguard Worker for test in reporter.get_test_results_by_runner(self._test_runner.NAME): 82*c2e18aaaSAndroid Build Coastguard Worker # group_name is module name with abi(for example, 83*c2e18aaaSAndroid Build Coastguard Worker # 'x86_64 CtsSampleDeviceTestCases'). 84*c2e18aaaSAndroid Build Coastguard Worker # Filtering abi in group_name. 85*c2e18aaaSAndroid Build Coastguard Worker test_group = test.group_name 86*c2e18aaaSAndroid Build Coastguard Worker # Withdraw module name only when the test result has reported. 87*c2e18aaaSAndroid Build Coastguard Worker module_name = test_group 88*c2e18aaaSAndroid Build Coastguard Worker if test_group and ' ' in test_group: 89*c2e18aaaSAndroid Build Coastguard Worker _, module_name = test_group.split() 90*c2e18aaaSAndroid Build Coastguard Worker testcase_name = '%s:%s' % (module_name, test.test_name) 91*c2e18aaaSAndroid Build Coastguard Worker result = test_runner_base.RESULT_CODE[test.status] 92*c2e18aaaSAndroid Build Coastguard Worker tests.append( 93*c2e18aaaSAndroid Build Coastguard Worker {'name': testcase_name, 'result': result, 'stacktrace': test.details} 94*c2e18aaaSAndroid Build Coastguard Worker ) 95*c2e18aaaSAndroid Build Coastguard Worker metrics.RunnerFinishEvent( 96*c2e18aaaSAndroid Build Coastguard Worker duration=run_time, 97*c2e18aaaSAndroid Build Coastguard Worker success=is_success, 98*c2e18aaaSAndroid Build Coastguard Worker runner_name=self._test_runner.NAME, 99*c2e18aaaSAndroid Build Coastguard Worker test=tests, 100*c2e18aaaSAndroid Build Coastguard Worker ) 101*c2e18aaaSAndroid Build Coastguard Worker 102*c2e18aaaSAndroid Build Coastguard Worker return tests_ret_code 103