def testWaitUntilComplete(self): """Test WaitUntilComplete returns False if background task isn't complete. As the background task is not started in this test, we expect it not to complete. """ op = operation.ProgressBarOperation() self.assertFalse(op.WaitUntilComplete(0))
def testCaptureOutputInBackground(self): """Test CaptureOutputInBackground puts finished in reasonable time.""" def func(): print('hi') op = operation.ProgressBarOperation() op.CaptureOutputInBackground(func) # This function should really finish in < 1 sec. However, we wait for a # longer time so the test does not fail on highly loaded builders. self.assertTrue(op.WaitUntilComplete(10))
def _VerifyProgressBar(self, width, percent, expected_shaded, expected_unshaded): """Helper to test progress bar with different percentages and lengths.""" terminal_width = width + ( operation.ProgressBarOperation._PROGRESS_BAR_BORDER_SIZE) self._terminal.return_value = operation._TerminalSize( 100, terminal_width) op = operation.ProgressBarOperation() with self.OutputCapturer() as output: op.ProgressBar(percent) stdout = output.GetStdout() # Check that the shaded and unshaded regions are the expected size. self.assertEqual(stdout.count('#'), expected_shaded) self.assertEqual(stdout.count('-'), expected_unshaded)
def UpdateRootfs(self): """Update the rootfs partition of the device (utilizing nebraska).""" logging.notice('Updating rootfs partition...') nebraska_bin = os.path.join(self.device_dev_dir, self.REMOTE_NEBRASKA_FILENAME) nebraska = nebraska_wrapper.RemoteNebraskaWrapper( self.device, nebraska_bin=nebraska_bin, update_payloads_address='file://' + self.device_payload_dir, update_metadata_dir=self.device_payload_dir) try: nebraska.Start() # Use the localhost IP address (default) to ensure that update engine # client can connect to the nebraska. nebraska_url = nebraska.GetURL(critical_update=True) cmd = [ self.REMOTE_UPDATE_ENGINE_BIN_FILENAME, '--check_for_update', '--omaha_url="%s"' % nebraska_url ] self.device.run(cmd, **self._cmd_kwargs) # If we are using a progress bar, update it every 0.5s instead of 10s. if command.UseProgressBar(): update_check_interval = self.UPDATE_CHECK_INTERVAL_PROGRESSBAR oper = operation.ProgressBarOperation() else: update_check_interval = self.UPDATE_CHECK_INTERVAL_NORMAL oper = None end_message_not_printed = True # Loop until update is complete. while True: # Number of times to retry `update_engine_client --status`. See # crbug.com/744212. update_engine_status_retry = 30 op, progress = retry_util.RetryException( cros_build_lib.RunCommandError, update_engine_status_retry, self.GetUpdateStatus, self.device, ['CURRENT_OP', 'PROGRESS'], delay_sec=DELAY_SEC_FOR_RETRY)[0:2] logging.info('Waiting for update...status: %s at progress %s', op, progress) if op == UPDATE_STATUS_UPDATED_NEED_REBOOT: logging.info('Update completed.') break if op == UPDATE_STATUS_IDLE: # Something went wrong. Try to get last error code. cmd = ['cat', self.REMOTE_UPDATE_ENGINE_LOGFILE_PATH] log = self.device.run(cmd).stdout.strip().splitlines() err_str = 'Updating payload state for error code: ' targets = [line for line in log if err_str in line] logging.debug('Error lines found: %s', targets) if not targets: raise RootfsUpdateError( 'Update failed with unexpected update status: %s' % op) else: # e.g 20 (ErrorCode::kDownloadStateInitializationError) raise RootfsUpdateError( targets[-1].rpartition(err_str)[2]) if oper is not None: if op == UPDATE_STATUS_DOWNLOADING: oper.ProgressBar(float(progress)) elif end_message_not_printed and op == UPDATE_STATUS_FINALIZING: oper.Cleanup() logging.info('Finalizing image.') end_message_not_printed = False time.sleep(update_check_interval) # TODO(ahassani): Scope the Exception to finer levels. For example we don't # need to revert the boot partition if the Nebraska fails to start, etc. except Exception as e: logging.error('Rootfs update failed %s', e) self.RevertBootPartition() logging.warning(nebraska.PrintLog() or 'No nebraska log is available.') raise RootfsUpdateError('Failed to perform rootfs update: %r' % e) finally: nebraska.Stop() nebraska.CollectLogs( os.path.join(self.tempdir, self.LOCAL_NEBRASKA_LOG_FILENAME)) self.device.CopyFromDevice( self.REMOTE_UPDATE_ENGINE_LOGFILE_PATH, os.path.join( self.tempdir, os.path.basename(self.REMOTE_UPDATE_ENGINE_LOGFILE_PATH)), follow_symlinks=True, **self._cmd_kwargs_omit_error)
def UpdateRootfs(self): """Update the rootfs partition of the device.""" devserver_bin = os.path.join(self.device_dev_dir, self.DEVSERVER_FILENAME) ds = ds_wrapper.RemoteDevServerWrapper( self.device, devserver_bin, static_dir=self.device_static_dir, log_dir=self.device.work_dir) logging.info('Updating rootfs partition') try: ds.Start() # Use the localhost IP address to ensure that update engine # client can connect to the devserver. omaha_url = ds.GetDevServerURL(ip='127.0.0.1', port=ds.port, sub_dir='update/pregenerated') cmd = [ self.UPDATE_ENGINE_BIN, '-check_for_update', '-omaha_url=%s' % omaha_url ] self.device.RunCommand(cmd) # If we are using a progress bar, update it every 0.5s instead of 10s. if command.UseProgressBar(): update_check_interval = self.UPDATE_CHECK_INTERVAL_PROGRESSBAR oper = operation.ProgressBarOperation() else: update_check_interval = self.UPDATE_CHECK_INTERVAL_NORMAL oper = None end_message_not_printed = True # Loop until update is complete. while True: op, progress = self.GetUpdateStatus(self.device, ['CURRENT_OP', 'PROGRESS']) logging.info('Waiting for update...status: %s at progress %s', op, progress) if op == UPDATE_STATUS_UPDATED_NEED_REBOOT: logging.notice('Update completed.') break if op == UPDATE_STATUS_IDLE: raise RootfsUpdateError( 'Update failed with unexpected update status: %s' % op) if oper is not None: if op == UPDATE_STATUS_DOWNLOADING: oper.ProgressBar(float(progress)) elif end_message_not_printed and op == UPDATE_STATUS_FINALIZING: oper.Cleanup() logging.notice('Finalizing image.') end_message_not_printed = False time.sleep(update_check_interval) ds.Stop() except Exception as e: logging.error('Rootfs update failed.') logging.warning(ds.TailLog() or 'No devserver log is available.') error_msg = 'Failed to perform rootfs update: %r' raise RootfsUpdateError(error_msg % e) finally: ds.Stop() self.device.CopyFromDevice(ds.log_file, os.path.join(self.tempdir, self.DEVSERVER_LOG), error_code_ok=True) self.device.CopyFromDevice(self.UPDATE_ENGINE_LOG, self.tempdir, follow_symlinks=True, error_code_ok=True)