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
17import os
18import shutil
19import tempfile
20import unittest
21
22from mobly.config_parser import TestRunConfig
23from mock import Mock
24from mock import patch
25
26from acts import test_runner
27
28
29class TestRunnerTest(unittest.TestCase):
30    def setUp(self):
31        self.tmp_dir = tempfile.mkdtemp()
32        self.base_mock_test_config = TestRunConfig()
33        self.base_mock_test_config.testbed_name = 'SampleTestBed'
34        self.base_mock_test_config.log_path = self.tmp_dir
35        self.base_mock_test_config.controller_configs = {'testpaths': ['./']}
36        self.base_mock_test_config.user_params = {
37            'icecream': 42,
38            'extra_param': 'haha'
39        }
40
41    def tearDown(self):
42        shutil.rmtree(self.tmp_dir)
43
44    @staticmethod
45    def create_test_classes(class_names):
46        return {class_name: Mock() for class_name in class_names}
47
48    @patch('acts.records.TestResult')
49    @patch.object(test_runner.TestRunner, '_write_results_to_file')
50    def test_class_name_pattern_single(self, *_):
51        class_names = ['test_class_1', 'test_class_2']
52        pattern = 'test*1'
53        tr = test_runner.TestRunner(self.base_mock_test_config,
54                                    [(pattern, None)])
55
56        test_classes = self.create_test_classes(class_names)
57        tr.import_test_modules = Mock(return_value=test_classes)
58        tr.run()
59        self.assertTrue(test_classes[class_names[0]].called)
60        self.assertFalse(test_classes[class_names[1]].called)
61
62    @patch('acts.records.TestResult')
63    @patch.object(test_runner.TestRunner, '_write_results_to_file')
64    def test_class_name_pattern_multi(self, *_):
65        class_names = ['test_class_1', 'test_class_2', 'other_name']
66        pattern = 'test_class*'
67        tr = test_runner.TestRunner(self.base_mock_test_config,
68                                    [(pattern, None)])
69
70        test_classes = self.create_test_classes(class_names)
71        tr.import_test_modules = Mock(return_value=test_classes)
72        tr.run()
73        self.assertTrue(test_classes[class_names[0]].called)
74        self.assertTrue(test_classes[class_names[1]].called)
75        self.assertFalse(test_classes[class_names[2]].called)
76
77    @patch('acts.records.TestResult')
78    @patch.object(test_runner.TestRunner, '_write_results_to_file')
79    def test_class_name_pattern_question_mark(self, *_):
80        class_names = ['test_class_1', 'test_class_12']
81        pattern = 'test_class_?'
82        tr = test_runner.TestRunner(self.base_mock_test_config,
83                                    [(pattern, None)])
84
85        test_classes = self.create_test_classes(class_names)
86        tr.import_test_modules = Mock(return_value=test_classes)
87        tr.run()
88        self.assertTrue(test_classes[class_names[0]].called)
89        self.assertFalse(test_classes[class_names[1]].called)
90
91    @patch('acts.records.TestResult')
92    @patch.object(test_runner.TestRunner, '_write_results_to_file')
93    def test_class_name_pattern_char_seq(self, *_):
94        class_names = ['test_class_1', 'test_class_2', 'test_class_3']
95        pattern = 'test_class_[1357]'
96        tr = test_runner.TestRunner(self.base_mock_test_config,
97                                    [(pattern, None)])
98
99        test_classes = self.create_test_classes(class_names)
100        tr.import_test_modules = Mock(return_value=test_classes)
101        tr.run()
102        self.assertTrue(test_classes[class_names[0]].called)
103        self.assertFalse(test_classes[class_names[1]].called)
104        self.assertTrue(test_classes[class_names[2]].called)
105
106    @patch('acts.records.TestResult')
107    @patch.object(test_runner.TestRunner, 'dump_config')
108    @patch.object(test_runner.TestRunner, '_write_results_to_file')
109    @patch('acts.test_runner.logger')
110    def test_class_logpath_contains_proper_directory(self, logger_mock, *_):
111        expected_timestamp = '1970-01-01_00-00-00-00-000000'
112        logger_mock.get_log_file_timestamp.return_value = expected_timestamp
113        tr = test_runner.TestRunner(self.base_mock_test_config,
114                                    [('MockTest', None)])
115        mock_class = Mock()
116        tr.import_test_modules = Mock(return_value={'MockTest': mock_class})
117        tr.run()
118
119        self.assertEqual(
120            mock_class.call_args_list[0][0][0].log_path,
121            os.path.join(self.tmp_dir, self.base_mock_test_config.testbed_name,
122                         expected_timestamp))
123
124
125if __name__ == '__main__':
126    unittest.main()
127