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