• 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
17import unittest
18import mock
19import os
20
21from acts.libs.ota.ota_tools import ota_tool
22from acts.libs.ota.ota_runners import ota_runner
23from acts.controllers import android_device
24
25
26class MockOtaTool(ota_tool.OtaTool):
27    def __init__(self, command):
28        super(MockOtaTool, self).__init__(command)
29        self.update_call_count = 0
30        self.cleanup_call_count = 0
31
32    def update(self, unused):
33        self.update_call_count += 1
34
35    def cleanup(self, unused):
36        self.cleanup_call_count += 1
37
38    def reset_count(self):
39        self.update_call_count = 0
40        self.cleanup_call_count = 0
41
42    def assert_calls_equal(self, test, number_of_expected_calls):
43        test.assertEqual(number_of_expected_calls, self.update_call_count)
44        test.assertEqual(number_of_expected_calls, self.cleanup_call_count)
45
46
47class OtaRunnerImpl(ota_runner.OtaRunner):
48    """Sets properties to return an empty string to allow OtaRunner tests."""
49
50    def get_sl4a_apk(self):
51        return ''
52
53    def get_ota_package(self):
54        return ''
55
56    def validate_update(self):
57        pass
58
59
60class OtaRunnerTest(unittest.TestCase):
61    """Tests the OtaRunner class."""
62
63    def setUp(self):
64        self.prev_sl4a_service_setup_time = ota_runner.SL4A_SERVICE_SETUP_TIME
65        ota_runner.SL4A_SERVICE_SETUP_TIME = 0
66
67    def tearDown(self):
68        ota_runner.SL4A_SERVICE_SETUP_TIME = self.prev_sl4a_service_setup_time
69
70    def test_update(self):
71        device = mock.MagicMock()
72        device.skip_sl4a = False
73        tool = MockOtaTool('mock_command')
74        runner = OtaRunnerImpl(tool, device)
75        runner.android_device.adb.getprop = mock.Mock(side_effect=['a', 'b'])
76        runner.get_post_build_id = lambda: 'abc'
77
78        runner._update()
79
80        self.assertTrue(device.stop_services.called)
81        self.assertTrue(device.wait_for_boot_completion.called)
82        self.assertTrue(device.start_services.called)
83        self.assertTrue(device.adb.install.called)
84        tool.assert_calls_equal(self, 1)
85
86    def test_update_fail_on_no_change_to_build(self):
87        device = mock.MagicMock()
88        tool = MockOtaTool('mock_command')
89        runner = OtaRunnerImpl(tool, device)
90        runner.android_device.adb.getprop = mock.Mock(side_effect=['a', 'a'])
91        runner.get_post_build_id = lambda: 'abc'
92        try:
93            runner._update()
94            self.fail('Matching build fingerprints did not throw an error!')
95        except ota_runner.OtaError:
96            pass
97
98    def test_init(self):
99        device = mock.MagicMock()
100        tool = MockOtaTool('mock_command')
101        runner = ota_runner.OtaRunner(tool, device)
102
103        self.assertEqual(runner.ota_tool, tool)
104        self.assertEqual(runner.android_device, device)
105        self.assertEqual(runner.serial, device.serial)
106
107    def test_get_post_build_id_grabs_valid_data(self):
108        device = mock.MagicMock()
109        tool = MockOtaTool('mock_command')
110        runner = OtaRunnerImpl(tool, device)
111        ota_package_path = os.path.join(
112            os.path.dirname(os.path.dirname(os.path.realpath(__file__))),
113            'dummy_ota_package.zip')
114        runner.get_ota_package = lambda: ota_package_path
115        self.assertEqual(runner.get_post_build_id(), 'post-build_information')
116
117    def test_get_ota_package_metadata_value_does_not_exist(self):
118        device = mock.MagicMock()
119        tool = MockOtaTool('mock_command')
120        runner = OtaRunnerImpl(tool, device)
121        ota_package_path = os.path.join(
122            os.path.dirname(os.path.dirname(os.path.realpath(__file__))),
123            'dummy_ota_package.zip')
124        runner.get_ota_package = lambda: ota_package_path
125        self.assertEqual(runner.get_ota_package_metadata('garbage-data'), None)
126
127
128class SingleUseOtaRunnerTest(unittest.TestCase):
129    """Tests the SingleUseOtaRunner class."""
130
131    def setUp(self):
132        self.device = mock.MagicMock()
133        self.tool = MockOtaTool('mock_command')
134
135    def test_update_first_update_runs(self):
136        runner = ota_runner.SingleUseOtaRunner(self.tool, self.device, '', '')
137        try:
138            with mock.patch.object(ota_runner.OtaRunner, '_update'):
139                runner.update()
140        except ota_runner.OtaError:
141            self.fail('SingleUseOtaRunner threw an exception on the first '
142                      'update call.')
143
144    def test_update_second_update_raises_error(self):
145        runner = ota_runner.SingleUseOtaRunner(self.tool, self.device, '', '')
146        with mock.patch.object(ota_runner.OtaRunner, '_update'):
147            runner.update()
148            try:
149                runner.update()
150            except ota_runner.OtaError:
151                return
152        self.fail('SingleUseOtaRunner did not throw an exception on the second'
153                  'update call.')
154
155    def test_can_update_no_updates_called(self):
156        runner = ota_runner.SingleUseOtaRunner(self.tool, self.device, '', '')
157        self.assertEqual(True, runner.can_update())
158
159    def test_can_update_has_updated_already(self):
160        runner = ota_runner.SingleUseOtaRunner(self.tool, self.device, '', '')
161        with mock.patch.object(ota_runner.OtaRunner, '_update'):
162            runner.update()
163        self.assertEqual(False, runner.can_update())
164
165    def test_get_ota_package(self):
166        runner = ota_runner.SingleUseOtaRunner(self.tool, self.device, 'a',
167                                               'b')
168        self.assertEqual(runner.get_ota_package(), 'a')
169
170    def test_get_sl4a_apk(self):
171        runner = ota_runner.SingleUseOtaRunner(self.tool, self.device, 'a',
172                                               'b')
173        self.assertEqual(runner.get_sl4a_apk(), 'b')
174
175
176class MultiUseOtaRunnerTest(unittest.TestCase):
177    """Tests the MultiUseOtaRunner class."""
178
179    def setUp(self):
180        self.device = mock.MagicMock()
181        self.tool = MockOtaTool('mock_command')
182
183    def test_update_first_update_runs(self):
184        runner = ota_runner.MultiUseOtaRunner(self.tool, self.device, [''],
185                                              [''])
186        try:
187            with mock.patch.object(ota_runner.OtaRunner, '_update'):
188                runner.update()
189        except ota_runner.OtaError:
190            self.fail('MultiUseOtaRunner threw an exception on the first '
191                      'update call.')
192
193    def test_update_multiple_updates_run(self):
194        runner = ota_runner.MultiUseOtaRunner(self.tool, self.device,
195                                              ['first_pkg', 'second_pkg'],
196                                              ['first_apk', 'second_apk'])
197        with mock.patch.object(ota_runner.OtaRunner, '_update'):
198            runner.update()
199            try:
200                runner.update()
201            except ota_runner.OtaError:
202                self.fail('MultiUseOtaRunner threw an exception before '
203                          'running out of update packages.')
204
205    def test_update_too_many_update_calls_raises_error(self):
206        runner = ota_runner.MultiUseOtaRunner(self.tool, self.device,
207                                              ['first_pkg', 'second_pkg'],
208                                              ['first_apk', 'second_apk'])
209        with mock.patch.object(ota_runner.OtaRunner, '_update'):
210            runner.update()
211            runner.update()
212            try:
213                runner.update()
214            except ota_runner.OtaError:
215                return
216        self.fail('MultiUseOtaRunner did not throw an exception after running '
217                  'out of update packages.')
218
219    def test_can_update_no_updates_called(self):
220        runner = ota_runner.MultiUseOtaRunner(self.tool, self.device,
221                                              ['first_pkg', 'second_pkg'],
222                                              ['first_apk', 'second_apk'])
223        self.assertEqual(True, runner.can_update())
224
225    def test_can_update_has_more_updates_left(self):
226        runner = ota_runner.MultiUseOtaRunner(self.tool, self.device,
227                                              ['first_pkg', 'second_pkg'],
228                                              ['first_apk', 'second_apk'])
229        with mock.patch.object(ota_runner.OtaRunner, '_update'):
230            runner.update()
231        self.assertEqual(True, runner.can_update())
232
233    def test_can_update_ran_out_of_updates(self):
234        runner = ota_runner.MultiUseOtaRunner(self.tool, self.device,
235                                              ['first_pkg', 'second_pkg'],
236                                              ['first_apk', 'second_apk'])
237        with mock.patch.object(ota_runner.OtaRunner, '_update'):
238            runner.update()
239            runner.update()
240        self.assertEqual(False, runner.can_update())
241
242    def test_get_ota_package(self):
243        runner = ota_runner.MultiUseOtaRunner(self.tool, self.device,
244                                              ['first_pkg', 'second_pkg'],
245                                              ['first_apk', 'second_apk'])
246        self.assertEqual(runner.get_ota_package(), 'first_pkg')
247
248    def test_get_sl4a_apk(self):
249        runner = ota_runner.MultiUseOtaRunner(self.tool, self.device,
250                                              ['first_pkg', 'second_pkg'],
251                                              ['first_apk', 'second_apk'])
252        self.assertEqual(runner.get_sl4a_apk(), 'first_apk')
253
254
255if __name__ == '__main__':
256    unittest.main()
257