• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2017 Google Inc.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import inspect
16import io
17import os
18import shutil
19import sys
20import tempfile
21import unittest
22from unittest import mock
23
24from mobly import base_suite
25from mobly import base_test
26from mobly import config_parser
27from mobly import test_runner
28from mobly import suite_runner
29from tests.lib import integration2_test
30from tests.lib import integration_test
31
32
33class FakeTest1(base_test.BaseTestClass):
34  pass
35
36
37class SuiteRunnerTest(unittest.TestCase):
38
39  def setUp(self):
40    self.tmp_dir = tempfile.mkdtemp()
41
42  def tearDown(self):
43    shutil.rmtree(self.tmp_dir)
44
45  def test_select_no_args(self):
46    identifiers = suite_runner.compute_selected_tests(test_classes=[
47        integration_test.IntegrationTest, integration2_test.Integration2Test
48    ],
49                                                      selected_tests=None)
50    self.assertEqual(
51        {
52            integration_test.IntegrationTest: None,
53            integration2_test.Integration2Test: None,
54        }, identifiers)
55
56  def test_select_by_class(self):
57    identifiers = suite_runner.compute_selected_tests(
58        test_classes=[
59            integration_test.IntegrationTest, integration2_test.Integration2Test
60        ],
61        selected_tests=['IntegrationTest'])
62    self.assertEqual({integration_test.IntegrationTest: None}, identifiers)
63
64  def test_select_by_method(self):
65    identifiers = suite_runner.compute_selected_tests(
66        test_classes=[
67            integration_test.IntegrationTest, integration2_test.Integration2Test
68        ],
69        selected_tests=['IntegrationTest.test_a', 'IntegrationTest.test_b'])
70    self.assertEqual({integration_test.IntegrationTest: ['test_a', 'test_b']},
71                     identifiers)
72
73  def test_select_all_clobbers_method(self):
74    identifiers = suite_runner.compute_selected_tests(
75        test_classes=[
76            integration_test.IntegrationTest, integration2_test.Integration2Test
77        ],
78        selected_tests=['IntegrationTest.test_a', 'IntegrationTest'])
79    self.assertEqual({integration_test.IntegrationTest: None}, identifiers)
80
81    identifiers = suite_runner.compute_selected_tests(
82        test_classes=[
83            integration_test.IntegrationTest, integration2_test.Integration2Test
84        ],
85        selected_tests=['IntegrationTest', 'IntegrationTest.test_a'])
86    self.assertEqual({integration_test.IntegrationTest: None}, identifiers)
87
88  @mock.patch('sys.exit')
89  def test_run_suite(self, mock_exit):
90    tmp_file_path = os.path.join(self.tmp_dir, 'config.yml')
91    with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
92      f.write(u"""
93        TestBeds:
94          # A test bed where adb will find Android devices.
95          - Name: SampleTestBed
96            Controllers:
97              MagicDevice: '*'
98            TestParams:
99              icecream: 42
100              extra_param: 'haha'
101      """)
102    suite_runner.run_suite([integration_test.IntegrationTest],
103                           argv=['-c', tmp_file_path])
104    mock_exit.assert_not_called()
105
106  @mock.patch('sys.exit')
107  def test_run_suite_with_failures(self, mock_exit):
108    tmp_file_path = os.path.join(self.tmp_dir, 'config.yml')
109    with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
110      f.write(u"""
111        TestBeds:
112          # A test bed where adb will find Android devices.
113          - Name: SampleTestBed
114            Controllers:
115              MagicDevice: '*'
116      """)
117    suite_runner.run_suite([integration_test.IntegrationTest],
118                           argv=['-c', tmp_file_path])
119    mock_exit.assert_called_once_with(1)
120
121  @mock.patch('sys.exit')
122  @mock.patch.object(suite_runner, '_find_suite_class', autospec=True)
123  def test_run_suite_class(self, mock_find_suite_class, mock_exit):
124    mock_called = mock.MagicMock()
125
126    class FakeTestSuite(base_suite.BaseSuite):
127
128      def setup_suite(self, config):
129        mock_called.setup_suite()
130        super().setup_suite(config)
131        self.add_test_class(FakeTest1)
132
133      def teardown_suite(self):
134        mock_called.teardown_suite()
135        super().teardown_suite()
136
137    mock_find_suite_class.return_value = FakeTestSuite
138
139    tmp_file_path = os.path.join(self.tmp_dir, 'config.yml')
140    with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
141      f.write(u"""
142        TestBeds:
143          # A test bed where adb will find Android devices.
144          - Name: SampleTestBed
145            Controllers:
146              MagicDevice: '*'
147      """)
148
149    mock_cli_args = ['test_binary', f'--config={tmp_file_path}']
150
151    with mock.patch.object(sys, 'argv', new=mock_cli_args):
152      suite_runner.run_suite_class()
153
154    mock_find_suite_class.assert_called_once()
155    mock_called.setup_suite.assert_called_once_with()
156    mock_called.teardown_suite.assert_called_once_with()
157    mock_exit.assert_not_called()
158
159  def test_print_test_names(self):
160    mock_test_class = mock.MagicMock()
161    mock_cls_instance = mock.MagicMock()
162    mock_test_class.return_value = mock_cls_instance
163    suite_runner._print_test_names([mock_test_class])
164    mock_cls_instance._pre_run.assert_called_once()
165    mock_cls_instance._clean_up.assert_called_once()
166
167  def test_print_test_names_with_exception(self):
168    mock_test_class = mock.MagicMock()
169    mock_cls_instance = mock.MagicMock()
170    mock_test_class.return_value = mock_cls_instance
171    suite_runner._print_test_names([mock_test_class])
172    mock_cls_instance._pre_run.side_effect = Exception(
173        'Something went wrong.')
174    mock_cls_instance._clean_up.assert_called_once()
175
176
177if __name__ == "__main__":
178  unittest.main()
179