1#!/usr/bin/env python3 2# 3# Copyright 2017, The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17"""Unittests for test_runner_handler.""" 18 19# pylint: disable=protected-access 20 21import unittest 22from unittest import mock 23 24from atest import atest_error 25from atest import test_runner_handler 26from atest.test_finders import test_info 27from atest.test_runners import test_runner_base as tr_base 28 29FAKE_TR_NAME_A = 'FakeTestRunnerA' 30FAKE_TR_NAME_B = 'FakeTestRunnerB' 31MISSING_TR_NAME = 'MissingTestRunner' 32FAKE_TR_A_REQS = {'fake_tr_A_req1', 'fake_tr_A_req2'} 33FAKE_TR_B_REQS = {'fake_tr_B_req1', 'fake_tr_B_req2'} 34MODULE_NAME_A = 'ModuleNameA' 35MODULE_NAME_A_AGAIN = 'ModuleNameA_AGAIN' 36MODULE_NAME_B = 'ModuleNameB' 37MODULE_NAME_B_AGAIN = 'ModuleNameB_AGAIN' 38MODULE_INFO_A = test_info.TestInfo(MODULE_NAME_A, FAKE_TR_NAME_A, set()) 39MODULE_INFO_A_AGAIN = test_info.TestInfo( 40 MODULE_NAME_A_AGAIN, FAKE_TR_NAME_A, set() 41) 42MODULE_INFO_B = test_info.TestInfo(MODULE_NAME_B, FAKE_TR_NAME_B, set()) 43MODULE_INFO_B_AGAIN = test_info.TestInfo( 44 MODULE_NAME_B_AGAIN, FAKE_TR_NAME_B, set() 45) 46BAD_TESTINFO = test_info.TestInfo('bad_name', MISSING_TR_NAME, set()) 47 48 49class FakeTestRunnerA(tr_base.TestRunnerBase): 50 """Fake test runner A.""" 51 52 NAME = FAKE_TR_NAME_A 53 EXECUTABLE = 'echo' 54 55 def run_tests(self, test_infos, extra_args, reporter): 56 return 0 57 58 def host_env_check(self): 59 pass 60 61 def get_test_runner_build_reqs(self, test_infos): 62 return FAKE_TR_A_REQS 63 64 def generate_run_commands(self, test_infos, extra_args, port=None): 65 return ['fake command'] 66 67 68class FakeTestRunnerB(FakeTestRunnerA): 69 """Fake test runner B.""" 70 71 NAME = FAKE_TR_NAME_B 72 73 def run_tests(self, test_infos, extra_args, reporter): 74 return 1 75 76 def get_test_runner_build_reqs(self, test_infos): 77 return FAKE_TR_B_REQS 78 79 80class TestRunnerHandlerUnittests(unittest.TestCase): 81 """Unit tests for test_runner_handler.py""" 82 83 _TEST_RUNNERS = { 84 FakeTestRunnerA.NAME: FakeTestRunnerA, 85 FakeTestRunnerB.NAME: FakeTestRunnerB, 86 } 87 88 def setUp(self): 89 mock.patch( 90 'atest.test_runner_handler._get_test_runners', 91 return_value=self._TEST_RUNNERS, 92 ).start() 93 94 def tearDown(self): 95 mock.patch.stopall() 96 97 def test_group_tests_by_test_runners(self): 98 """Test that we properly group tests by test runners.""" 99 # Happy path testing. 100 test_infos = [ 101 MODULE_INFO_A, 102 MODULE_INFO_A_AGAIN, 103 MODULE_INFO_B, 104 MODULE_INFO_B_AGAIN, 105 ] 106 want_list = [ 107 (FakeTestRunnerA, [MODULE_INFO_A, MODULE_INFO_A_AGAIN]), 108 (FakeTestRunnerB, [MODULE_INFO_B, MODULE_INFO_B_AGAIN]), 109 ] 110 self.assertEqual( 111 want_list, test_runner_handler.group_tests_by_test_runners(test_infos) 112 ) 113 114 # Let's make sure we fail as expected. 115 self.assertRaises( 116 atest_error.UnknownTestRunnerError, 117 test_runner_handler.group_tests_by_test_runners, 118 [BAD_TESTINFO], 119 ) 120 121 def test_get_test_runner_reqs(self): 122 """Test that we get all the reqs from the test runners.""" 123 test_infos = [MODULE_INFO_A, MODULE_INFO_B] 124 want_set = FAKE_TR_A_REQS | FAKE_TR_B_REQS 125 empty_module_info = None 126 invocations = test_runner_handler.create_test_runner_invocations( 127 test_infos=test_infos, 128 results_dir='', 129 mod_info=empty_module_info, 130 extra_args={}, 131 minimal_build=True, 132 ) 133 134 build_targets = set() 135 for invocation in invocations: 136 build_targets |= invocation.get_test_runner_reqs() 137 138 self.assertEqual(want_set, build_targets) 139 140 def test_run_all_tests_succeed(self): 141 """Test that the return value as we expected.""" 142 results_dir = '' 143 extra_args = {} 144 test_infos = [MODULE_INFO_A, MODULE_INFO_A_AGAIN] 145 invocation = test_runner_handler.TestRunnerInvocation( 146 test_infos=test_infos, 147 test_runner=FakeTestRunnerA(results_dir), 148 extra_args=extra_args, 149 ) 150 151 exit_code = invocation.run_all_tests(mock.MagicMock()) 152 153 self.assertEqual(0, exit_code) 154 155 def test_run_all_tests_failed(self): 156 """Test that the return value as we expected.""" 157 results_dir = '' 158 extra_args = {} 159 test_infos = [MODULE_INFO_B, MODULE_INFO_B_AGAIN] 160 invocation = test_runner_handler.TestRunnerInvocation( 161 test_infos=test_infos, 162 test_runner=FakeTestRunnerB(results_dir), 163 extra_args=extra_args, 164 ) 165 166 exit_code = invocation.run_all_tests(mock.MagicMock()) 167 168 self.assertEqual(1, exit_code) 169 170 171if __name__ == '__main__': 172 unittest.main() 173