| # Copyright 2017 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import mock |
| import unittest |
| |
| import common |
| from autotest_lib.frontend.afe.json_rpc import proxy as rpc_proxy |
| from autotest_lib.server import frontend |
| from autotest_lib.server.hosts import afe_store |
| from autotest_lib.server.hosts import host_info |
| |
| class AfeStoreTest(unittest.TestCase): |
| """Test refresh/commit success cases for AfeStore.""" |
| |
| def setUp(self): |
| self.hostname = 'some-host' |
| self.mock_afe = mock.create_autospec(frontend.AFE, instance=True) |
| self.store = afe_store.AfeStore(self.hostname, afe=self.mock_afe) |
| |
| |
| def _create_mock_host(self, labels, attributes): |
| """Create a mock frontend.Host with the given labels and attributes. |
| |
| @param labels: The labels to set on the host. |
| @param attributes: The attributes to set on the host. |
| @returns: A mock object for frontend.Host. |
| """ |
| mock_host = mock.create_autospec(frontend.Host, instance=True) |
| mock_host.labels = labels |
| mock_host.attributes = attributes |
| return mock_host |
| |
| |
| def test_refresh(self): |
| """Test that refresh correctly translates host information.""" |
| self.mock_afe.get_hosts.return_value = [ |
| self._create_mock_host(['label1'], {'attrib1': 'val1'})] |
| info = self.store._refresh_impl() |
| self.assertListEqual(info.labels, ['label1']) |
| self.assertDictEqual(info.attributes, {'attrib1': 'val1'}) |
| |
| |
| def test_refresh_no_host_raises(self): |
| """Test that refresh complains if no host is found.""" |
| self.mock_afe.get_hosts.return_value = [] |
| with self.assertRaises(host_info.StoreError): |
| self.store._refresh_impl() |
| |
| |
| def test_refresh_multiple_hosts_picks_first(self): |
| """Test that refresh returns the first host if multiple match.""" |
| self.mock_afe.get_hosts.return_value = [ |
| self._create_mock_host(['label1'], {'attrib1': 'val1'}), |
| self._create_mock_host(['label2'], {'attrib2': 'val2'})] |
| info = self.store._refresh_impl() |
| self.assertListEqual(info.labels, ['label1']) |
| self.assertDictEqual(info.attributes, {'attrib1': 'val1'}) |
| |
| |
| def test_commit_labels(self): |
| """Tests that labels are updated correctly on commit.""" |
| self.mock_afe.get_hosts.return_value = [ |
| self._create_mock_host(['label1'], {})] |
| info = host_info.HostInfo(['label2'], {}) |
| self.store._commit_impl(info) |
| self.assertEqual(self.mock_afe.run.call_count, 2) |
| expected_run_calls = [ |
| mock.call('host_remove_labels', id='some-host', |
| labels={'label1'}), |
| mock.call('host_add_labels', id='some-host', |
| labels={'label2'}), |
| ] |
| self.mock_afe.run.assert_has_calls(expected_run_calls, |
| any_order=True) |
| |
| |
| def test_commit_labels_raises(self): |
| """Test that exception while committing is translated properly.""" |
| self.mock_afe.get_hosts.return_value = [ |
| self._create_mock_host(['label1'], {})] |
| self.mock_afe.run.side_effect = rpc_proxy.JSONRPCException('some error') |
| info = host_info.HostInfo(['label2'], {}) |
| with self.assertRaises(host_info.StoreError): |
| self.store._commit_impl(info) |
| |
| |
| def test_committing_attributes_warns(self): |
| """Test that a warning is issued if attribute changes are committed.""" |
| self.mock_afe.get_hosts.return_value = [ |
| self._create_mock_host([], {})] |
| info = host_info.HostInfo([], {'attrib': 'val'}) |
| with mock.patch('logging.warning', autospec=True) as mock_warning: |
| self.store._commit_impl(info) |
| self.assertEqual(mock_warning.call_count, 1) |
| self.assertRegexpMatches( |
| mock_warning.call_args[0][0], |
| '.*Updating attributes is currently not supported.*') |
| |
| |
| @unittest.expectedFailure |
| def test_commit_adds_attributes(self): |
| """Tests that new attributes are added correctly on commit.""" |
| self.mock_afe.get_hosts.return_value = [ |
| self._create_mock_host([], {})] |
| info = host_info.HostInfo([], {'attrib1': 'val1'}) |
| self.store._commit_impl(info) |
| self.assertEqual(self.mock_afe.set_host_attribute.call_count, 1) |
| self.mock_afe.assert_called_once_with('attrib1', 'val1', |
| hostname=self.hostname) |
| |
| |
| @unittest.expectedFailure |
| def test_commit_updates_attributes(self): |
| """Tests that existing attributes are updated correctly on commit.""" |
| self.mock_afe.get_hosts.return_value = [ |
| self._create_mock_host([], {'attrib1': 'val1'})] |
| info = host_info.HostInfo([], {'attrib1': 'val1_updated'}) |
| self.store._commit_impl(info) |
| self.assertEqual(self.mock_afe.set_host_attribute.call_count, 1) |
| self.mock_afe.assert_called_once_with('attrib1', 'val1_updated', |
| hostname=self.hostname) |
| |
| |
| @unittest.expectedFailure |
| def test_commit_deletes_attributes(self): |
| """Tests that deleted attributes are updated correctly on commit.""" |
| self.mock_afe.get_hosts.return_value = [ |
| self._create_mock_host([], {'attrib1': 'val1'})] |
| info = host_info.HostInfo([], {}) |
| self.store._commit_impl(info) |
| self.assertEqual(self.mock_afe.set_host_attribute.call_count, 1) |
| self.mock_afe.assert_called_once_with('attrib1', None, |
| hostname=self.hostname) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |