xref: /aosp_15_r20/external/autotest/server/site_tests/autoupdate_MiniOS/autoupdate_MiniOS.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Lint as: python3
2# Copyright 2022 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
7
8from autotest_lib.client.common_lib import error
9from autotest_lib.client.common_lib.cros import kernel_utils
10from autotest_lib.server.cros.minios import minios_test
11
12
13class autoupdate_MiniOS(minios_test.MiniOsTest):
14    """Tests MiniOS update. """
15
16    version = 1
17
18    _EXCLUSION_PREFS_DIR = "exclusion"
19    _MINIOS_PREFS_DIR = "minios"
20
21    def initialize(self, host=None):
22        """
23        Clear test related prefs on the DUT before starting the test.
24
25        """
26        super(autoupdate_MiniOS, self).initialize(host=host)
27        self._remove_minios_update_prefs()
28
29    def cleanup(self):
30        super(autoupdate_MiniOS, self).cleanup()
31        self._save_extra_update_engine_logs(number_of_logs=2)
32        self._remove_minios_update_prefs()
33
34    def _remove_minios_update_prefs(self):
35        for pref in ((self._EXCLUSION_PREFS_DIR, True),
36                     (self._MINIOS_PREFS_DIR, True)):
37            self._remove_update_engine_pref(pref=pref[0], is_dir=pref[1])
38
39    def _setup_minios_update(self, has_update, with_exclusion=False):
40        # Get payload URL for the MiniOS update.
41        # We'll always need a full payload for MiniOS update.
42        payload_url = self.get_payload_for_nebraska(
43                job_repo_url=self._job_repo_url,
44                full_payload=True,
45                payload_type=self._PAYLOAD_TYPE.MINIOS,
46                public_bucket=self._running_at_desk)
47        self._payload_urls.append(payload_url)
48
49        # Test that MiniOS payload can be excluded by creating a pref file.
50        # This simulates that the update engine tries to exclude MiniOS payload
51        # after getting certain types of MiniOS update failure.
52        if with_exclusion:
53            self._create_update_engine_pref(
54                    pref_name=self._get_exclusion_name(payload_url),
55                    sub_dir=self._EXCLUSION_PREFS_DIR)
56
57        # MiniOS booting to be verified.
58        if has_update:
59            self._verifications.append(self._boot_minios)
60
61    def _setup_cros_update(self, has_update):
62        if has_update:
63            # Get payload URL for the platform (OS) update.
64            self._payload_urls.append(
65                    self.get_payload_for_nebraska(
66                            job_repo_url=self._job_repo_url,
67                            full_payload=self._full_payload,
68                            public_bucket=self._running_at_desk))
69
70        # Platform (OS) update to be verified.
71        self._verifications.append(lambda: self._verify_cros_update(
72                updated=has_update))
73
74    def _setup_dlc_update(self):
75        # Payload URLs for sample-dlc, a test DLC package.
76        # We'll always need a full payload for DLC installation,
77        # and optionally a delta payload if required by the test.
78        self._payload_urls.append(
79                self.get_payload_for_nebraska(
80                        job_repo_url=self._job_repo_url,
81                        full_payload=True,
82                        payload_type=self._PAYLOAD_TYPE.DLC,
83                        public_bucket=self._running_at_desk))
84        if not self._full_payload:
85            self._payload_urls.append(
86                    self.get_payload_for_nebraska(
87                            job_repo_url=self._job_repo_url,
88                            full_payload=False,
89                            payload_type=self._PAYLOAD_TYPE.DLC,
90                            public_bucket=self._running_at_desk))
91
92        # DLC update to be verified.
93        self._verifications.append(self._verify_dlc_update)
94
95    def _verify_cros_update(self, updated):
96        if updated:
97            # Verify the platform (OS) update completed successfully.
98            kernel_utils.verify_boot_expectations(self._inactive_cros,
99                                                  host=self._host)
100            rootfs_hostlog, _ = self._create_hostlog_files()
101            self.verify_update_events(self._FORCED_UPDATE, rootfs_hostlog)
102        else:
103            # Verify the Platform (OS) boot expectation unchanged.
104            kernel_utils.verify_boot_expectations(self._active_cros,
105                                                  host=self._host)
106
107    def _verify_dlc_update(self):
108        # Verify the DLC update completed successfully.
109        dlc_rootfs_hostlog, _ = self._create_dlc_hostlog_files()
110        logging.info('Checking DLC update events')
111        self.verify_update_events(
112                self._FORCED_UPDATE,
113                dlc_rootfs_hostlog[self._dlc_util._SAMPLE_DLC_ID])
114        # Verify the DLC was successfully installed.
115        self._dlc_util.remove_preloaded(self._dlc_util._SAMPLE_DLC_ID)
116        self._dlc_util.install(self._dlc_util._SAMPLE_DLC_ID,
117                               omaha_url='fake_url')
118        if not self._dlc_util.is_installed(self._dlc_util._SAMPLE_DLC_ID):
119            raise error.TestFail('Test DLC was not installed.')
120
121    def run_once(self,
122                 full_payload=True,
123                 job_repo_url=None,
124                 with_os=False,
125                 with_dlc=False,
126                 with_exclusion=False,
127                 running_at_desk=False):
128        """
129        Tests that we can successfully update MiniOS along with the OS.
130
131        @param full_payload: True for full OS and DLC payloads. False for delta.
132        @param job_repo_url: This is used to figure out the current build and
133                             the devserver to use. The test will read this
134                             from a host argument when run in the lab.
135        @param with_os: True for MiniOS update along with Platform (OS)
136                             update. False for MiniOS only update.
137        @param with_dlc: True for MiniOS update with Platform (OS) and DLC.
138                             False for turning off DLC update.
139        @param with_exclusion: True for excluding MiniOS payload.
140        @param running_at_desk: Indicates test is run locally from a
141                                workstation.
142
143        """
144        self._full_payload = full_payload
145        self._job_repo_url = job_repo_url
146        self._running_at_desk = running_at_desk
147
148        if not with_os and with_dlc:
149            logging.info("DLC only updates with the platform (OS), "
150                         "automatically set with_os to True.")
151            with_os = True
152
153        # Record DUT state before the update.
154        self._active_cros, self._inactive_cros \
155            = kernel_utils.get_kernel_state(self._host)
156        active_minios, inactive_minios \
157            = kernel_utils.get_minios_priority(self._host)
158
159        minios_update = with_os and not with_exclusion
160        # MiniOS update to be verified.
161        self._verifications = [
162                lambda: kernel_utils.verify_minios_priority_after_update(
163                        self._host,
164                        expected=inactive_minios
165                        if minios_update else active_minios)
166        ]
167
168        # Get payload URLs and setup tests.
169        self._payload_urls = []
170        self._setup_cros_update(has_update=with_os)
171        if with_dlc:
172            self._setup_dlc_update()
173        self._setup_minios_update(has_update=minios_update,
174                                  with_exclusion=with_exclusion)
175
176        # Update MiniOS.
177        if with_dlc:
178            self._run_client_test_and_check_result(
179                    'autoupdate_InstallAndUpdateDLC',
180                    payload_urls=self._payload_urls,
181                    allow_failure=not with_os)
182        else:
183            self._run_client_test_and_check_result(
184                    'autoupdate_CannedOmahaUpdate',
185                    payload_url=self._payload_urls,
186                    allow_failure=not with_os)
187
188        if with_os:
189            self._host.reboot()
190
191        # Verify updates.
192        for verify in self._verifications:
193            verify()
194