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