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