xref: /aosp_15_r20/external/autotest/server/cros/faft/firmware_test_unittest.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Lint as: python2, python3
2# Copyright (c) 2020 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import unittest
7from unittest import mock
8
9from autotest_lib.client.common_lib import error
10from autotest_lib.server.cros.faft import firmware_test
11
12
13class TestRunOnce(unittest.TestCase):
14    """Tests that run_once works as expected."""
15    class GoodFirmwareTest(firmware_test.FirmwareTest):
16        """A FirmwareTest stub providing the parts that should be tested."""
17        def __init__(self, *_args, **_dargs):
18            # pylint: disable=super-init-not-called
19            """Init logic in FirmwareTest is not relevant to this test."""
20            self.test = mock.MagicMock()
21            self.test_good = mock.MagicMock()
22            self.test_good_better = mock.MagicMock()
23            self.test_host_mock = mock.MagicMock()
24            self.test_arg2_mock = mock.MagicMock()
25
26        def test_host(self, host, **kwargs):
27            """Get at the 'host' mock"""
28            self.test_host_mock(host, **kwargs)
29
30        def test_arg2(self, arg2):
31            """Get at the 'arg2' mock"""
32            self.test_arg2_mock(arg2)
33
34    def test_keyword_test_name(self):
35        """Test that keyworded test names work"""
36        ft = self.GoodFirmwareTest()
37
38        ft.run_once(test_name='GoodFirmwareTest.good')
39        ft.test_good.assert_called_with()
40
41        ft.run_once('arg1', test_name='GoodFirmwareTest.good', arg2='arg2')
42        ft.test_good.assert_called_with('arg1', arg2='arg2')
43
44    def test_positional_test_name(self):
45        """Test that positional test names work"""
46        ft = self.GoodFirmwareTest()
47
48        ft.run_once('GoodFirmwareTest.good')
49        ft.test_good.assert_called_with()
50
51        ft.run_once('GoodFirmwareTest.good', 'arg1', arg2='arg2')
52        ft.test_good.assert_called_with('arg1', arg2='arg2')
53
54    def test_no_test_name(self):
55        """Test that running a whole test class works"""
56        ft = self.GoodFirmwareTest()
57
58        ft.run_once('GoodFirmwareTest')
59        ft.test.assert_called_with()
60
61        ft.run_once('GoodFirmwareTest', 'arg1', arg2='arg2')
62        ft.test.assert_called_with('arg1', arg2='arg2')
63
64    def test_sub_test_name(self):
65        """Test that sub tests can be executed"""
66        ft = self.GoodFirmwareTest()
67
68        ft.run_once('GoodFirmwareTest.good.better')
69        ft.test_good_better.assert_called_with()
70
71        ft.run_once('GoodFirmwareTest.good.better', 'arg1', arg2='arg2')
72        ft.test_good_better.assert_called_with('arg1', arg2='arg2')
73
74    def test_missing_test_name(self):
75        """Test that a test name must be passed"""
76        ft = self.GoodFirmwareTest()
77
78        with self.assertRaises(error.TestError):
79            ft.run_once()
80
81    def test_bad_class_name(self):
82        """Test that the class name must be valid"""
83        ft = self.GoodFirmwareTest()
84
85        with self.assertRaises(error.TestError):
86            ft.run_once(test_name='BadFirmwareTest')
87
88    def test_bad_method_name(self):
89        """Test that the method must be valid"""
90        ft = self.GoodFirmwareTest()
91
92        with self.assertRaises(error.TestError):
93            ft.run_once(test_name='GoodFirmwareTest.bad')
94
95    def test_host_arg(self):
96        """Test operation with host arg used"""
97        ft = self.GoodFirmwareTest()
98
99        ft.run_once('GoodFirmwareTest.host', host='host', arg2='arg2')
100        ft.test_host_mock.assert_called_with('host', arg2='arg2')
101
102    def test_arg2(self):
103        """Test operation with arg2 used"""
104        ft = self.GoodFirmwareTest()
105
106        ft.run_once('GoodFirmwareTest.arg2', host='host', arg2='arg2')
107        ft.test_arg2_mock.assert_called_with('arg2')
108
109
110class TestCheckPowerState(unittest.TestCase):
111    """Test that power_state matching is precise"""
112    # Mock out EC behavior to return definable power states
113    class MockedECFirmwareTest(firmware_test.FirmwareTest):
114        """A stubbed out FirmwareTest to check the precision behavior"""
115
116        def __init__(self, *_args, **_dargs):
117            # pylint: disable=super-init-not-called
118            pass
119
120    # power_state is supposed to be a string, but lists seem somewhat common,
121    # so guard against them.
122    def test_fails_on_list(self):
123        ft = self.MockedECFirmwareTest()
124
125        with self.assertRaises(error.TestError):
126            ft._check_power_state([], 'S0')
127
128    def test_s0ix_isnt_s0(self):
129        ft = self.MockedECFirmwareTest()
130
131        self.assertEqual(False, ft._check_power_state("S0", "S0ix"))
132
133    def test_s0_is_found(self):
134        ft = self.MockedECFirmwareTest()
135
136        self.assertEqual(True, ft._check_power_state("S0", "S0"))
137
138    def test_s0_is_found_unicode(self):
139        ft = self.MockedECFirmwareTest()
140
141        self.assertEqual(True, ft._check_power_state(u"S0", "S0"))
142        self.assertEqual(True, ft._check_power_state("S0", u"S0"))
143        self.assertEqual(True, ft._check_power_state(u"S0", u"S0"))
144
145    def test_s0_or_s3_is_found(self):
146        ft = self.MockedECFirmwareTest()
147
148        self.assertEqual(True, ft._check_power_state("(S0|S3)", "S0"))
149        self.assertEqual(True, ft._check_power_state("(S0|S3)", "S3"))
150        self.assertEqual(False, ft._check_power_state("(S0|S3)", "G3"))
151
152
153class Test_stage_build_to_usbkey(unittest.TestCase):
154    """stage_build_to_usbkey test"""
155
156    class MockFirmwareTest(firmware_test.FirmwareTest):
157        """Mock of FirmwareTest"""
158
159        def __init__(self):
160            self._client = mock.MagicMock()
161            self.faft_client = mock.MagicMock()
162
163    def setUp(self):
164        self.test = self.MockFirmwareTest()
165
166    def test_stage_build_to_usbkey(self):
167        self.test._client.host_info_store.get.return_value.build = "placeholder_build"
168        self.test._client._servo_host.validate_image_usbkey.return_value = (
169            "another_build")
170        self.assertTrue(self.test.stage_build_to_usbkey())
171        self.test._client.stage_build_to_usb.assert_called_with(
172                "placeholder_build")
173
174    def test_stage_build_to_usbkey_same_build(self):
175        self.test._client.host_info_store.get.return_value.build = "placeholder_build"
176        self.test._client._servo_host.validate_image_usbkey.return_value = (
177                "placeholder_build")
178        self.assertTrue(self.test.stage_build_to_usbkey())
179        self.test._client.stage_build_to_usb.assert_not_called()
180
181    def test_stage_build_to_usbkey_no_build(self):
182        self.test._client.host_info_store.get.return_value.build = None
183        self.assertFalse(self.test.stage_build_to_usbkey())
184        self.test._client.stage_build_to_usb.assert_not_called()
185
186    def test_stage_build_to_usbkey_download_error(self):
187        self.test._client.host_info_store.get.return_value.build = "placeholder_build"
188        self.test._client._servo_host.validate_image_usbkey.return_value = (
189            "another_build")
190        self.test._client.stage_build_to_usb = (
191            mock.MagicMock(side_effect=error.AutotestError("download")))
192        self.assertFalse(self.test.stage_build_to_usbkey())
193        self.test._client.stage_build_to_usb.assert_called_with(
194                "placeholder_build")
195
196    def test_setup_usbkey(self):
197        self.test._client.host_info_store.get.return_value.build = "placeholder_build"
198        self.test._client._servo_host.validate_image_usbkey.return_value = (
199            "another_build")
200        self.test.assert_test_image_in_usb_disk = mock.MagicMock()
201        self.test.set_servo_v4_role_to_snk = mock.MagicMock()
202        with mock.patch('time.sleep'):
203            self.test.setup_usbkey(usbkey=True)
204        self.test._client.stage_build_to_usb.assert_called_with(
205                "placeholder_build")
206        self.test.assert_test_image_in_usb_disk.assert_called()
207        self.test.set_servo_v4_role_to_snk.assert_called()
208
209    def test_setup_usbkey_no_stage(self):
210        self.test._client.host_info_store.get.return_value.build = "placeholder_build"
211        self.test._client._servo_host.validate_image_usbkey.return_value = (
212            "another_build")
213        self.test.assert_test_image_in_usb_disk = mock.MagicMock()
214        self.test.set_servo_v4_role_to_snk = mock.MagicMock()
215        self.test.servo = mock.MagicMock()
216        self.test.setup_usbkey(usbkey=False)
217        self.test._client.stage_build_to_usb.assert_not_called()
218        self.test.assert_test_image_in_usb_disk.assert_not_called()
219        self.test.servo.switch_usbkey.assert_called_with('host')
220        self.test.set_servo_v4_role_to_snk.assert_not_called()
221
222
223if __name__ == '__main__':
224    unittest.main()
225