1*9c5db199SXin Li#!/usr/bin/python3 2*9c5db199SXin Li# pylint: disable=missing-docstring 3*9c5db199SXin Li 4*9c5db199SXin Liimport unittest 5*9c5db199SXin Lifrom unittest import mock 6*9c5db199SXin Li 7*9c5db199SXin Liimport common 8*9c5db199SXin Li 9*9c5db199SXin Lifrom autotest_lib.client.common_lib import error 10*9c5db199SXin Lifrom autotest_lib.server.cros.servo import servo 11*9c5db199SXin Lifrom autotest_lib.server.hosts import cros_host 12*9c5db199SXin Lifrom autotest_lib.server.hosts import servo_constants 13*9c5db199SXin Lifrom autotest_lib.server.hosts import host_info 14*9c5db199SXin Li 15*9c5db199SXin LiCROSSYSTEM_RESULT = ''' 16*9c5db199SXin Lifwb_tries = 0 # Fake comment 17*9c5db199SXin Lifw_vboot2 = 1 # Fake comment 18*9c5db199SXin Lifwid = Google_Reef.9933.0.0 # Fake comment 19*9c5db199SXin Lifwupdate_tries = 0 # 20*9c5db199SXin Lifw_tried = B # 21*9c5db199SXin Lifw_try_count = 0 # 22*9c5db199SXin Li''' 23*9c5db199SXin Li 24*9c5db199SXin LiNON_UNI_LSB_RELEASE_OUTPUT = ''' 25*9c5db199SXin LiCHROMEOS_RELEASE_BOARD=reef 26*9c5db199SXin Li''' 27*9c5db199SXin Li 28*9c5db199SXin LiUNI_LSB_RELEASE_OUTPUT = ''' 29*9c5db199SXin LiCHROMEOS_RELEASE_BOARD=coral 30*9c5db199SXin LiCHROMEOS_RELEASE_UNIBUILD=1 31*9c5db199SXin Li''' 32*9c5db199SXin Li 33*9c5db199SXin LiSERVO_STATE_PREFIX = servo_constants.SERVO_STATE_LABEL_PREFIX 34*9c5db199SXin Li 35*9c5db199SXin Li 36*9c5db199SXin Liclass MockCmd(object): 37*9c5db199SXin Li """Simple mock command with base command and results""" 38*9c5db199SXin Li 39*9c5db199SXin Li def __init__(self, cmd, exit_status, stdout): 40*9c5db199SXin Li self.cmd = cmd 41*9c5db199SXin Li self.stdout = stdout 42*9c5db199SXin Li self.exit_status = exit_status 43*9c5db199SXin Li 44*9c5db199SXin Li 45*9c5db199SXin Liclass MockHost(cros_host.CrosHost): 46*9c5db199SXin Li """Simple host for running mock'd host commands""" 47*9c5db199SXin Li 48*9c5db199SXin Li def __init__(self, *args): 49*9c5db199SXin Li self._mock_cmds = {c.cmd: c for c in args} 50*9c5db199SXin Li self.hostname = 'MockHost' 51*9c5db199SXin Li 52*9c5db199SXin Li def run(self, command, **kwargs): 53*9c5db199SXin Li """Finds the matching result by command value""" 54*9c5db199SXin Li mock_cmd = self._mock_cmds[command] 55*9c5db199SXin Li file_out = kwargs.get('stdout_tee', None) 56*9c5db199SXin Li if file_out: 57*9c5db199SXin Li file_out.write(mock_cmd.stdout) 58*9c5db199SXin Li return mock_cmd 59*9c5db199SXin Li 60*9c5db199SXin Li 61*9c5db199SXin Liclass GetPlatformModelTests(unittest.TestCase): 62*9c5db199SXin Li """Unit tests for CrosHost.get_platform_model""" 63*9c5db199SXin Li 64*9c5db199SXin Li def test_cros_config_succeeds(self): 65*9c5db199SXin Li host = MockHost( 66*9c5db199SXin Li MockCmd('cat /etc/lsb-release', 0, UNI_LSB_RELEASE_OUTPUT), 67*9c5db199SXin Li MockCmd('cros_config / name', 0, 'coral')) 68*9c5db199SXin Li self.assertEqual(host.get_platform(), 'coral') 69*9c5db199SXin Li 70*9c5db199SXin Li def test_cros_config_resorts_to_fallback(self): 71*9c5db199SXin Li host = MockHost( 72*9c5db199SXin Li MockCmd('cat /etc/lsb-release', 0, UNI_LSB_RELEASE_OUTPUT), 73*9c5db199SXin Li MockCmd('cros_config / name', 1, ''), 74*9c5db199SXin Li MockCmd('mosys platform model', 0, 'coral')) 75*9c5db199SXin Li self.assertEqual(host.get_platform(), 'coral') 76*9c5db199SXin Li 77*9c5db199SXin Li def test_cros_config_fails(self): 78*9c5db199SXin Li host = MockHost( 79*9c5db199SXin Li MockCmd('cat /etc/lsb-release', 0, UNI_LSB_RELEASE_OUTPUT), 80*9c5db199SXin Li MockCmd('cros_config / name', 1, ''), 81*9c5db199SXin Li MockCmd('mosys platform model', 1, ''), 82*9c5db199SXin Li MockCmd('crossystem', 0, CROSSYSTEM_RESULT)) 83*9c5db199SXin Li self.assertEqual(host.get_platform(), 'reef') 84*9c5db199SXin Li 85*9c5db199SXin Li def test_non_unibuild(self): 86*9c5db199SXin Li host = MockHost( 87*9c5db199SXin Li MockCmd('cat /etc/lsb-release', 0, NON_UNI_LSB_RELEASE_OUTPUT), 88*9c5db199SXin Li MockCmd('crossystem', 0, CROSSYSTEM_RESULT)) 89*9c5db199SXin Li self.assertEqual(host.get_platform(), 'reef') 90*9c5db199SXin Li 91*9c5db199SXin Li def test_cat_lsb_fails(self): 92*9c5db199SXin Li host = MockHost( 93*9c5db199SXin Li MockCmd('cat /etc/lsb-release', 1, ''), 94*9c5db199SXin Li MockCmd('crossystem', 0, CROSSYSTEM_RESULT)) 95*9c5db199SXin Li self.assertEqual(host.get_platform(), 'reef') 96*9c5db199SXin Li 97*9c5db199SXin Li 98*9c5db199SXin Liclass DictFilteringTestCase(unittest.TestCase): 99*9c5db199SXin Li """Tests for dict filtering methods on CrosHost.""" 100*9c5db199SXin Li 101*9c5db199SXin Li def test_get_chameleon_arguments(self): 102*9c5db199SXin Li got = cros_host.CrosHost.get_chameleon_arguments({ 103*9c5db199SXin Li 'chameleon_host': 'host', 104*9c5db199SXin Li 'spam': 'eggs', 105*9c5db199SXin Li }) 106*9c5db199SXin Li self.assertEqual(got, {'chameleon_host': 'host'}) 107*9c5db199SXin Li 108*9c5db199SXin Li def test_get_pdtester_arguments(self): 109*9c5db199SXin Li got = cros_host.CrosHost.get_pdtester_arguments({ 110*9c5db199SXin Li 'pdtester_host': 'host', 111*9c5db199SXin Li 'spam': 'eggs', 112*9c5db199SXin Li }) 113*9c5db199SXin Li self.assertEqual(got, {'pdtester_host': 'host'}) 114*9c5db199SXin Li 115*9c5db199SXin Li def test_get_servo_arguments(self): 116*9c5db199SXin Li got = cros_host.CrosHost.get_servo_arguments({ 117*9c5db199SXin Li servo_constants.SERVO_HOST_ATTR: 'host', 118*9c5db199SXin Li 'spam': 'eggs', 119*9c5db199SXin Li }) 120*9c5db199SXin Li self.assertEqual(got, {servo_constants.SERVO_HOST_ATTR: 'host'}) 121*9c5db199SXin Li 122*9c5db199SXin Li 123*9c5db199SXin Liclass DictFilteringTestCase(unittest.TestCase): 124*9c5db199SXin Li """Test to verify servo_state was set-up as label in host_info_store""" 125*9c5db199SXin Li 126*9c5db199SXin Li def create_host(self): 127*9c5db199SXin Li host = MockHost() 128*9c5db199SXin Li host.servo = None 129*9c5db199SXin Li host._servo_host = mock.Mock() 130*9c5db199SXin Li servo = mock.Mock() 131*9c5db199SXin Li servo.get_servo_type.return_value = None 132*9c5db199SXin Li host._servo_host.get_servo.return_value = servo 133*9c5db199SXin Li host._servo_host.get_servo_state.return_value = 'SOME_STATE' 134*9c5db199SXin Li host.host_info_store = host_info.InMemoryHostInfoStore() 135*9c5db199SXin Li return host 136*9c5db199SXin Li 137*9c5db199SXin Li def test_do_not_update_label_when_servo_host_is_not_inited(self): 138*9c5db199SXin Li host = self.create_host() 139*9c5db199SXin Li host._servo_host = None 140*9c5db199SXin Li 141*9c5db199SXin Li host.set_servo_state('some_status') 142*9c5db199SXin Li self.assertEqual(host.host_info_store.get().get_label_value(SERVO_STATE_PREFIX), 'some_status') 143*9c5db199SXin Li 144*9c5db199SXin Li def test_do_not_update_label_when_servo_state_is_None(self): 145*9c5db199SXin Li host = self.create_host() 146*9c5db199SXin Li 147*9c5db199SXin Li host.set_servo_state(None) 148*9c5db199SXin Li host._servo_host.get_servo_state.assert_not_called() 149*9c5db199SXin Li self.assertEqual(host.host_info_store.get().get_label_value(SERVO_STATE_PREFIX), '') 150*9c5db199SXin Li 151*9c5db199SXin Li def test_repair_servo_set_servo_state_after_repair_when_repair_is_fail(self): 152*9c5db199SXin Li host = self.create_host() 153*9c5db199SXin Li host._servo_host.repair.side_effect = Exception('Something bad') 154*9c5db199SXin Li 155*9c5db199SXin Li try: 156*9c5db199SXin Li host.repair_servo() 157*9c5db199SXin Li self.assertEqual("Exception is", 'expecting to raise') 158*9c5db199SXin Li except: 159*9c5db199SXin Li pass 160*9c5db199SXin Li host._servo_host.get_servo_state.assert_called() 161*9c5db199SXin Li self.assertEqual(host.host_info_store.get().get_label_value(SERVO_STATE_PREFIX), 'SOME_STATE') 162*9c5db199SXin Li 163*9c5db199SXin Li def test_repair_servo_set_servo_state_after_repair_when_repair_is_not_fail(self): 164*9c5db199SXin Li host = self.create_host() 165*9c5db199SXin Li try: 166*9c5db199SXin Li host.repair_servo() 167*9c5db199SXin Li except: 168*9c5db199SXin Li self.assertEqual("Exception is not", 'expected') 169*9c5db199SXin Li pass 170*9c5db199SXin Li host._servo_host.get_servo_state.assert_called() 171*9c5db199SXin Li self.assertEqual(host.host_info_store.get().get_label_value(SERVO_STATE_PREFIX), 'SOME_STATE') 172*9c5db199SXin Li 173*9c5db199SXin Li def test_set_servo_host_update_servo_state_when_host_exist(self): 174*9c5db199SXin Li host = self.create_host() 175*9c5db199SXin Li host._servo_host = mock.Mock() 176*9c5db199SXin Li servo = mock.Mock() 177*9c5db199SXin Li servo.get_servo_type.return_value = None 178*9c5db199SXin Li host._servo_host.get_servo.return_value = servo 179*9c5db199SXin Li host._servo_host.get_servo_state.return_value = 'SOME_STATE' 180*9c5db199SXin Li self.assertEqual(host.host_info_store.get().get_label_value(SERVO_STATE_PREFIX), '') 181*9c5db199SXin Li 182*9c5db199SXin Li try: 183*9c5db199SXin Li host.repair_servo() 184*9c5db199SXin Li except: 185*9c5db199SXin Li self.assertEqual("Exception is not", 'expected') 186*9c5db199SXin Li pass 187*9c5db199SXin Li host._servo_host.get_servo_state.assert_called() 188*9c5db199SXin Li self.assertEqual(host.host_info_store.get().get_label_value(SERVO_STATE_PREFIX), 'SOME_STATE') 189*9c5db199SXin Li 190*9c5db199SXin Li def test_set_servo_host_use_passed_servo_state_when_host_is_None(self): 191*9c5db199SXin Li host = self.create_host() 192*9c5db199SXin Li 193*9c5db199SXin Li host.set_servo_host(None, 'passed_State') 194*9c5db199SXin Li self.assertEqual(host.host_info_store.get().get_label_value(SERVO_STATE_PREFIX), 'passed_State') 195*9c5db199SXin Li 196*9c5db199SXin Li def test_set_servo_host_use_servo_state_from_host_when_host_is_passed(self): 197*9c5db199SXin Li host = self.create_host() 198*9c5db199SXin Li servo_host = mock.Mock() 199*9c5db199SXin Li servo = mock.Mock() 200*9c5db199SXin Li servo.get_servo_type.return_value = None 201*9c5db199SXin Li servo_host.get_servo.return_value = servo 202*9c5db199SXin Li servo_host.get_servo_state.return_value = 'state_of_host' 203*9c5db199SXin Li 204*9c5db199SXin Li host.set_servo_host(servo_host) 205*9c5db199SXin Li self.assertEqual(host.host_info_store.get().get_label_value(SERVO_STATE_PREFIX), 'state_of_host') 206*9c5db199SXin Li 207*9c5db199SXin Li servo_host.get_servo_state.return_value = 'state_of_host2' 208*9c5db199SXin Li host.set_servo_host(servo_host, 'passed_State') 209*9c5db199SXin Li self.assertEqual(host.host_info_store.get().get_label_value(SERVO_STATE_PREFIX), 'state_of_host2') 210*9c5db199SXin Li 211*9c5db199SXin Liclass CrosHostTestCase(unittest.TestCase): 212*9c5db199SXin Li """Tests to verify CrosHost.""" 213*9c5db199SXin Li 214*9c5db199SXin Li class TestCrosHost(cros_host.CrosHost): 215*9c5db199SXin Li def __init__(self, *args, **kwargs): 216*9c5db199SXin Li self.hostname = 'hostname' 217*9c5db199SXin Li self.servo = mock.create_autospec(servo.Servo) 218*9c5db199SXin Li 219*9c5db199SXin Li @mock.patch('autotest_lib.server.hosts.cros_host.dev_server') 220*9c5db199SXin Li def test_stage_build_to_usb(self, devserver_mock): 221*9c5db199SXin Li host = self.TestCrosHost() 222*9c5db199SXin Li image_server = mock.MagicMock() 223*9c5db199SXin Li devserver_mock.ImageServer.resolve.return_value = image_server 224*9c5db199SXin Li image_server.get_test_image_url.return_value = 'image_url' 225*9c5db199SXin Li 226*9c5db199SXin Li host.stage_build_to_usb('board/version') 227*9c5db199SXin Li 228*9c5db199SXin Li image_server.stage_artifacts.assert_called_with('board/version', ['test_image']) 229*9c5db199SXin Li host.servo.image_to_servo_usb.assert_called_with('image_url') 230*9c5db199SXin Li 231*9c5db199SXin Li host.servo.get_power_state_controller.return_value.power_on.assert_called() 232*9c5db199SXin Li 233*9c5db199SXin Li @mock.patch('autotest_lib.server.hosts.cros_host.dev_server') 234*9c5db199SXin Li def test_stage_build_to_usb_failure(self, devserver_mock): 235*9c5db199SXin Li host = self.TestCrosHost() 236*9c5db199SXin Li image_server = mock.MagicMock() 237*9c5db199SXin Li devserver_mock.ImageServer.resolve.return_value = image_server 238*9c5db199SXin Li image_server.get_test_image_url.return_value = 'image_url' 239*9c5db199SXin Li host.servo.image_to_servo_usb.side_effect = error.AutotestError('download') 240*9c5db199SXin Li 241*9c5db199SXin Li with self.assertRaises(error.AutotestError): 242*9c5db199SXin Li host.stage_build_to_usb('board/version') 243*9c5db199SXin Li 244*9c5db199SXin Li host.servo.get_power_state_controller.return_value.power_on.assert_called() 245*9c5db199SXin Li 246*9c5db199SXin Li 247*9c5db199SXin Liif __name__ == "__main__": 248*9c5db199SXin Li unittest.main() 249