#!/usr/bin/env vpython3 # Copyright 2023 The Chromium Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """File for testing serial_boot_device.py.""" import json import os import unittest import unittest.mock as mock from subprocess import CompletedProcess import serial_boot_device from boot_device import BootMode # pylint: disable=too-many-public-methods, missing-function-docstring @mock.patch('shutil.which', return_value='/bin') class SerialBootDeviceTest(unittest.TestCase): """Unittests for serial_boot_device.py.""" def setUp(self) -> None: os.environ['FUCHSIA_NODENAME'] = 'fuchsia-node-id' os.environ['FUCHSIA_FASTBOOT_SERNUM'] = 'fuchsia-serial-num' def test_does_not_boot_without_binaries(self, *_) -> None: with mock.patch('shutil.which', return_value=None): self.assertNotEqual(serial_boot_device.main('reboot'), 0) @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[True]) @mock.patch('subprocess.run', return_value=CompletedProcess(args=['/bin'], returncode=0)) @mock.patch('builtins.print') def test_check_health_in_fuchsia(self, mock_print, *_) -> None: self.assertEqual(serial_boot_device.main('health-check'), 0) result = json.loads(mock_print.call_args.args[0]) self.assertEqual(result[0]['nodename'], 'fuchsia-node-id') self.assertEqual(result[0]['state'], 'healthy') @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[True]) @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False]) @mock.patch('subprocess.run', return_value=CompletedProcess(args=['/bin'], returncode=0)) @mock.patch('builtins.print') def test_check_health_in_fastboot(self, mock_print, *_) -> None: self.assertEqual(serial_boot_device.main('health-check'), 0) result = json.loads(mock_print.call_args.args[0]) self.assertEqual(result[0]['nodename'], 'fuchsia-node-id') self.assertEqual(result[0]['state'], 'healthy') @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False]) @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False]) @mock.patch('subprocess.run', return_value=CompletedProcess(args=['/bin'], returncode=0)) def test_check_health_undetectable(self, *_) -> None: self.assertNotEqual(serial_boot_device.main('health-check'), 0) @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False, True]) @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False]) @mock.patch('subprocess.run', return_value=CompletedProcess(args=['/bin'], returncode=0)) def test_boot_undetectable(self, mock_run, *_) -> None: self.assertEqual(serial_boot_device.main('reboot'), 0) mock_run.assert_called_once_with( ['serialio', 'fuchsia-node-id', 'send', 'dm', 'reboot']) @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False, True]) @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False]) @mock.patch('subprocess.run', return_value=CompletedProcess(args=['/bin'], returncode=0)) def test_boot_undetectable_not_must_boot(self, mock_run, *_) -> None: self.assertTrue( serial_boot_device.boot_device('fuchsia-node-id', 'fuchsia-serial-num', BootMode.REGULAR, must_boot=False)) mock_run.assert_called_once_with( ['serialio', 'fuchsia-node-id', 'send', 'dm', 'reboot']) @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False]) @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False, True]) @mock.patch('subprocess.run', return_value=CompletedProcess(args=['/bin'], returncode=0)) def test_boot_undetectable_to_fastboot(self, mock_run, *_) -> None: self.assertEqual(serial_boot_device.main('reboot-fastboot'), 0) mock_run.assert_called_once_with( ['serialio', 'fuchsia-node-id', 'send', 'dm', 'reboot-bootloader']) @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False]) @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[True, True]) @mock.patch('subprocess.run', return_value=CompletedProcess(args=['/bin'], returncode=0)) def test_boot_from_fuchsia_to_fuchsia(self, mock_run, *_) -> None: self.assertEqual(serial_boot_device.main('reboot'), 0) mock_run.assert_called_once_with( ['serialio', 'fuchsia-node-id', 'send', 'dm', 'reboot']) @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False]) @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[True]) @mock.patch('subprocess.run', return_value=CompletedProcess(args=['/bin'], returncode=0)) def test_boot_from_fuchsia_to_fuchsia_not_must_boot(self, mock_run, *_) -> None: self.assertTrue( serial_boot_device.boot_device('fuchsia-node-id', 'fuchsia-serial-num', BootMode.REGULAR, must_boot=False)) mock_run.assert_not_called() @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False, True]) @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[True]) @mock.patch('subprocess.run', return_value=CompletedProcess(args=['/bin'], returncode=0)) def test_boot_from_fastboot_to_fuchsia(self, mock_run, *_) -> None: self.assertEqual(serial_boot_device.main('reboot'), 0) mock_run.assert_called_once_with( ['fastboot', 'reboot', '-s', 'fuchsia-serial-num'], capture_output=True, timeout=30) @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[True]) @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[False, True]) @mock.patch('subprocess.run', return_value=CompletedProcess(args=['/bin'], returncode=0)) def test_boot_from_fuchsia_to_fastboot(self, mock_run, *_) -> None: self.assertEqual(serial_boot_device.main('reboot-fastboot'), 0) mock_run.assert_called_once_with( ['serialio', 'fuchsia-node-id', 'send', 'dm', 'reboot-bootloader']) @mock.patch('serial_boot_device.is_in_fuchsia', side_effect=[False]) @mock.patch('serial_boot_device.is_in_fastboot', side_effect=[True]) @mock.patch('subprocess.run', return_value=CompletedProcess(args=['/bin'], returncode=0)) def test_boot_from_fastboot_to_fastboot(self, mock_run, *_) -> None: self.assertEqual(serial_boot_device.main('reboot-fastboot'), 0) mock_run.assert_not_called() if __name__ == '__main__': unittest.main()