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