1#!/usr/bin/env vpython3 2# Copyright 2023 The Chromium Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5"""File for testing serial_boot_device.py.""" 6 7import json 8import os 9import unittest 10import unittest.mock as mock 11 12from subprocess import CompletedProcess 13 14import serial_boot_device 15 16from boot_device import BootMode 17 18 19# pylint: disable=too-many-public-methods, missing-function-docstring 20@mock.patch('shutil.which', return_value='/bin') 21class SerialBootDeviceTest(unittest.TestCase): 22 """Unittests for serial_boot_device.py.""" 23 def setUp(self) -> None: 24 os.environ['FUCHSIA_NODENAME'] = 'fuchsia-node-id' 25 os.environ['FUCHSIA_FASTBOOT_SERNUM'] = 'fuchsia-serial-num' 26 27 def test_does_not_boot_without_binaries(self, *_) -> None: 28 with mock.patch('shutil.which', return_value=None): 29 self.assertNotEqual(serial_boot_device.main('reboot'), 0) 30 31 @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[True]) 32 @mock.patch('subprocess.run', 33 return_value=CompletedProcess(args=['/bin'], returncode=0)) 34 @mock.patch('builtins.print') 35 def test_check_health_in_fuchsia(self, mock_print, *_) -> None: 36 self.assertEqual(serial_boot_device.main('health-check'), 0) 37 result = json.loads(mock_print.call_args.args[0]) 38 self.assertEqual(result[0]['nodename'], 'fuchsia-node-id') 39 self.assertEqual(result[0]['state'], 'healthy') 40 41 @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[True]) 42 @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False]) 43 @mock.patch('subprocess.run', 44 return_value=CompletedProcess(args=['/bin'], returncode=0)) 45 @mock.patch('builtins.print') 46 def test_check_health_in_fastboot(self, mock_print, *_) -> None: 47 self.assertEqual(serial_boot_device.main('health-check'), 0) 48 result = json.loads(mock_print.call_args.args[0]) 49 self.assertEqual(result[0]['nodename'], 'fuchsia-node-id') 50 self.assertEqual(result[0]['state'], 'healthy') 51 52 @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False]) 53 @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False]) 54 @mock.patch('subprocess.run', 55 return_value=CompletedProcess(args=['/bin'], returncode=0)) 56 def test_check_health_undetectable(self, *_) -> None: 57 self.assertNotEqual(serial_boot_device.main('health-check'), 0) 58 59 @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False, True]) 60 @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False]) 61 @mock.patch('subprocess.run', 62 return_value=CompletedProcess(args=['/bin'], returncode=0)) 63 def test_boot_undetectable(self, mock_run, *_) -> None: 64 self.assertEqual(serial_boot_device.main('reboot'), 0) 65 mock_run.assert_called_once_with( 66 ['serialio', 'fuchsia-node-id', 'send', 'dm', 'reboot']) 67 68 @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False, True]) 69 @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False]) 70 @mock.patch('subprocess.run', 71 return_value=CompletedProcess(args=['/bin'], returncode=0)) 72 def test_boot_undetectable_not_must_boot(self, mock_run, *_) -> None: 73 self.assertTrue( 74 serial_boot_device.boot_device('fuchsia-node-id', 75 'fuchsia-serial-num', 76 BootMode.REGULAR, 77 must_boot=False)) 78 mock_run.assert_called_once_with( 79 ['serialio', 'fuchsia-node-id', 'send', 'dm', 'reboot']) 80 81 @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False]) 82 @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False, True]) 83 @mock.patch('subprocess.run', 84 return_value=CompletedProcess(args=['/bin'], returncode=0)) 85 def test_boot_undetectable_to_fastboot(self, mock_run, *_) -> None: 86 self.assertEqual(serial_boot_device.main('reboot-fastboot'), 0) 87 mock_run.assert_called_once_with( 88 ['serialio', 'fuchsia-node-id', 'send', 'dm', 'reboot-bootloader']) 89 90 @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False]) 91 @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[True, True]) 92 @mock.patch('subprocess.run', 93 return_value=CompletedProcess(args=['/bin'], returncode=0)) 94 def test_boot_from_fuchsia_to_fuchsia(self, mock_run, *_) -> None: 95 self.assertEqual(serial_boot_device.main('reboot'), 0) 96 mock_run.assert_called_once_with( 97 ['serialio', 'fuchsia-node-id', 'send', 'dm', 'reboot']) 98 99 @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False]) 100 @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[True]) 101 @mock.patch('subprocess.run', 102 return_value=CompletedProcess(args=['/bin'], returncode=0)) 103 def test_boot_from_fuchsia_to_fuchsia_not_must_boot(self, mock_run, 104 *_) -> None: 105 self.assertTrue( 106 serial_boot_device.boot_device('fuchsia-node-id', 107 'fuchsia-serial-num', 108 BootMode.REGULAR, 109 must_boot=False)) 110 mock_run.assert_not_called() 111 112 @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False, True]) 113 @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[True]) 114 @mock.patch('subprocess.run', 115 return_value=CompletedProcess(args=['/bin'], returncode=0)) 116 def test_boot_from_fastboot_to_fuchsia(self, mock_run, *_) -> None: 117 self.assertEqual(serial_boot_device.main('reboot'), 0) 118 mock_run.assert_called_once_with( 119 ['fastboot', 'reboot', '-s', 'fuchsia-serial-num'], 120 capture_output=True, 121 timeout=30) 122 123 @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[True]) 124 @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False, True]) 125 @mock.patch('subprocess.run', 126 return_value=CompletedProcess(args=['/bin'], returncode=0)) 127 def test_boot_from_fuchsia_to_fastboot(self, mock_run, *_) -> None: 128 self.assertEqual(serial_boot_device.main('reboot-fastboot'), 0) 129 mock_run.assert_called_once_with( 130 ['serialio', 'fuchsia-node-id', 'send', 'dm', 'reboot-bootloader']) 131 132 @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False]) 133 @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[True]) 134 @mock.patch('subprocess.run', 135 return_value=CompletedProcess(args=['/bin'], returncode=0)) 136 def test_boot_from_fastboot_to_fastboot(self, mock_run, *_) -> None: 137 self.assertEqual(serial_boot_device.main('reboot-fastboot'), 0) 138 mock_run.assert_not_called() 139 140 141if __name__ == '__main__': 142 unittest.main() 143