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