Home | History | Annotate | Download | only in hosts
      1 # Copyright 2017 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 
      5 import mock
      6 import unittest
      7 
      8 import common
      9 from autotest_lib.frontend.afe.json_rpc import proxy as rpc_proxy
     10 from autotest_lib.server import frontend
     11 from autotest_lib.server.hosts import afe_store
     12 from autotest_lib.server.hosts import host_info
     13 
     14 class AfeStoreTest(unittest.TestCase):
     15     """Test refresh/commit success cases for AfeStore."""
     16 
     17     def setUp(self):
     18         self.hostname = 'some-host'
     19         self.mock_afe = mock.create_autospec(frontend.AFE, instance=True)
     20         self.store = afe_store.AfeStore(self.hostname, afe=self.mock_afe)
     21 
     22 
     23     def _create_mock_host(self, labels, attributes):
     24         """Create a mock frontend.Host with the given labels and attributes.
     25 
     26         @param labels: The labels to set on the host.
     27         @param attributes: The attributes to set on the host.
     28         @returns: A mock object for frontend.Host.
     29         """
     30         mock_host = mock.create_autospec(frontend.Host, instance=True)
     31         mock_host.labels = labels
     32         mock_host.attributes = attributes
     33         return mock_host
     34 
     35 
     36     def test_refresh(self):
     37         """Test that refresh correctly translates host information."""
     38         self.mock_afe.get_hosts.return_value = [
     39                 self._create_mock_host(['label1'], {'attrib1': 'val1'})]
     40         info = self.store._refresh_impl()
     41         self.assertListEqual(info.labels, ['label1'])
     42         self.assertDictEqual(info.attributes, {'attrib1': 'val1'})
     43 
     44 
     45     def test_refresh_no_host_raises(self):
     46         """Test that refresh complains if no host is found."""
     47         self.mock_afe.get_hosts.return_value = []
     48         with self.assertRaises(host_info.StoreError):
     49             self.store._refresh_impl()
     50 
     51 
     52     def test_refresh_multiple_hosts_picks_first(self):
     53         """Test that refresh returns the first host if multiple match."""
     54         self.mock_afe.get_hosts.return_value = [
     55                 self._create_mock_host(['label1'], {'attrib1': 'val1'}),
     56                 self._create_mock_host(['label2'], {'attrib2': 'val2'})]
     57         info = self.store._refresh_impl()
     58         self.assertListEqual(info.labels, ['label1'])
     59         self.assertDictEqual(info.attributes, {'attrib1': 'val1'})
     60 
     61 
     62     def test_commit_labels(self):
     63         """Tests that labels are updated correctly on commit."""
     64         self.mock_afe.get_hosts.return_value = [
     65                 self._create_mock_host(['label1'], {})]
     66         info = host_info.HostInfo(['label2'], {})
     67         self.store._commit_impl(info)
     68         self.assertEqual(self.mock_afe.run.call_count, 2)
     69         expected_run_calls = [
     70                 mock.call('host_remove_labels', id='some-host',
     71                           labels={'label1'}),
     72                 mock.call('host_add_labels', id='some-host',
     73                           labels={'label2'}),
     74         ]
     75         self.mock_afe.run.assert_has_calls(expected_run_calls,
     76                                            any_order=True)
     77 
     78 
     79     def test_commit_labels_raises(self):
     80         """Test that exception while committing is translated properly."""
     81         self.mock_afe.get_hosts.return_value = [
     82                 self._create_mock_host(['label1'], {})]
     83         self.mock_afe.run.side_effect = rpc_proxy.JSONRPCException('some error')
     84         info = host_info.HostInfo(['label2'], {})
     85         with self.assertRaises(host_info.StoreError):
     86             self.store._commit_impl(info)
     87 
     88 
     89     def test_committing_attributes_warns(self):
     90         """Test that a warning is issued if attribute changes are committed."""
     91         self.mock_afe.get_hosts.return_value = [
     92                 self._create_mock_host([], {})]
     93         info = host_info.HostInfo([], {'attrib': 'val'})
     94         with mock.patch('logging.warning', autospec=True) as mock_warning:
     95             self.store._commit_impl(info)
     96         self.assertEqual(mock_warning.call_count, 1)
     97         self.assertRegexpMatches(
     98                 mock_warning.call_args[0][0],
     99                 '.*Updating attributes is currently not supported.*')
    100 
    101 
    102     @unittest.expectedFailure
    103     def test_commit_adds_attributes(self):
    104         """Tests that new attributes are added correctly on commit."""
    105         self.mock_afe.get_hosts.return_value = [
    106                 self._create_mock_host([], {})]
    107         info = host_info.HostInfo([], {'attrib1': 'val1'})
    108         self.store._commit_impl(info)
    109         self.assertEqual(self.mock_afe.set_host_attribute.call_count, 1)
    110         self.mock_afe.assert_called_once_with('attrib1', 'val1',
    111                                               hostname=self.hostname)
    112 
    113 
    114     @unittest.expectedFailure
    115     def test_commit_updates_attributes(self):
    116         """Tests that existing attributes are updated correctly on commit."""
    117         self.mock_afe.get_hosts.return_value = [
    118                 self._create_mock_host([], {'attrib1': 'val1'})]
    119         info = host_info.HostInfo([], {'attrib1': 'val1_updated'})
    120         self.store._commit_impl(info)
    121         self.assertEqual(self.mock_afe.set_host_attribute.call_count, 1)
    122         self.mock_afe.assert_called_once_with('attrib1', 'val1_updated',
    123                                               hostname=self.hostname)
    124 
    125 
    126     @unittest.expectedFailure
    127     def test_commit_deletes_attributes(self):
    128         """Tests that deleted attributes are updated correctly on commit."""
    129         self.mock_afe.get_hosts.return_value = [
    130                 self._create_mock_host([], {'attrib1': 'val1'})]
    131         info = host_info.HostInfo([], {})
    132         self.store._commit_impl(info)
    133         self.assertEqual(self.mock_afe.set_host_attribute.call_count, 1)
    134         self.mock_afe.assert_called_once_with('attrib1', None,
    135                                               hostname=self.hostname)
    136 
    137 
    138 if __name__ == '__main__':
    139     unittest.main()
    140