1# Copyright 2018 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6import random 7import urlparse 8 9from autotest_lib.client.common_lib import error 10from autotest_lib.client.common_lib import utils 11from autotest_lib.server.cros.update_engine import update_engine_test 12 13class autoupdate_Interruptions(update_engine_test.UpdateEngineTest): 14 """Ensures an update completes with multiple user interruptions.""" 15 version = 1 16 17 def cleanup(self): 18 self._save_extra_update_engine_logs(4) 19 super(autoupdate_Interruptions, self).cleanup() 20 21 22 def run_once(self, full_payload=True, interrupt=None, job_repo_url=None): 23 """ 24 Runs an update with interruptions from the user. 25 26 @param full_payload: True for a full payload. False for delta. 27 @param interrupt: The interrupt to perform: [reboot, network, suspend]. 28 @param job_repo_url: Used for debugging locally. This is used to figure 29 out the current build and the devserver to use. 30 The test will read this from a host argument 31 when run in the lab. 32 33 """ 34 35 update_url = self.get_update_url_for_test(job_repo_url, 36 full_payload=full_payload, 37 critical_update=True) 38 chromeos_version = self._get_chromeos_version() 39 40 # Choose a random downloaded progress to interrupt the update. 41 progress = random.uniform(0.1, 0.6) 42 logging.info('Progress when we will begin interruptions: %f', progress) 43 44 parsed_url = urlparse.urlparse(update_url) 45 server = 'http://%s' % parsed_url.hostname 46 # Login, start the update, logout 47 self._run_client_test_and_check_result( 48 'autoupdate_LoginStartUpdateLogout', server=server, 49 port=parsed_url.port, progress_to_complete=progress) 50 51 if interrupt is not None: 52 if self._is_update_finished_downloading(): 53 raise error.TestFail('Update finished before interrupt' 54 'started.') 55 completed = self._get_update_progress() 56 if interrupt is 'reboot': 57 self._host.reboot() 58 utils.poll_for_condition(self._get_update_engine_status, 59 desc='update engine to start') 60 self._check_for_update(server=server, port=parsed_url.port) 61 elif interrupt is 'network': 62 self._disconnect_then_reconnect_network(update_url) 63 elif interrupt is 'suspend': 64 self._suspend_then_resume() 65 else: 66 raise error.TestFail('Unknown interrupt type: %s' % interrupt) 67 if self._is_update_engine_idle(): 68 raise error.TestFail('The update was IDLE after interrupt.') 69 if not self._update_continued_where_it_left_off(completed): 70 raise error.TestFail('The update did not continue where it ' 71 'left off after interruption.') 72 73 # Add a new user and crash browser. 74 self._run_client_test_and_check_result( 75 'autoupdate_CrashBrowserAfterUpdate') 76 77 # Update is complete. Reboot the device. 78 self._host.reboot() 79 utils.poll_for_condition(self._get_update_engine_status, 80 desc='update engine to start') 81 # We do check update with no_update=True so it doesn't start the update 82 # again. 83 self._check_for_update(server=server, port=parsed_url.port, 84 no_update=True) 85 86 # Verify that the update completed successfully by checking hostlog. 87 rootfs_hostlog, reboot_hostlog = self._create_hostlog_files() 88 self.verify_update_events(chromeos_version, rootfs_hostlog) 89 self.verify_update_events(chromeos_version, reboot_hostlog, 90 chromeos_version) 91