1# Copyright (c) 2012 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 os 7 8from autotest_lib.client.common_lib.cros import kernel_utils 9from autotest_lib.client.cros import constants 10from autotest_lib.server import afe_utils 11from autotest_lib.server.cros import provisioner 12from autotest_lib.server.cros.update_engine import update_engine_test 13 14 15class autoupdate_EndToEndTest(update_engine_test.UpdateEngineTest): 16 """Complete update test between two Chrome OS releases. 17 18 Performs an end-to-end test of updating a ChromeOS device from one version 19 to another. The test performs the following steps: 20 21 - Stages the source (full) and target update payloads on a devserver. 22 - Installs source image on the DUT (if provided) and reboots to it. 23 - Verifies that sign in works correctly on the source image. 24 - Installs target image on the DUT and reboots. 25 - Does a final update check. 26 - Verifies that sign in works correctly on the target image. 27 - Returns the hostlogs collected during each update check for 28 verification against expected update events. 29 30 This class interacts with several others: 31 UpdateEngineTest: base class for comparing expected update events against 32 the events listed in the hostlog. 33 UpdateEngineEvent: class representing a single expected update engine event. 34 35 """ 36 version = 1 37 38 _LOGIN_TEST = 'login_LoginSuccess' 39 40 41 def cleanup(self): 42 """Save the logs from stateful_partition's preserved/log dir.""" 43 stateful_preserved_logs = os.path.join(self.resultsdir, 44 '~stateful_preserved_logs') 45 os.makedirs(stateful_preserved_logs) 46 self._host.get_file(constants.AUTOUPDATE_PRESERVE_LOG, 47 stateful_preserved_logs, safe_symlinks=True, 48 preserve_perm=False) 49 super(autoupdate_EndToEndTest, self).cleanup() 50 51 52 def _print_rerun_command(self, test_conf): 53 """Prints the command to rerun a test run from the lab at your desk.""" 54 logging.debug('Rerun this test run at your desk using this command:') 55 rerun_cmd = ('test_that <DUT NAME>.cros autoupdate_EndToEndTest ' 56 '--args="update_type=%s source_release=%s ' 57 'source_payload_uri=%s target_release=%s ' 58 'target_payload_uri=%s"') 59 rerun_cmd = rerun_cmd % ( 60 test_conf['update_type'], test_conf['source_release'], 61 test_conf['source_payload_uri'], test_conf['target_release'], 62 test_conf['target_payload_uri']) 63 logging.debug(rerun_cmd) 64 65 def run_update_test(self, test_conf): 66 """Runs the update test and checks it succeeded. 67 68 @param test_conf: A dictionary containing test configuration values. 69 70 """ 71 # Record the active root partition. 72 active, inactive = kernel_utils.get_kernel_state(self._host) 73 logging.info('Source active slot: %s', active) 74 75 source_release = test_conf['source_release'] 76 target_release = test_conf['target_release'] 77 78 self.update_device(test_conf['target_payload_uri'], tag='target') 79 80 # Compare hostlog events from the update to the expected ones. 81 rootfs, reboot = self._create_hostlog_files() 82 self.verify_update_events(source_release, rootfs) 83 self.verify_update_events(source_release, reboot, target_release) 84 kernel_utils.verify_boot_expectations(inactive, host=self._host) 85 logging.info('Update successful, test completed') 86 87 88 def run_once(self, test_conf): 89 """Performs a complete auto update test. 90 91 @param test_conf: a dictionary containing test configuration values. 92 93 """ 94 logging.debug('The test configuration supplied: %s', test_conf) 95 self._print_rerun_command(test_conf) 96 self._autotest_devserver = self._get_devserver_for_test(test_conf) 97 98 afe_utils.clean_provision_labels(self._host) 99 100 # Install source image with quick-provision. 101 source_payload_uri = test_conf['source_payload_uri'] 102 if source_payload_uri: 103 build_name, _ = self._get_update_parameters_from_uri( 104 source_payload_uri) 105 update_url = self._autotest_devserver.get_update_url( 106 build_name) 107 logging.info('Installing source image with update url: %s', 108 update_url) 109 110 provisioner.ChromiumOSProvisioner( 111 update_url, host=self._host, 112 is_release_bucket=True).run_provision() 113 114 self._run_client_test_and_check_result(self._LOGIN_TEST, 115 tag='source') 116 # Start the update to the target image. 117 self._stage_payloads(test_conf['target_payload_uri'], 118 test_conf['target_archive_uri']) 119 self.run_update_test(test_conf) 120 121 # Check we can login after the update. 122 self._run_client_test_and_check_result(self._LOGIN_TEST, tag='target') 123