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