1# Lint as: python2, python3 2# Copyright 2017 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import logging 7 8from autotest_lib.client.bin import utils 9from autotest_lib.client.common_lib import error 10from autotest_lib.client.common_lib import lsbrelease_utils 11from autotest_lib.client.common_lib.cros import chrome 12from autotest_lib.client.cros.cellular import test_environment 13from autotest_lib.client.cros.update_engine import nebraska_wrapper 14from autotest_lib.client.cros.update_engine import update_engine_test 15 16class autoupdate_StartOOBEUpdate(update_engine_test.UpdateEngineTest): 17 """Starts a forced update at OOBE. 18 19 ChromeOS will restart when the update is complete so this test will just 20 start the update. The rest of the processing will be done in a server 21 side test. 22 """ 23 version = 1 24 25 26 def initialize(self): 27 """Test setup.""" 28 super(autoupdate_StartOOBEUpdate, self).initialize() 29 self._clear_custom_lsb_release() 30 31 32 def _navigate_to_oobe_update_screen(self): 33 """Navigates to the OOBE update check screen.""" 34 timeout = 30 35 self._oobe.WaitForJavaScriptCondition( 36 "typeof Oobe == 'function' && typeof OobeAPI == 'object' && " 37 "Oobe.readyForTesting", 38 timeout=timeout) 39 self._oobe.WaitForJavaScriptCondition( 40 "OobeAPI.screens.WelcomeScreen.isVisible()", timeout=timeout) 41 self._oobe.ExecuteJavaScript( 42 "OobeAPI.screens.WelcomeScreen.clickNext()") 43 44 if not self._oobe.EvaluateJavaScript( 45 "OobeAPI.screens.NetworkScreen.shouldSkip()"): 46 self._oobe.WaitForJavaScriptCondition( 47 "OobeAPI.screens.NetworkScreen.isVisible()", 48 timeout=timeout) 49 self._oobe.ExecuteJavaScript( 50 "OobeAPI.screens.NetworkScreen.clickNext()") 51 52 if not self._oobe.EvaluateJavaScript( 53 "OobeAPI.screens.EulaScreen.shouldSkip()"): 54 self._oobe.WaitForJavaScriptCondition( 55 "OobeAPI.screens.EulaScreen.isVisible()", timeout=timeout) 56 self._oobe.WaitForJavaScriptCondition( 57 "OobeAPI.screens.EulaScreen.nextButton.isEnabled()", 58 timeout=timeout) 59 self._oobe.ExecuteJavaScript( 60 "OobeAPI.screens.EulaScreen.clickNext()") 61 62 # TODO(yunkez): remove this check after M92 is in stable 63 if self._oobe.EvaluateJavaScript( 64 "typeof OobeAPI.screens.UpdateScreen == 'object'"): 65 self._oobe.WaitForJavaScriptCondition( 66 "OobeAPI.screens.UpdateScreen.isVisible()", 67 timeout=timeout) 68 else: 69 self._oobe.WaitForJavaScriptCondition("!$('oobe-update').hidden", 70 timeout=timeout) 71 72 def _start_oobe_update(self, update_url, critical_update): 73 """ 74 Jump to the update check screen at OOBE and wait for update to start. 75 76 @param update_url: The omaha update URL we expect to call. 77 @param critical_update: True if the update is critical. 78 79 """ 80 self._create_custom_lsb_release(update_url) 81 # Start chrome instance to interact with OOBE. 82 extra_browser_args = [] 83 if lsbrelease_utils.get_device_type() != 'CHROMEBOOK': 84 extra_browser_args.append('--disable-hid-detection-on-oobe') 85 self._chrome = chrome.Chrome(auto_login=False, 86 extra_browser_args=extra_browser_args) 87 self._oobe = self._chrome.browser.oobe 88 self._navigate_to_oobe_update_screen() 89 90 timeout = 180 91 err_str = 'Update did not start within %d seconds.' % timeout 92 try: 93 utils.poll_for_condition(self._is_update_started, 94 error.TestFail(err_str), 95 timeout=timeout) 96 except error.TestFail as e: 97 if critical_update: 98 if not self._get_update_requests(): 99 raise error.TestFail('%s There were no update requests in' 100 ' update_engine.log. OOBE update' 101 ' screen was missed.' % err_str) 102 err_code = self._get_last_error_string() 103 if err_code is not None: 104 raise error.TestFail('%s %s' % (err_str, err_code)) 105 else: 106 raise e 107 108 109 def run_once(self, 110 payload_url=None, 111 cellular=False, 112 critical_update=True, 113 full_payload=None, 114 interrupt_network=False, 115 interrupt_progress=0.0): 116 """ 117 Test that will start a forced update at OOBE. 118 119 @param payload_url: Payload url to pass to Nebraska. 120 @param cellular: True if we should run this test using a sim card. 121 @param critical_update: True if we should have deadline:now in omaha 122 response. 123 @param full_payload: Whether the payload is full or delta. None if we 124 don't have to care about it. 125 @param interrupt_network: True to cause a network interruption after 126 starting the update. Should only be used 127 during a critical update. 128 @param interrupt_progress: If interrupt_network is True, we will wait 129 for the update progress to reach this 130 value before interrupting. Should be 131 expressed as a number between 0 and 1. 132 133 """ 134 135 with nebraska_wrapper.NebraskaWrapper( 136 log_dir=self.resultsdir, 137 payload_url=payload_url, 138 persist_metadata=True) as nebraska: 139 140 config = { 141 'critical_update': critical_update, 142 'full_payload': full_payload 143 } 144 nebraska.update_config(**config) 145 update_url = nebraska.get_update_url() 146 # Create a nebraska config, which causes nebraska to start up before update_engine. 147 # This will allow nebraska to be up right after system startup so it can be used in interruption tests. 148 nebraska.create_startup_config(**config) 149 150 if not cellular: 151 self._start_oobe_update(update_url, critical_update) 152 if interrupt_network: 153 self._wait_for_progress(interrupt_progress) 154 self._take_screenshot(self._BEFORE_INTERRUPT_FILENAME) 155 completed = self._get_update_progress() 156 self._disconnect_reconnect_network_test() 157 self._take_screenshot(self._AFTER_INTERRUPT_FILENAME) 158 159 if self._is_update_engine_idle(): 160 raise error.TestFail( 161 'The update was IDLE after interrupt.') 162 if not self._update_continued_where_it_left_off(completed): 163 raise error.TestFail( 164 'The update did not continue where ' 165 'it left off after interruption.') 166 167 # Remove screenshots since the interrupt test succeeded. 168 self._remove_screenshots() 169 return 170 171 try: 172 with test_environment.CellularOTATestEnvironment() as test_env: 173 service = test_env.shill.wait_for_cellular_service_object() 174 if not service: 175 raise error.TestError('No cellular service found.') 176 connect_timeout = 120 177 test_env.shill.connect_service_synchronous(service, 178 connect_timeout) 179 180 self._start_oobe_update(update_url, critical_update) 181 182 # Set the nebraska startup config's no_update=True for the 183 # post-reboot update check, just in case we don't have time 184 # to server-side. 185 config['no_update'] = True 186 nebraska.create_startup_config(**config) 187 self._clear_custom_lsb_release() 188 189 # Need to return from this client test before OOBE reboots 190 # or the server test will hang. Cannot return immediately 191 # when the OOBE update starts because all code for cellular 192 # connections is client side and the test will switch to 193 # ethernet. So wait for FINALIZING so payload is downloaded 194 # via cellular and won't ping omaha again. After reboot, 195 # there is a final ping to omaha and login screen is shown. 196 self._wait_for_update_status( 197 self._UPDATE_STATUS_FINALIZING) 198 except error.TestError as e: 199 logging.error('Failure setting up sim card.') 200 raise error.TestFail(e) 201