• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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# pylint: disable=line-too-long
21
22import os
23import tempfile
24import unittest
25
26from unittest import mock
27
28import atest_error
29import constants
30import module_info
31import test_runner_handler
32import unittest_constants as uc
33
34from metrics import metrics
35from test_finders import test_info
36from test_runners import test_runner_base as tr_base
37
38FAKE_TR_NAME_A = 'FakeTestRunnerA'
39FAKE_TR_NAME_B = 'FakeTestRunnerB'
40MISSING_TR_NAME = 'MissingTestRunner'
41FAKE_TR_A_REQS = {'fake_tr_A_req1', 'fake_tr_A_req2'}
42FAKE_TR_B_REQS = {'fake_tr_B_req1', 'fake_tr_B_req2'}
43MODULE_NAME_A = 'ModuleNameA'
44MODULE_NAME_A_AGAIN = 'ModuleNameA_AGAIN'
45MODULE_NAME_B = 'ModuleNameB'
46MODULE_NAME_B_AGAIN = 'ModuleNameB_AGAIN'
47MODULE_INFO_A = test_info.TestInfo(MODULE_NAME_A, FAKE_TR_NAME_A, set())
48MODULE_INFO_A_AGAIN = test_info.TestInfo(MODULE_NAME_A_AGAIN, FAKE_TR_NAME_A,
49                                         set())
50MODULE_INFO_B = test_info.TestInfo(MODULE_NAME_B, FAKE_TR_NAME_B, set())
51MODULE_INFO_B_AGAIN = test_info.TestInfo(MODULE_NAME_B_AGAIN, FAKE_TR_NAME_B,
52                                         set())
53BAD_TESTINFO = test_info.TestInfo('bad_name', MISSING_TR_NAME, set())
54BUILD_TOP_DIR = tempfile.TemporaryDirectory().name
55PRODUCT_OUT_DIR = os.path.join(BUILD_TOP_DIR, 'out/target/product/vsoc_x86_64')
56
57class FakeTestRunnerA(tr_base.TestRunnerBase):
58    """Fake test runner A."""
59
60    NAME = FAKE_TR_NAME_A
61    EXECUTABLE = 'echo'
62
63    def run_tests(self, test_infos, extra_args, reporter):
64        return 0
65
66    def host_env_check(self):
67        pass
68
69    def get_test_runner_build_reqs(self):
70        return FAKE_TR_A_REQS
71
72    def generate_run_commands(self, test_infos, extra_args, port=None):
73        return ['fake command']
74
75
76class FakeTestRunnerB(FakeTestRunnerA):
77    """Fake test runner B."""
78
79    NAME = FAKE_TR_NAME_B
80
81    def run_tests(self, test_infos, extra_args, reporter):
82        return 1
83
84    def get_test_runner_build_reqs(self):
85        return FAKE_TR_B_REQS
86
87
88class TestRunnerHandlerUnittests(unittest.TestCase):
89    """Unit tests for test_runner_handler.py"""
90
91    _TEST_RUNNERS = {
92        FakeTestRunnerA.NAME: FakeTestRunnerA,
93        FakeTestRunnerB.NAME: FakeTestRunnerB,
94    }
95
96    def setUp(self):
97        mock.patch('test_runner_handler._get_test_runners',
98                   return_value=self._TEST_RUNNERS).start()
99
100    def tearDown(self):
101        mock.patch.stopall()
102
103    def test_group_tests_by_test_runners(self):
104        """Test that we properly group tests by test runners."""
105        # Happy path testing.
106        test_infos = [MODULE_INFO_A, MODULE_INFO_A_AGAIN, MODULE_INFO_B,
107                      MODULE_INFO_B_AGAIN]
108        want_list = [(FakeTestRunnerA, [MODULE_INFO_A, MODULE_INFO_A_AGAIN]),
109                     (FakeTestRunnerB, [MODULE_INFO_B, MODULE_INFO_B_AGAIN])]
110        self.assertEqual(
111            want_list,
112            test_runner_handler.group_tests_by_test_runners(test_infos))
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, [BAD_TESTINFO])
118
119    def test_get_test_runner_reqs(self):
120        """Test that we get all the reqs from the test runners."""
121        test_infos = [MODULE_INFO_A, MODULE_INFO_B]
122        want_set = FAKE_TR_A_REQS | FAKE_TR_B_REQS
123        empty_module_info = None
124        self.assertEqual(
125            want_set,
126            test_runner_handler.get_test_runner_reqs(empty_module_info,
127                                                     test_infos))
128
129    @mock.patch.dict('os.environ', {constants.ANDROID_BUILD_TOP:'/',
130                                    constants.ANDROID_PRODUCT_OUT:PRODUCT_OUT_DIR})
131    @mock.patch.object(metrics, 'RunnerFinishEvent')
132    def test_run_all_tests(self, _mock_runner_finish):
133        """Test that the return value as we expected."""
134        results_dir = ""
135        extra_args = {}
136        mod_info = module_info.ModuleInfo(
137            module_file=os.path.join(uc.TEST_DATA_DIR, uc.JSON_FILE))
138        # Tests both run_tests return 0
139        test_infos = [MODULE_INFO_A, MODULE_INFO_A_AGAIN]
140        self.assertEqual(
141            0,
142            test_runner_handler.run_all_tests(
143                results_dir, test_infos, extra_args, mod_info)[0])
144        # Tests both run_tests return 1
145        test_infos = [MODULE_INFO_B, MODULE_INFO_B_AGAIN]
146        self.assertEqual(
147            1,
148            test_runner_handler.run_all_tests(
149                results_dir, test_infos, extra_args, mod_info)[0])
150        # Tests with on run_tests return 0, the other return 1
151        test_infos = [MODULE_INFO_A, MODULE_INFO_B]
152        self.assertEqual(
153            1,
154            test_runner_handler.run_all_tests(
155                results_dir, test_infos, extra_args, mod_info)[0])
156
157if __name__ == '__main__':
158    unittest.main()
159