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
7from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
8from autotest_lib.client.common_lib import error
9
10
11class firmware_UpdateKernelDataKeyVersion(FirmwareTest):
12    """
13    This test should run in developer mode. On runtime, this test modifies the
14    kernel data key version of kernel b and modifies cgpt to reboot with kernel
15    b. Check kernel data key version after reboot, and then recover kernel b's
16    data key version to original version. Here also tries to reboot with kernel
17    b after recovery. If sccuess, reboot with kernel a.
18    """
19    version = 1
20
21    def check_kernel_datakey_version(self, expected_ver):
22        actual_ver = self.faft_client.kernel.get_datakey_version('b')
23        if actual_ver != expected_ver:
24            raise error.TestFail(
25                'Kernel Version should be %s, but got %s.'
26                % (expected_ver, actual_ver))
27        else:
28            logging.info(
29                'Update success, now version is %s',
30                actual_ver)
31
32    def resign_kernel_datakey_version(self, host):
33        host.send_file(os.path.join(self.bindir,
34                                    'files/common.sh'),
35                       os.path.join(self.faft_client.updater.get_temp_path(),
36                                     'common.sh'))
37        host.send_file(os.path.join(self.bindir,
38                                    'files/make_keys.sh'),
39                       os.path.join(self.faft_client.updater.get_temp_path(),
40                                    'make_keys.sh'))
41
42        self.faft_client.system.run_shell_command('/bin/bash %s %s' % (
43            os.path.join(self.faft_client.updater.get_temp_path(),
44                         'make_keys.sh'),
45            self._update_version))
46
47    def modify_kernel_b_and_set_cgpt_priority(self, delta, target_dev):
48        if delta == 1:
49            self.faft_client.kernel.resign_with_keys(
50                'b', self.faft_client.updater.get_keys_path())
51        elif delta == -1:
52            self.check_kernel_datakey_version(self._update_version)
53            self.faft_client.kernel.resign_with_keys('b')
54
55        if target_dev == 'a':
56            self.reset_and_prioritize_kernel('a')
57        else:
58            self.reset_and_prioritize_kernel('b')
59
60    def initialize(self, host, cmdline_args, dev_mode=True):
61        super(firmware_UpdateKernelDataKeyVersion, self).initialize(host,
62                                                                cmdline_args)
63
64        self.switcher.setup_mode('dev' if dev_mode else 'normal')
65
66        actual_ver = self.faft_client.kernel.get_datakey_version('b')
67        logging.info('Original Kernel Version of KERN-B is %s', actual_ver)
68
69        self._update_version = actual_ver + 1
70        logging.info('KERN-B will update to version %s', self._update_version)
71
72        self.setup_kernel('a')
73        self.resign_kernel_datakey_version(host)
74
75    def cleanup(self):
76        self.faft_client.updater.cleanup()
77        super(firmware_UpdateKernelDataKeyVersion, self).cleanup()
78
79    def run_once(self):
80        logging.info("Update Kernel Data Key Version.")
81        self.check_state((self.check_root_part_on_non_recovery, 'a'))
82        self.modify_kernel_b_and_set_cgpt_priority(1, 'b')
83        self.switcher.mode_aware_reboot()
84
85        logging.info("Check kernel data key version and rollback.")
86        self.check_state((self.check_root_part_on_non_recovery, 'b'))
87        self.modify_kernel_b_and_set_cgpt_priority(-1, 'b')
88        self.switcher.mode_aware_reboot()
89
90        logging.info("Boot with rollback kernel and change boot priority.")
91        self.check_state((self.check_root_part_on_non_recovery, 'b'))
92        self.modify_kernel_b_and_set_cgpt_priority(0, 'a')
93        self.switcher.mode_aware_reboot()
94
95        logging.info("Check rollback version.")
96        self.check_state((self.check_root_part_on_non_recovery, 'a'))
97        self.check_kernel_datakey_version(self._update_version - 1)
98