# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from unittest import mock from keystoneauth1 import adapter from openstack.common import metadata from openstack import exceptions from openstack import resource from openstack.tests.unit import base from openstack.tests.unit.test_resource import FakeResponse IDENTIFIER = 'IDENTIFIER' class TestMetadata(base.TestCase): def setUp(self): super(TestMetadata, self).setUp() self.service_name = "service" self.base_path = "base_path" self.metadata_result = {"metadata": {"go": "cubs", "boo": "sox"}} self.meta_result = {"meta": {"oh": "yeah"}} class Test(resource.Resource, metadata.MetadataMixin): service = self.service_name base_path = self.base_path resources_key = 'resources' allow_create = True allow_fetch = True allow_head = True allow_commit = True allow_delete = True allow_list = True self.test_class = Test self.request = mock.Mock(spec=resource._Request) self.request.url = "uri" self.request.body = "body" self.request.headers = "headers" self.response = FakeResponse({}) self.sot = Test.new(id="id") self.sot._prepare_request = mock.Mock(return_value=self.request) self.sot._translate_response = mock.Mock() self.session = mock.Mock(spec=adapter.Adapter) self.session.get = mock.Mock(return_value=self.response) self.session.put = mock.Mock(return_value=self.response) self.session.post = mock.Mock(return_value=self.response) self.session.delete = mock.Mock(return_value=self.response) def test_metadata_attribute(self): res = self.sot self.assertTrue(hasattr(res, 'metadata')) def test_get_metadata(self): res = self.sot mock_response = mock.Mock() mock_response.status_code = 200 mock_response.links = {} mock_response.json.return_value = {'metadata': {'foo': 'bar'}} self.session.get.side_effect = [mock_response] result = res.fetch_metadata(self.session) # Check metadata attribute is updated self.assertDictEqual({'foo': 'bar'}, result.metadata) # Check passed resource is returned self.assertEqual(res, result) url = self.base_path + '/' + res.id + '/metadata' self.session.get.assert_called_once_with(url) def test_set_metadata(self): res = self.sot result = res.set_metadata(self.session, {'foo': 'bar'}) # Check metadata attribute is updated self.assertDictEqual({'foo': 'bar'}, res.metadata) # Check passed resource is returned self.assertEqual(res, result) url = self.base_path + '/' + res.id + '/metadata' self.session.post.assert_called_once_with( url, json={'metadata': {'foo': 'bar'}} ) def test_replace_metadata(self): res = self.sot result = res.replace_metadata(self.session, {'foo': 'bar'}) # Check metadata attribute is updated self.assertDictEqual({'foo': 'bar'}, res.metadata) # Check passed resource is returned self.assertEqual(res, result) url = self.base_path + '/' + res.id + '/metadata' self.session.put.assert_called_once_with( url, json={'metadata': {'foo': 'bar'}} ) def test_delete_all_metadata(self): res = self.sot # Set some initial value to check removal res.metadata = {'foo': 'bar'} result = res.delete_metadata(self.session) # Check metadata attribute is updated self.assertEqual({}, res.metadata) # Check passed resource is returned self.assertEqual(res, result) url = self.base_path + '/' + res.id + '/metadata' self.session.put.assert_called_once_with(url, json={'metadata': {}}) def test_get_metadata_item(self): res = self.sot mock_response = mock.Mock() mock_response.status_code = 200 mock_response.json.return_value = {'meta': {'foo': 'bar'}} self.session.get.side_effect = [mock_response] result = res.get_metadata_item(self.session, 'foo') # Check tags attribute is updated self.assertEqual({'foo': 'bar'}, res.metadata) # Check the passed resource is returned self.assertEqual(res, result) url = self.base_path + '/' + res.id + '/metadata/foo' self.session.get.assert_called_once_with(url) def test_delete_single_item(self): res = self.sot res.metadata = {'foo': 'bar', 'foo2': 'bar2'} result = res.delete_metadata_item(self.session, 'foo2') # Check metadata attribute is updated self.assertEqual({'foo': 'bar'}, res.metadata) # Check passed resource is returned self.assertEqual(res, result) url = self.base_path + '/' + res.id + '/metadata/foo2' self.session.delete.assert_called_once_with(url) def test_delete_signle_item_empty(self): res = self.sot result = res.delete_metadata_item(self.session, 'foo2') # Check metadata attribute is updated self.assertEqual({}, res.metadata) # Check passed resource is returned self.assertEqual(res, result) url = self.base_path + '/' + res.id + '/metadata/foo2' self.session.delete.assert_called_once_with(url) def test_get_metadata_item_not_exists(self): res = self.sot mock_response = mock.Mock() mock_response.status_code = 404 mock_response.content = None self.session.get.side_effect = [mock_response] # ensure we get 404 self.assertRaises( exceptions.NotFoundException, res.get_metadata_item, self.session, 'dummy', ) def test_set_metadata_item(self): res = self.sot # Set some initial value to check add res.metadata = {'foo': 'bar'} result = res.set_metadata_item(self.session, 'foo', 'black') # Check metadata attribute is updated self.assertEqual({'foo': 'black'}, res.metadata) # Check passed resource is returned self.assertEqual(res, result) url = self.base_path + '/' + res.id + '/metadata/foo' self.session.put.assert_called_once_with( url, json={'meta': {'foo': 'black'}} )