1*9c5db199SXin Li#!/usr/bin/python3 2*9c5db199SXin Li# Copyright 2016 The Chromium OS Authors. All rights reserved. 3*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 4*9c5db199SXin Li# found in the LICENSE file. 5*9c5db199SXin Li 6*9c5db199SXin Liimport unittest 7*9c5db199SXin Li 8*9c5db199SXin Liimport common 9*9c5db199SXin Lifrom autotest_lib.client.common_lib import error 10*9c5db199SXin Lifrom autotest_lib.server.hosts import base_label_unittest, factory 11*9c5db199SXin Lifrom autotest_lib.server.hosts import host_info 12*9c5db199SXin Li 13*9c5db199SXin Li 14*9c5db199SXin Liclass MockHost(object): 15*9c5db199SXin Li """Mock host object with no side effects.""" 16*9c5db199SXin Li def __init__(self, hostname, **args): 17*9c5db199SXin Li self._init_args = args 18*9c5db199SXin Li self._init_args['hostname'] = hostname 19*9c5db199SXin Li 20*9c5db199SXin Li 21*9c5db199SXin Li def job_start(self): 22*9c5db199SXin Li """Only method called by factory.""" 23*9c5db199SXin Li pass 24*9c5db199SXin Li 25*9c5db199SXin Li 26*9c5db199SXin Liclass MockConnectivity(object): 27*9c5db199SXin Li """Mock connectivity object with no side effects.""" 28*9c5db199SXin Li def __init__(self, hostname, **args): 29*9c5db199SXin Li pass 30*9c5db199SXin Li 31*9c5db199SXin Li def run(self, *args, **kwargs): 32*9c5db199SXin Li pass 33*9c5db199SXin Li 34*9c5db199SXin Li def close(self): 35*9c5db199SXin Li pass 36*9c5db199SXin Li 37*9c5db199SXin Li 38*9c5db199SXin Lidef _gen_mock_host(name, check_host=False): 39*9c5db199SXin Li """Create an identifiable mock host closs. 40*9c5db199SXin Li """ 41*9c5db199SXin Li return type('mock_host_%s' % name, (MockHost,), { 42*9c5db199SXin Li '_host_cls_name': name, 43*9c5db199SXin Li 'check_host': staticmethod(lambda host, timeout=None: check_host) 44*9c5db199SXin Li }) 45*9c5db199SXin Li 46*9c5db199SXin Li 47*9c5db199SXin Lidef _gen_mock_conn(name): 48*9c5db199SXin Li """Create an identifiable mock connectivity class. 49*9c5db199SXin Li """ 50*9c5db199SXin Li return type('mock_conn_%s' % name, (MockConnectivity,), 51*9c5db199SXin Li {'_conn_cls_name': name}) 52*9c5db199SXin Li 53*9c5db199SXin Li 54*9c5db199SXin Lidef _gen_machine_dict(hostname='localhost', labels=[], attributes={}): 55*9c5db199SXin Li """Generate a machine dictionary with the specified parameters. 56*9c5db199SXin Li 57*9c5db199SXin Li @param hostname: hostname of machine 58*9c5db199SXin Li @param labels: list of host labels 59*9c5db199SXin Li @param attributes: dict of host attributes 60*9c5db199SXin Li 61*9c5db199SXin Li @return: machine dict with mocked AFE Host object and fake AfeStore. 62*9c5db199SXin Li """ 63*9c5db199SXin Li afe_host = base_label_unittest.MockAFEHost(labels, attributes) 64*9c5db199SXin Li store = host_info.InMemoryHostInfoStore() 65*9c5db199SXin Li store.commit(host_info.HostInfo(labels, attributes)) 66*9c5db199SXin Li return {'hostname': hostname, 67*9c5db199SXin Li 'afe_host': afe_host, 68*9c5db199SXin Li 'host_info_store': store} 69*9c5db199SXin Li 70*9c5db199SXin Li 71*9c5db199SXin Liclass CreateHostUnittests(unittest.TestCase): 72*9c5db199SXin Li """Tests for create_host function.""" 73*9c5db199SXin Li 74*9c5db199SXin Li def setUp(self): 75*9c5db199SXin Li """Prevent use of real Host and connectivity objects due to potential 76*9c5db199SXin Li side effects. 77*9c5db199SXin Li """ 78*9c5db199SXin Li self._orig_types = factory.host_types 79*9c5db199SXin Li self._orig_dict = factory.OS_HOST_DICT 80*9c5db199SXin Li self._orig_cros_host = factory.cros_host.CrosHost 81*9c5db199SXin Li self._orig_local_host = factory.local_host.LocalHost 82*9c5db199SXin Li self._orig_ssh_host = factory.ssh_host.SSHHost 83*9c5db199SXin Li 84*9c5db199SXin Li self.host_types = factory.host_types = [] 85*9c5db199SXin Li self.os_host_dict = factory.OS_HOST_DICT = {} 86*9c5db199SXin Li factory.cros_host.CrosHost = _gen_mock_host('cros_host') 87*9c5db199SXin Li factory.local_host.LocalHost = _gen_mock_conn('local') 88*9c5db199SXin Li factory.ssh_host.SSHHost = _gen_mock_conn('ssh') 89*9c5db199SXin Li 90*9c5db199SXin Li 91*9c5db199SXin Li def tearDown(self): 92*9c5db199SXin Li """Clean up mocks.""" 93*9c5db199SXin Li factory.host_types = self._orig_types 94*9c5db199SXin Li factory.OS_HOST_DICT = self._orig_dict 95*9c5db199SXin Li factory.cros_host.CrosHost = self._orig_cros_host 96*9c5db199SXin Li factory.local_host.LocalHost = self._orig_local_host 97*9c5db199SXin Li factory.ssh_host.SSHHost = self._orig_ssh_host 98*9c5db199SXin Li 99*9c5db199SXin Li 100*9c5db199SXin Li def test_use_specified(self): 101*9c5db199SXin Li """Confirm that the specified host class is used.""" 102*9c5db199SXin Li machine = _gen_machine_dict() 103*9c5db199SXin Li host_obj = factory.create_host( 104*9c5db199SXin Li machine, 105*9c5db199SXin Li _gen_mock_host('specified'), 106*9c5db199SXin Li ) 107*9c5db199SXin Li self.assertEqual(host_obj._host_cls_name, 'specified') 108*9c5db199SXin Li 109*9c5db199SXin Li 110*9c5db199SXin Li def test_detect_host_by_os_label(self): 111*9c5db199SXin Li """Confirm that the host object is selected by the os label. 112*9c5db199SXin Li """ 113*9c5db199SXin Li machine = _gen_machine_dict(labels=['os:foo']) 114*9c5db199SXin Li self.os_host_dict['foo'] = _gen_mock_host('foo') 115*9c5db199SXin Li host_obj = factory.create_host(machine) 116*9c5db199SXin Li self.assertEqual(host_obj._host_cls_name, 'foo') 117*9c5db199SXin Li 118*9c5db199SXin Li 119*9c5db199SXin Li def test_detect_host_by_os_type_attribute(self): 120*9c5db199SXin Li """Confirm that the host object is selected by the os_type attribute 121*9c5db199SXin Li and that the os_type attribute is preferred over the os label. 122*9c5db199SXin Li """ 123*9c5db199SXin Li machine = _gen_machine_dict(labels=['os:foo'], 124*9c5db199SXin Li attributes={'os_type': 'bar'}) 125*9c5db199SXin Li self.os_host_dict['foo'] = _gen_mock_host('foo') 126*9c5db199SXin Li self.os_host_dict['bar'] = _gen_mock_host('bar') 127*9c5db199SXin Li host_obj = factory.create_host(machine) 128*9c5db199SXin Li self.assertEqual(host_obj._host_cls_name, 'bar') 129*9c5db199SXin Li 130*9c5db199SXin Li 131*9c5db199SXin Li def test_detect_host_by_check_host(self): 132*9c5db199SXin Li """Confirm check_host logic chooses a host object when label/attribute 133*9c5db199SXin Li detection fails. 134*9c5db199SXin Li """ 135*9c5db199SXin Li machine = _gen_machine_dict() 136*9c5db199SXin Li self.host_types.append(_gen_mock_host('first', check_host=False)) 137*9c5db199SXin Li self.host_types.append(_gen_mock_host('second', check_host=True)) 138*9c5db199SXin Li self.host_types.append(_gen_mock_host('third', check_host=False)) 139*9c5db199SXin Li host_obj = factory.create_host(machine) 140*9c5db199SXin Li self.assertEqual(host_obj._host_cls_name, 'second') 141*9c5db199SXin Li 142*9c5db199SXin Li 143*9c5db199SXin Li def test_detect_host_fallback_to_cros_host(self): 144*9c5db199SXin Li """Confirm fallback to CrosHost when all other detection fails. 145*9c5db199SXin Li """ 146*9c5db199SXin Li machine = _gen_machine_dict() 147*9c5db199SXin Li host_obj = factory.create_host(machine) 148*9c5db199SXin Li self.assertEqual(host_obj._host_cls_name, 'cros_host') 149*9c5db199SXin Li 150*9c5db199SXin Li 151*9c5db199SXin Li def test_choose_connectivity_local(self): 152*9c5db199SXin Li """Confirm local connectivity class used when hostname is localhost. 153*9c5db199SXin Li """ 154*9c5db199SXin Li machine = _gen_machine_dict(hostname='localhost') 155*9c5db199SXin Li host_obj = factory.create_host(machine) 156*9c5db199SXin Li self.assertEqual(host_obj._conn_cls_name, 'local') 157*9c5db199SXin Li 158*9c5db199SXin Li 159*9c5db199SXin Li def test_choose_connectivity_ssh(self): 160*9c5db199SXin Li """Confirm ssh connectivity class used when configured and hostname 161*9c5db199SXin Li is not localhost. 162*9c5db199SXin Li """ 163*9c5db199SXin Li machine = _gen_machine_dict(hostname='somehost') 164*9c5db199SXin Li host_obj = factory.create_host(machine) 165*9c5db199SXin Li self.assertEqual(host_obj._conn_cls_name, 'ssh') 166*9c5db199SXin Li 167*9c5db199SXin Li 168*9c5db199SXin Li def test_argument_passthrough(self): 169*9c5db199SXin Li """Confirm that detected and specified arguments are passed through to 170*9c5db199SXin Li the host object. 171*9c5db199SXin Li """ 172*9c5db199SXin Li machine = _gen_machine_dict(hostname='localhost') 173*9c5db199SXin Li host_obj = factory.create_host(machine, foo='bar') 174*9c5db199SXin Li self.assertEqual(host_obj._init_args['hostname'], 'localhost') 175*9c5db199SXin Li self.assertTrue('afe_host' in host_obj._init_args) 176*9c5db199SXin Li self.assertTrue('host_info_store' in host_obj._init_args) 177*9c5db199SXin Li self.assertEqual(host_obj._init_args['foo'], 'bar') 178*9c5db199SXin Li 179*9c5db199SXin Li 180*9c5db199SXin Li def test_global_ssh_params(self): 181*9c5db199SXin Li """Confirm passing of ssh parameters set as globals. 182*9c5db199SXin Li """ 183*9c5db199SXin Li factory.ssh_user = 'foo' 184*9c5db199SXin Li factory.ssh_pass = 'bar' 185*9c5db199SXin Li factory.ssh_port = 1 186*9c5db199SXin Li factory.ssh_verbosity_flag = 'baz' 187*9c5db199SXin Li factory.ssh_options = 'zip' 188*9c5db199SXin Li machine = _gen_machine_dict() 189*9c5db199SXin Li try: 190*9c5db199SXin Li host_obj = factory.create_host(machine) 191*9c5db199SXin Li self.assertEqual(host_obj._init_args['user'], 'foo') 192*9c5db199SXin Li self.assertEqual(host_obj._init_args['password'], 'bar') 193*9c5db199SXin Li self.assertEqual(host_obj._init_args['port'], 1) 194*9c5db199SXin Li self.assertEqual(host_obj._init_args['ssh_verbosity_flag'], 'baz') 195*9c5db199SXin Li self.assertEqual(host_obj._init_args['ssh_options'], 'zip') 196*9c5db199SXin Li finally: 197*9c5db199SXin Li del factory.ssh_user 198*9c5db199SXin Li del factory.ssh_pass 199*9c5db199SXin Li del factory.ssh_port 200*9c5db199SXin Li del factory.ssh_verbosity_flag 201*9c5db199SXin Li del factory.ssh_options 202*9c5db199SXin Li 203*9c5db199SXin Li 204*9c5db199SXin Li def test_host_attribute_ssh_params(self): 205*9c5db199SXin Li """Confirm passing of ssh parameters from host attributes. 206*9c5db199SXin Li """ 207*9c5db199SXin Li machine = _gen_machine_dict(attributes={'ssh_user': 'somebody', 208*9c5db199SXin Li 'ssh_port': 100, 209*9c5db199SXin Li 'ssh_verbosity_flag': 'verb', 210*9c5db199SXin Li 'ssh_options': 'options'}) 211*9c5db199SXin Li host_obj = factory.create_host(machine) 212*9c5db199SXin Li self.assertEqual(host_obj._init_args['user'], 'somebody') 213*9c5db199SXin Li self.assertEqual(host_obj._init_args['port'], 100) 214*9c5db199SXin Li self.assertEqual(host_obj._init_args['ssh_verbosity_flag'], 'verb') 215*9c5db199SXin Li self.assertEqual(host_obj._init_args['ssh_options'], 'options') 216*9c5db199SXin Li 217*9c5db199SXin Li 218*9c5db199SXin Liif __name__ == '__main__': 219*9c5db199SXin Li unittest.main() 220*9c5db199SXin Li 221