1# Lint as: python2, python3 2# Copyright (c) 2013 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 7import os 8 9from autotest_lib.client.common_lib import error 10from autotest_lib.client.common_lib.cros import kernel_utils 11from autotest_lib.server.cros.update_engine import update_engine_test 12 13POWERWASH_COMMAND = 'safe fast keepimg' 14POWERWASH_MARKER_FILE = '/mnt/stateful_partition/factory_install_reset' 15STATEFUL_MARKER_FILE = '/mnt/stateful_partition/autoupdate_Rollback_flag' 16 17class autoupdate_Rollback(update_engine_test.UpdateEngineTest): 18 """Test that updates the machine and performs rollback.""" 19 version = 1 20 21 def _powerwash(self): 22 """Powerwashes DUT.""" 23 logging.info('Powerwashing device before rollback.') 24 self._host.run(['echo', 'car', '>', STATEFUL_MARKER_FILE]) 25 self._host.run(['echo', "'%s'" % POWERWASH_COMMAND, '>', 26 POWERWASH_MARKER_FILE]) 27 self._host.reboot() 28 marker = self._host.run(['test', '-e', STATEFUL_MARKER_FILE], 29 ignore_status=True, ignore_timeout=True) 30 if marker is None or marker.exit_status == 0: 31 raise error.TestFail("Powerwash cycle didn't remove the marker " 32 "file on the stateful partition.") 33 34 35 def cleanup(self): 36 """Clean up test state.""" 37 # Save update_engine logs for the update, rollback, and post-reboot. 38 self._save_extra_update_engine_logs(number_of_logs=3) 39 40 # Restore the stateful partition so tests can still use this DUT. 41 if self._powerwash_attempted: 42 self._restore_stateful() 43 44 # Delete rollback-version and rollback-happened pref which are 45 # generated during Rollback and Enterprise Rollback. 46 # rollback-version is written when update_engine Rollback D-Bus API is 47 # called. The existence of rollback-version prevents update_engine to 48 # apply payload whose version is the same as rollback-version. 49 # rollback-happened is written when update_engine finished Enterprise 50 # Rollback operation. 51 preserved_prefs_path = ('/mnt/stateful_partition/unencrypted/preserve' 52 '/update_engine/prefs/') 53 self._host.run( 54 ['rm', os.path.join(preserved_prefs_path, 'rollback-version'), 55 os.path.join(preserved_prefs_path, 'rollback-happened')], 56 ignore_status=True) 57 # Restart update-engine to pick up new prefs. 58 self._restart_update_engine(ignore_status=True) 59 60 61 def run_once(self, job_repo_url=None, powerwash_before_rollback=False): 62 """Runs the test. 63 64 @param job_repo_url: URL to get the image. 65 @param powerwash_before_rollback: True if we should rollback before 66 powerwashing. 67 68 @raise error.TestError if anything went wrong with setting up the test; 69 error.TestFail if any part of the test has failed. 70 71 """ 72 self._powerwash_attempted = False 73 payload_url = self.get_payload_for_nebraska(job_repo_url) 74 active, inactive = kernel_utils.get_kernel_state(self._host) 75 logging.info('Initial device state: active kernel %s, ' 76 'inactive kernel %s.', active, inactive) 77 78 logging.info('Performing an update.') 79 self._run_client_test_and_check_result('autoupdate_CannedOmahaUpdate', 80 payload_url=payload_url) 81 self._host.reboot() 82 # Ensure the update completed successfully. 83 rootfs_hostlog, _ = self._create_hostlog_files() 84 self.verify_update_events(self._FORCED_UPDATE, rootfs_hostlog) 85 # We should be booting from the new partition. 86 error_msg = 'Failed to set up test by updating DUT.' 87 kernel_utils.verify_boot_expectations(inactive, error_msg, self._host) 88 89 if powerwash_before_rollback: 90 self._powerwash_attempted = True 91 self._powerwash() 92 93 logging.info('Update verified, initiating rollback.') 94 # Powerwash is tested separately from rollback. 95 self._rollback(powerwash=False) 96 self._host.reboot() 97 98 # We should be back on our initial partition. 99 error_msg = ('Autoupdate reported that rollback succeeded but we ' 100 'did not boot into the correct partition.') 101 kernel_utils.verify_boot_expectations(active, error_msg, self._host) 102 logging.info('We successfully rolled back to initial kernel.') 103