xref: /aosp_15_r20/system/extras/tests/bootloader/haltest.py (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker# Copyright (C) 2016 The Android Open Source Project
2*288bf522SAndroid Build Coastguard Worker#
3*288bf522SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*288bf522SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*288bf522SAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*288bf522SAndroid Build Coastguard Worker#
7*288bf522SAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
8*288bf522SAndroid Build Coastguard Worker#
9*288bf522SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*288bf522SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*288bf522SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*288bf522SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*288bf522SAndroid Build Coastguard Worker# limitations under the License.
14*288bf522SAndroid Build Coastguard Worker
15*288bf522SAndroid Build Coastguard Workerimport bootctl
16*288bf522SAndroid Build Coastguard Workerimport shelltest
17*288bf522SAndroid Build Coastguard Workerimport sys
18*288bf522SAndroid Build Coastguard Workerimport unittest
19*288bf522SAndroid Build Coastguard Worker
20*288bf522SAndroid Build Coastguard Worker# Note: In order to run these tests, the device must be able to boot
21*288bf522SAndroid Build Coastguard Worker# from all slots on the device.
22*288bf522SAndroid Build Coastguard Workerclass HalTest(shelltest.ShellTest):
23*288bf522SAndroid Build Coastguard Worker    def __init__(self, *args, **kwargs):
24*288bf522SAndroid Build Coastguard Worker        super(HalTest, self).__init__(*args, **kwargs)
25*288bf522SAndroid Build Coastguard Worker        self.bootctl = bootctl.Bootctl(self.device)
26*288bf522SAndroid Build Coastguard Worker
27*288bf522SAndroid Build Coastguard Worker    def test_slots(self):
28*288bf522SAndroid Build Coastguard Worker        """Test that all slots are reported and named uniquely."""
29*288bf522SAndroid Build Coastguard Worker
30*288bf522SAndroid Build Coastguard Worker        self.device.root()
31*288bf522SAndroid Build Coastguard Worker        self.device.wait()
32*288bf522SAndroid Build Coastguard Worker        num_slots = self.bootctl.get_number_slots()
33*288bf522SAndroid Build Coastguard Worker        suffixes = dict()
34*288bf522SAndroid Build Coastguard Worker        for slot in range(num_slots):
35*288bf522SAndroid Build Coastguard Worker            suffix = self.bootctl.get_suffix(slot)
36*288bf522SAndroid Build Coastguard Worker            self.assertNotEqual(suffix, "(null)")
37*288bf522SAndroid Build Coastguard Worker            suffixes[suffix] = slot
38*288bf522SAndroid Build Coastguard Worker        self.assertEqual(len(suffixes), num_slots)
39*288bf522SAndroid Build Coastguard Worker
40*288bf522SAndroid Build Coastguard Worker    def test_mark_successful(self):
41*288bf522SAndroid Build Coastguard Worker        """Ensure mark successful works, and persists on reboot.
42*288bf522SAndroid Build Coastguard Worker
43*288bf522SAndroid Build Coastguard Worker        Ensure that mark_successful will mark the slot as
44*288bf522SAndroid Build Coastguard Worker        successful, and that the HAL sees this. First resets
45*288bf522SAndroid Build Coastguard Worker        slot-successful by setting the active slot to the current one."""
46*288bf522SAndroid Build Coastguard Worker
47*288bf522SAndroid Build Coastguard Worker        self.device.root()
48*288bf522SAndroid Build Coastguard Worker        self.device.wait()
49*288bf522SAndroid Build Coastguard Worker        slot = self.bootctl.get_current_slot()
50*288bf522SAndroid Build Coastguard Worker        self.assertTrue(self.bootctl.set_active_boot_slot(slot))
51*288bf522SAndroid Build Coastguard Worker        self.assertFalse(self.bootctl.is_slot_marked_successful(slot))
52*288bf522SAndroid Build Coastguard Worker        self.assertTrue(self.bootctl.mark_boot_successful())
53*288bf522SAndroid Build Coastguard Worker        self.assertTrue(self.bootctl.is_slot_marked_successful(slot))
54*288bf522SAndroid Build Coastguard Worker        self.device.reboot()
55*288bf522SAndroid Build Coastguard Worker        self.device.wait()
56*288bf522SAndroid Build Coastguard Worker        self.device.root()
57*288bf522SAndroid Build Coastguard Worker        self.device.wait()
58*288bf522SAndroid Build Coastguard Worker        self.assertTrue(self.bootctl.is_slot_marked_successful(slot))
59*288bf522SAndroid Build Coastguard Worker
60*288bf522SAndroid Build Coastguard Worker    def test_switch_slots(self):
61*288bf522SAndroid Build Coastguard Worker        """Test that setActiveBootSlot works and persists
62*288bf522SAndroid Build Coastguard Worker
63*288bf522SAndroid Build Coastguard Worker        Ensure switching slots works, and that setting the slot does not
64*288bf522SAndroid Build Coastguard Worker        change the reported slot until the reboot."""
65*288bf522SAndroid Build Coastguard Worker
66*288bf522SAndroid Build Coastguard Worker        # Cycle through all slots once
67*288bf522SAndroid Build Coastguard Worker        num_slots = self.bootctl.get_number_slots()
68*288bf522SAndroid Build Coastguard Worker        for i in range(num_slots):
69*288bf522SAndroid Build Coastguard Worker            self.device.root()
70*288bf522SAndroid Build Coastguard Worker            self.device.wait()
71*288bf522SAndroid Build Coastguard Worker            slot = self.bootctl.get_current_slot()
72*288bf522SAndroid Build Coastguard Worker            new_slot = (slot + 1) % num_slots
73*288bf522SAndroid Build Coastguard Worker            self.assertTrue(self.bootctl.set_active_boot_slot(new_slot))
74*288bf522SAndroid Build Coastguard Worker            slot2 = self.bootctl.get_current_slot()
75*288bf522SAndroid Build Coastguard Worker            self.assertEqual(slot, slot2)
76*288bf522SAndroid Build Coastguard Worker            self.device.reboot()
77*288bf522SAndroid Build Coastguard Worker            self.device.wait()
78*288bf522SAndroid Build Coastguard Worker            self.device.root()
79*288bf522SAndroid Build Coastguard Worker            self.device.wait()
80*288bf522SAndroid Build Coastguard Worker            self.assertEqual(new_slot, self.bootctl.get_current_slot())
81*288bf522SAndroid Build Coastguard Worker
82*288bf522SAndroid Build Coastguard Worker    def test_unbootable(self):
83*288bf522SAndroid Build Coastguard Worker        """Test setSlotAsUnbootable
84*288bf522SAndroid Build Coastguard Worker
85*288bf522SAndroid Build Coastguard Worker        Test that the device will attempt to roll back to a valid slot if
86*288bf522SAndroid Build Coastguard Worker        the current slot is unbootable."""
87*288bf522SAndroid Build Coastguard Worker
88*288bf522SAndroid Build Coastguard Worker        # Cycle through all slots once
89*288bf522SAndroid Build Coastguard Worker        num_slots = self.bootctl.get_number_slots()
90*288bf522SAndroid Build Coastguard Worker        for i in range(num_slots):
91*288bf522SAndroid Build Coastguard Worker            self.device.root()
92*288bf522SAndroid Build Coastguard Worker            self.device.wait()
93*288bf522SAndroid Build Coastguard Worker            slot = self.bootctl.get_current_slot()
94*288bf522SAndroid Build Coastguard Worker            new_slot = (slot + 1) % num_slots
95*288bf522SAndroid Build Coastguard Worker            self.device.root()
96*288bf522SAndroid Build Coastguard Worker            self.device.wait()
97*288bf522SAndroid Build Coastguard Worker            self.assertTrue(self.bootctl.set_active_boot_slot(new_slot))
98*288bf522SAndroid Build Coastguard Worker            self.assertTrue(self.bootctl.is_slot_bootable(new_slot))
99*288bf522SAndroid Build Coastguard Worker            self.assertTrue(self.bootctl.set_slot_as_unbootable_slot(new_slot))
100*288bf522SAndroid Build Coastguard Worker            self.assertFalse(self.bootctl.is_slot_bootable(new_slot))
101*288bf522SAndroid Build Coastguard Worker            self.device.reboot()
102*288bf522SAndroid Build Coastguard Worker            self.device.wait()
103*288bf522SAndroid Build Coastguard Worker            self.device.root()
104*288bf522SAndroid Build Coastguard Worker            self.device.wait()
105*288bf522SAndroid Build Coastguard Worker            self.assertEqual(slot, self.bootctl.get_current_slot())
106*288bf522SAndroid Build Coastguard Worker            self.assertFalse(self.bootctl.is_slot_bootable(new_slot))
107*288bf522SAndroid Build Coastguard Worker            self.assertTrue(self.bootctl.set_active_boot_slot(new_slot))
108*288bf522SAndroid Build Coastguard Worker            self.assertTrue(self.bootctl.is_slot_bootable(new_slot))
109*288bf522SAndroid Build Coastguard Worker            self.device.reboot()
110*288bf522SAndroid Build Coastguard Worker            self.device.wait()
111*288bf522SAndroid Build Coastguard Worker            self.device.root()
112*288bf522SAndroid Build Coastguard Worker            self.device.wait()
113*288bf522SAndroid Build Coastguard Worker            self.assertEqual(new_slot, self.bootctl.get_current_slot());
114*288bf522SAndroid Build Coastguard Worker
115*288bf522SAndroid Build Coastguard Workerif __name__ == '__main__':
116*288bf522SAndroid Build Coastguard Worker    unittest.main(verbosity=3)
117