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