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