1#!/usr/bin/python 2# 3# Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7import unittest 8 9import common 10from autotest_lib.client.common_lib.test_utils import unittest 11from autotest_lib.frontend import setup_django_environment 12from autotest_lib.frontend.afe import frontend_test_utils 13from autotest_lib.frontend.afe import rdb_model_extensions as rdb_models 14from autotest_lib.scheduler import rdb_hosts 15from autotest_lib.scheduler import rdb_testing_utils 16from autotest_lib.scheduler import rdb_utils 17 18 19class RDBHostTests(unittest.TestCase, frontend_test_utils.FrontendTestMixin): 20 """Unittests for RDBHost objects.""" 21 22 def setUp(self): 23 self.db_helper = rdb_testing_utils.DBHelper() 24 self._database = self.db_helper.database 25 # Runs syncdb setting up initial database conditions 26 self._frontend_common_setup() 27 28 29 def tearDown(self): 30 self._database.disconnect() 31 self._frontend_common_teardown() 32 33 34 def testWireFormat(self): 35 """Test that we can create a client host with the server host's fields. 36 37 Get the wire_format fields of an RDBServerHostWrapper and use them to 38 create an RDBClientHostWrapper. 39 40 @raises AssertionError: If the labels and acls don't match up after 41 going through the complete wire_format conversion, of the bare 42 wire_format conversion also converts labels and acls. 43 @raises RDBException: If some critical fields were lost during 44 wire_format conversion, as we won't be able to construct the 45 RDBClientHostWrapper. 46 """ 47 labels = set(['a', 'b', 'c']) 48 acls = set(['d', 'e']) 49 server_host = rdb_hosts.RDBServerHostWrapper( 50 self.db_helper.create_host('h1', deps=labels, acls=acls)) 51 acl_ids = set([aclgroup.id for aclgroup in 52 self.db_helper.get_acls(name__in=acls)]) 53 label_ids = set([label.id for label in 54 self.db_helper.get_labels(name__in=labels)]) 55 56 # The RDBServerHostWrapper keeps ids of labels/acls to perform 57 # comparison operations within the rdb, but converts labels to 58 # strings because this is the format the scheduler expects them in. 59 self.assertTrue(set(server_host.labels) == label_ids and 60 set(server_host.acls) == acl_ids) 61 62 formatted_server_host = server_host.wire_format() 63 client_host = rdb_hosts.RDBClientHostWrapper(**formatted_server_host) 64 self.assertTrue(set(client_host.labels) == labels and 65 set(client_host.acls) == acl_ids) 66 bare_formatted_server_host = server_host.wire_format( 67 unwrap_foreign_keys=False) 68 self.assertTrue(bare_formatted_server_host.get('labels') is None and 69 bare_formatted_server_host.get('acls') is None) 70 71 72 def testLeasing(self): 73 """Test that leasing a leased host raises an exception. 74 75 @raises AssertionError: If double leasing a host doesn't raise 76 an RDBException, or the leased bits are not set after the 77 first attempt at leasing it. 78 @raises RDBException: If the host is created with the leased bit set. 79 """ 80 hostname = 'h1' 81 server_host = rdb_hosts.RDBServerHostWrapper( 82 self.db_helper.create_host(hostname)) 83 server_host.lease() 84 host = self.db_helper.get_host(hostname=hostname)[0] 85 self.assertTrue(host.leased and server_host.leased) 86 self.assertRaises(rdb_utils.RDBException, server_host.lease) 87 88 89 def testPlatformAndLabels(self): 90 """Test that a client host returns the right platform and labels. 91 92 @raises AssertionError: If client host cannot return the right platform 93 and labels. 94 """ 95 platform_name = 'x86' 96 label_names = ['a', 'b'] 97 self.db_helper.create_label(name=platform_name, platform=True) 98 server_host = rdb_hosts.RDBServerHostWrapper( 99 self.db_helper.create_host( 100 'h1', deps=set(label_names + [platform_name]))) 101 client_host = rdb_hosts.RDBClientHostWrapper( 102 **server_host.wire_format()) 103 platform, labels = client_host.platform_and_labels() 104 self.assertTrue(platform == platform_name) 105 self.assertTrue(set(labels) == set(label_names)) 106 107 108 def testClientUpdateSave(self): 109 """Test that a client host is capable of saving its attributes. 110 111 Create a client host, set its attributes and verify that the attributes 112 are saved properly by recreating a server host and checking them. 113 114 @raises AssertionError: If the server host has the wrong attributes. 115 """ 116 hostname = 'h1' 117 db_host = self.db_helper.create_host(hostname, leased=True) 118 server_host_dict = rdb_hosts.RDBServerHostWrapper(db_host).wire_format() 119 client_host = rdb_hosts.RDBClientHostWrapper(**server_host_dict) 120 121 host_data = {'hostname': hostname, 'id': db_host.id} 122 default_values = rdb_models.AbstractHostModel.provide_default_values( 123 host_data) 124 for k, v in default_values.iteritems(): 125 self.assertTrue(server_host_dict[k] == v) 126 127 updated_client_fields = { 128 'locked': True, 129 'leased': False, 130 'status': 'FakeStatus', 131 'invalid': True, 132 'protection': 1, 133 'dirty': True, 134 } 135 client_host.__dict__.update(updated_client_fields) 136 client_host.save() 137 138 updated_server_host = rdb_hosts.RDBServerHostWrapper( 139 self.db_helper.get_host(hostname=hostname)[0]).wire_format() 140 for k, v in updated_client_fields.iteritems(): 141 self.assertTrue(updated_server_host[k] == v) 142 143 144 def testUpdateField(self): 145 """Test that update field on the client host works as expected. 146 147 @raises AssertionError: If a bad update is processed without an 148 exception, of a good update isn't processed as expected. 149 """ 150 hostname = 'h1' 151 db_host = self.db_helper.create_host(hostname, dirty=False) 152 server_host_dict = rdb_hosts.RDBServerHostWrapper(db_host).wire_format() 153 client_host = rdb_hosts.RDBClientHostWrapper(**server_host_dict) 154 self.assertRaises(rdb_utils.RDBException, client_host.update_field, 155 *('id', 'fakeid')) 156 self.assertRaises(rdb_utils.RDBException, client_host.update_field, 157 *('Nonexist', 'Nonexist')) 158 client_host.update_field('dirty', True) 159 self.assertTrue( 160 self.db_helper.get_host(hostname=hostname)[0].dirty == True and 161 client_host.dirty == True) 162 new_status = 'newstatus' 163 client_host.set_status(new_status) 164 self.assertTrue( 165 self.db_helper.get_host(hostname=hostname)[0].status == 166 new_status and client_host.status == new_status) 167 168 169if __name__ == '__main__': 170 unittest.main() 171