hacking 3.0.x is really old. Let's bump it to the latest version available. This also fixes some errors detected but some rules are excluded now. See the comments in tox.ini for further details. Change-Id: I2565e5f5e791dfdd9bbc1890b35c413965d83626
892 lines
38 KiB
Python
892 lines
38 KiB
Python
# 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 exceptions as ks_exc
|
|
from keystoneauth1 import loading as keystone
|
|
from oslo_serialization import jsonutils
|
|
from oslo_utils import uuidutils
|
|
|
|
from neutron_lib._i18n import _
|
|
from neutron_lib.exceptions import placement as n_exc
|
|
from neutron_lib import fixture
|
|
from neutron_lib.placement import client as place_client
|
|
from neutron_lib.tests import _base as base
|
|
|
|
|
|
RESOURCE_PROVIDER_UUID = uuidutils.generate_uuid()
|
|
SECOND_RESOURCE_PROVIDER_UUID = uuidutils.generate_uuid()
|
|
CONSUMER_UUID = uuidutils.generate_uuid()
|
|
RESOURCE_PROVIDER_NAME = 'resource_provider_name'
|
|
RESOURCE_PROVIDER = {
|
|
'uuid': RESOURCE_PROVIDER_UUID,
|
|
'name': RESOURCE_PROVIDER_NAME,
|
|
}
|
|
RESOURCE_PROVIDER_GENERATION = 1
|
|
RESOURCE_CLASS_NAME = 'resource_class_name'
|
|
TRAIT_NAME = 'trait_name'
|
|
INVENTORY = {
|
|
RESOURCE_CLASS_NAME: {
|
|
'total': 42
|
|
}
|
|
}
|
|
|
|
|
|
class TestNoAuthClient(base.BaseTestCase):
|
|
|
|
def setUp(self):
|
|
super(TestNoAuthClient, self).setUp()
|
|
self.noauth_client = place_client.NoAuthClient('placement/')
|
|
self.body_json = jsonutils.dumps({'name': 'foo'})
|
|
self.uuid = '42'
|
|
|
|
@mock.patch.object(place_client.NoAuthClient, 'request')
|
|
def test_get(self, mock_request):
|
|
self.noauth_client.get('resource_providers', '')
|
|
mock_request.assert_called_with('placement/resource_providers', 'GET')
|
|
|
|
@mock.patch.object(place_client.NoAuthClient, 'request')
|
|
def test_post(self, mock_request):
|
|
self.noauth_client.post('resource_providers', self.body_json, '')
|
|
mock_request.assert_called_with('placement/resource_providers', 'POST',
|
|
body=self.body_json)
|
|
|
|
@mock.patch.object(place_client.NoAuthClient, 'request')
|
|
def test_put(self, mock_request):
|
|
self.noauth_client.put('resource_providers/%s' % self.uuid,
|
|
self.body_json, '')
|
|
mock_request.assert_called_with(
|
|
'placement/resource_providers/%s' % self.uuid, 'PUT',
|
|
body=self.body_json)
|
|
|
|
@mock.patch.object(place_client.NoAuthClient, 'request')
|
|
def test_delete(self, mock_request):
|
|
self.noauth_client.delete('resource_providers/%s' % self.uuid, '')
|
|
mock_request.assert_called_with(
|
|
'placement/resource_providers/%s' % self.uuid, 'DELETE')
|
|
|
|
|
|
class TestPlacementAPIClientNoAuth(base.BaseTestCase):
|
|
def setUp(self):
|
|
super(TestPlacementAPIClientNoAuth, self).setUp()
|
|
self.config = mock.Mock()
|
|
|
|
@mock.patch('neutron_lib.placement.client.NoAuthClient', autospec=True)
|
|
def test__create_client_noauth(self, mock_auth_client):
|
|
self.config.placement.auth_type = 'noauth'
|
|
self.config.placement.auth_section = 'placement/'
|
|
self.placement_api_client = place_client.PlacementAPIClient(
|
|
self.config)
|
|
self.placement_api_client._create_client()
|
|
mock_auth_client.assert_called_once_with('placement/')
|
|
|
|
@mock.patch.object(keystone, 'load_auth_from_conf_options')
|
|
@mock.patch.object(keystone, 'load_session_from_conf_options')
|
|
def test__create_client(self, mock_session_from_conf, mock_auth_from_conf):
|
|
self.config.placement.auth_type = 'password'
|
|
self.placement_api_client = place_client.PlacementAPIClient(
|
|
self.config)
|
|
self.placement_api_client._create_client()
|
|
mock_auth_from_conf.assert_called_once_with(self.config, 'placement')
|
|
mock_session_from_conf.assert_called_once()
|
|
|
|
|
|
class TestPlacementAPIClient(base.BaseTestCase):
|
|
|
|
def setUp(self):
|
|
super(TestPlacementAPIClient, self).setUp()
|
|
config = mock.Mock()
|
|
config.region_name = 'region_name'
|
|
self.openstack_api_version = (
|
|
place_client.PLACEMENT_API_LATEST_SUPPORTED)
|
|
self.placement_api_client = place_client.PlacementAPIClient(
|
|
config, self.openstack_api_version)
|
|
self.placement_fixture = self.useFixture(
|
|
fixture.PlacementAPIClientFixture(self.placement_api_client))
|
|
|
|
def test_create_resource_provider(self):
|
|
self.placement_api_client.create_resource_provider(
|
|
RESOURCE_PROVIDER)
|
|
self.placement_fixture.mock_post.assert_called_once_with(
|
|
'/resource_providers',
|
|
RESOURCE_PROVIDER
|
|
)
|
|
|
|
def test_update_resource_provider(self):
|
|
self.placement_api_client.update_resource_provider(
|
|
RESOURCE_PROVIDER)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/resource_providers/%s' % RESOURCE_PROVIDER_UUID,
|
|
{'name': RESOURCE_PROVIDER_NAME}
|
|
)
|
|
|
|
def test_ensure_update_resource_provider(self):
|
|
self.placement_api_client.ensure_resource_provider(
|
|
RESOURCE_PROVIDER)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/resource_providers/%s' % RESOURCE_PROVIDER_UUID,
|
|
{'name': RESOURCE_PROVIDER_NAME}
|
|
)
|
|
self.placement_fixture.mock_post.assert_not_called()
|
|
|
|
def test_ensure_create_resource_provider(self):
|
|
self.placement_fixture.mock_put.side_effect = \
|
|
n_exc.PlacementResourceProviderNotFound(
|
|
resource_provider=RESOURCE_PROVIDER_UUID)
|
|
self.placement_api_client.ensure_resource_provider(
|
|
RESOURCE_PROVIDER)
|
|
self.placement_fixture.mock_post.assert_called_once_with(
|
|
'/resource_providers',
|
|
RESOURCE_PROVIDER
|
|
)
|
|
|
|
def test_delete_resource_provider(self):
|
|
self.placement_api_client.delete_resource_provider(
|
|
RESOURCE_PROVIDER_UUID)
|
|
self.placement_fixture.mock_delete.assert_called_once_with(
|
|
'/resource_providers/%s' % RESOURCE_PROVIDER_UUID)
|
|
|
|
def test_get_resource_provider(self):
|
|
self.placement_api_client.get_resource_provider(RESOURCE_PROVIDER_UUID)
|
|
self.placement_fixture.mock_get.assert_called_once_with(
|
|
'/resource_providers/%s' % RESOURCE_PROVIDER_UUID)
|
|
|
|
def test_get_resource_provider_no_resource_provider(self):
|
|
self.placement_fixture.mock_get.side_effect = ks_exc.NotFound()
|
|
self.assertRaises(n_exc.PlacementResourceProviderNotFound,
|
|
self.placement_api_client.get_resource_provider,
|
|
RESOURCE_PROVIDER_UUID)
|
|
|
|
def test_list_resource_providers(self):
|
|
filter_1 = {'name': 'name1', 'in_tree': 'tree1_uuid'}
|
|
self.placement_api_client.list_resource_providers(**filter_1)
|
|
args = str(self.placement_fixture.mock_get.call_args)
|
|
self.placement_fixture.mock_get.assert_called_once()
|
|
self.assertIn('name=name1', args)
|
|
self.assertIn('in_tree=tree1_uuid', args)
|
|
|
|
filter_2 = {'member_of': ['aggregate_uuid'], 'uuid': 'uuid_1',
|
|
'resources': {'r_class1': 'value1'}}
|
|
self.placement_fixture.mock_get.reset_mock()
|
|
self.placement_api_client.list_resource_providers(**filter_2)
|
|
args = str(self.placement_fixture.mock_get.call_args)
|
|
self.placement_fixture.mock_get.assert_called_once()
|
|
self.assertIn('member_of', args)
|
|
self.assertIn('uuid', args)
|
|
self.assertIn('resources', args)
|
|
|
|
filter_1.update(filter_2)
|
|
self.placement_fixture.mock_get.reset_mock()
|
|
self.placement_api_client.list_resource_providers(**filter_1)
|
|
args = str(self.placement_fixture.mock_get.call_args)
|
|
self.placement_fixture.mock_get.assert_called_once()
|
|
for key in filter_1:
|
|
self.assertIn(key, args)
|
|
|
|
def test_list_resource_providers_placement_api_version_too_low(self):
|
|
self.placement_api_client._target_version = (1, 1)
|
|
self.assertRaises(
|
|
n_exc.PlacementAPIVersionIncorrect,
|
|
self.placement_api_client.list_resource_providers,
|
|
member_of=['aggregate_uuid'])
|
|
self.assertRaises(
|
|
n_exc.PlacementAPIVersionIncorrect,
|
|
self.placement_api_client.list_resource_providers,
|
|
in_tree='tree1_uuid')
|
|
|
|
def test_update_resource_provider_inventories_generation(self):
|
|
expected_body = {
|
|
'resource_provider_generation': RESOURCE_PROVIDER_GENERATION,
|
|
'inventories': INVENTORY
|
|
}
|
|
self.placement_api_client.update_resource_provider_inventories(
|
|
RESOURCE_PROVIDER_UUID, INVENTORY, RESOURCE_PROVIDER_GENERATION)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/resource_providers/%s/inventories' % RESOURCE_PROVIDER_UUID,
|
|
expected_body)
|
|
|
|
def test_update_resource_provider_inventories_no_generation(self):
|
|
expected_body = {
|
|
'resource_provider_generation': RESOURCE_PROVIDER_GENERATION,
|
|
'inventories': INVENTORY
|
|
}
|
|
with mock.patch.object(
|
|
self.placement_api_client, 'get_resource_provider',
|
|
return_value={'generation': RESOURCE_PROVIDER_GENERATION}):
|
|
self.placement_api_client.update_resource_provider_inventories(
|
|
RESOURCE_PROVIDER_UUID, INVENTORY)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/resource_providers/%s/inventories' % RESOURCE_PROVIDER_UUID,
|
|
expected_body)
|
|
|
|
def test_update_resource_provider_inventories_no_rp(self):
|
|
self.placement_fixture.mock_put.side_effect = ks_exc.NotFound()
|
|
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceProviderNotFound,
|
|
self.placement_api_client.update_resource_provider_inventories,
|
|
RESOURCE_PROVIDER_UUID, INVENTORY, RESOURCE_PROVIDER_GENERATION)
|
|
|
|
def test_delete_resource_provider_inventory(self):
|
|
self.placement_api_client.delete_resource_provider_inventory(
|
|
RESOURCE_PROVIDER_UUID, RESOURCE_CLASS_NAME
|
|
)
|
|
self.placement_fixture.mock_delete.assert_called_once_with(
|
|
'/resource_providers/%(rp_uuid)s/inventories/%(rc_name)s' %
|
|
{'rp_uuid': RESOURCE_PROVIDER_UUID,
|
|
'rc_name': RESOURCE_CLASS_NAME}
|
|
)
|
|
|
|
def test_delete_resource_provider_inventory_no_rp(self):
|
|
self.placement_fixture.mock_delete.side_effect = ks_exc.NotFound(
|
|
details='No resource provider with uuid'
|
|
)
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceProviderNotFound,
|
|
self.placement_api_client.delete_resource_provider_inventory,
|
|
RESOURCE_PROVIDER_UUID,
|
|
RESOURCE_CLASS_NAME
|
|
)
|
|
|
|
def test_get_inventory(self):
|
|
self.placement_api_client.get_inventory(RESOURCE_PROVIDER_UUID,
|
|
RESOURCE_CLASS_NAME)
|
|
self.placement_fixture.mock_get.assert_called_once_with(
|
|
'/resource_providers/%(rp_uuid)s/inventories/%(rc_name)s' %
|
|
{'rp_uuid': RESOURCE_PROVIDER_UUID,
|
|
'rc_name': RESOURCE_CLASS_NAME})
|
|
|
|
def test_get_inventory_no_resource_provider(self):
|
|
_exception = ks_exc.NotFound()
|
|
_exception.details = "No resource provider with uuid"
|
|
self.placement_fixture.mock_get.side_effect = _exception
|
|
self.assertRaises(n_exc.PlacementResourceProviderNotFound,
|
|
self.placement_api_client.get_inventory,
|
|
RESOURCE_PROVIDER_UUID, RESOURCE_CLASS_NAME)
|
|
|
|
def test_get_inventory_no_inventory(self):
|
|
_exception = ks_exc.NotFound()
|
|
_exception.details = _("No inventory of class")
|
|
self.placement_fixture.mock_get.side_effect = _exception
|
|
self.assertRaises(n_exc.PlacementInventoryNotFound,
|
|
self.placement_api_client.get_inventory,
|
|
RESOURCE_PROVIDER_UUID, RESOURCE_CLASS_NAME)
|
|
|
|
def test_get_inventory_not_found(self):
|
|
_exception = ks_exc.NotFound()
|
|
_exception.details = "Any other exception explanation"
|
|
_exception.response = mock.Mock(text="Some error response body")
|
|
self.placement_fixture.mock_get.side_effect = _exception
|
|
self.assertRaises(n_exc.PlacementClientError,
|
|
self.placement_api_client.get_inventory,
|
|
RESOURCE_PROVIDER_UUID, RESOURCE_CLASS_NAME)
|
|
|
|
def test_update_resource_provider_inventory_generation(self):
|
|
expected_body = {
|
|
'resource_provider_generation': RESOURCE_PROVIDER_GENERATION,
|
|
}
|
|
expected_body.update(INVENTORY)
|
|
self.placement_api_client.update_resource_provider_inventory(
|
|
RESOURCE_PROVIDER_UUID, INVENTORY, RESOURCE_CLASS_NAME,
|
|
resource_provider_generation=1)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/resource_providers/%(rp_uuid)s/inventories/%(rc_name)s' %
|
|
{'rp_uuid': RESOURCE_PROVIDER_UUID,
|
|
'rc_name': RESOURCE_CLASS_NAME},
|
|
expected_body)
|
|
|
|
def test_update_resource_provider_inventory_no_generation(self):
|
|
expected_body = {
|
|
'resource_provider_generation': RESOURCE_PROVIDER_GENERATION,
|
|
}
|
|
expected_body.update(INVENTORY)
|
|
with mock.patch.object(
|
|
self.placement_api_client, 'get_resource_provider',
|
|
return_value={'generation': RESOURCE_PROVIDER_GENERATION}):
|
|
self.placement_api_client.update_resource_provider_inventory(
|
|
RESOURCE_PROVIDER_UUID, INVENTORY, RESOURCE_CLASS_NAME)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/resource_providers/%(rp_uuid)s/inventories/%(rc_name)s' %
|
|
{'rp_uuid': RESOURCE_PROVIDER_UUID,
|
|
'rc_name': RESOURCE_CLASS_NAME},
|
|
expected_body)
|
|
|
|
def test_update_resource_provider_inventory_not_found(self):
|
|
# Test the resource provider not found case
|
|
self.placement_fixture.mock_put.side_effect = ks_exc.NotFound(
|
|
details="No resource provider with uuid")
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceNotFound,
|
|
self.placement_api_client.update_resource_provider_inventory,
|
|
RESOURCE_PROVIDER_UUID, INVENTORY,
|
|
RESOURCE_CLASS_NAME, RESOURCE_PROVIDER_GENERATION)
|
|
|
|
def test_associate_aggregates(self):
|
|
self.placement_api_client.associate_aggregates(RESOURCE_PROVIDER_UUID,
|
|
mock.ANY)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/resource_providers/%s/aggregates' % RESOURCE_PROVIDER_UUID,
|
|
mock.ANY)
|
|
|
|
def test_list_aggregates(self):
|
|
self.placement_api_client.list_aggregates(RESOURCE_PROVIDER_UUID)
|
|
self.placement_fixture.mock_get.assert_called_once_with(
|
|
'/resource_providers/%s/aggregates' % RESOURCE_PROVIDER_UUID)
|
|
|
|
def test_list_aggregates_no_resource_provider(self):
|
|
self.placement_fixture.mock_get.side_effect = ks_exc.NotFound()
|
|
self.assertRaises(n_exc.PlacementAggregateNotFound,
|
|
self.placement_api_client.list_aggregates,
|
|
RESOURCE_PROVIDER_UUID)
|
|
|
|
def test_list_traits(self):
|
|
self.placement_api_client.list_traits()
|
|
self.placement_fixture.mock_get.assert_called_once_with(
|
|
'/traits')
|
|
|
|
def test_get_trait(self):
|
|
self.placement_api_client.get_trait(TRAIT_NAME)
|
|
self.placement_fixture.mock_get.assert_called_once_with(
|
|
'/traits/%s' % TRAIT_NAME)
|
|
|
|
def test_get_trait_no_trait(self):
|
|
self.placement_fixture.mock_get.side_effect = ks_exc.NotFound()
|
|
self.assertRaises(
|
|
n_exc.PlacementTraitNotFound,
|
|
self.placement_api_client.get_trait,
|
|
TRAIT_NAME)
|
|
|
|
def test_create_trait(self):
|
|
self.placement_api_client.update_trait(TRAIT_NAME)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/traits/%s' % TRAIT_NAME, None)
|
|
|
|
def test_update_resource_provider_traits_generation(self):
|
|
traits = [TRAIT_NAME]
|
|
self.placement_api_client.update_resource_provider_traits(
|
|
RESOURCE_PROVIDER_UUID, traits,
|
|
resource_provider_generation=RESOURCE_PROVIDER_GENERATION)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/resource_providers/%(rp_uuid)s/traits' %
|
|
{'rp_uuid': RESOURCE_PROVIDER_UUID},
|
|
{'resource_provider_generation': RESOURCE_PROVIDER_GENERATION,
|
|
'traits': traits})
|
|
|
|
def test_update_resource_provider_traits_no_generation(self):
|
|
traits = [TRAIT_NAME]
|
|
with mock.patch.object(
|
|
self.placement_api_client, 'get_resource_provider',
|
|
return_value={'generation': RESOURCE_PROVIDER_GENERATION}):
|
|
self.placement_api_client.update_resource_provider_traits(
|
|
RESOURCE_PROVIDER_UUID, traits)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/resource_providers/%(rp_uuid)s/traits' %
|
|
{'rp_uuid': RESOURCE_PROVIDER_UUID},
|
|
{'resource_provider_generation': RESOURCE_PROVIDER_GENERATION,
|
|
'traits': traits})
|
|
|
|
def test_update_resource_provider_traits_no_rp(self):
|
|
traits = [TRAIT_NAME]
|
|
self.placement_fixture.mock_put.side_effect = ks_exc.NotFound()
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceProviderNotFound,
|
|
self.placement_api_client.update_resource_provider_traits,
|
|
RESOURCE_PROVIDER_UUID, traits, resource_provider_generation=0)
|
|
|
|
def test_update_resource_provider_traits_trait_not_found(self):
|
|
traits = [TRAIT_NAME]
|
|
self.placement_fixture.mock_put.side_effect = ks_exc.BadRequest()
|
|
self.assertRaises(
|
|
n_exc.PlacementTraitNotFound,
|
|
self.placement_api_client.update_resource_provider_traits,
|
|
RESOURCE_PROVIDER_UUID, traits, resource_provider_generation=0)
|
|
|
|
def test_list_resource_provider_traits(self):
|
|
self.placement_api_client.list_resource_provider_traits(
|
|
RESOURCE_PROVIDER_UUID)
|
|
self.placement_fixture.mock_get.assert_called_once_with(
|
|
'/resource_providers/%s/traits' % RESOURCE_PROVIDER_UUID)
|
|
|
|
def test_list_resource_provider_traits_no_rp(self):
|
|
self.placement_fixture.mock_get.side_effect = ks_exc.NotFound()
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceProviderNotFound,
|
|
self.placement_api_client.list_resource_provider_traits,
|
|
RESOURCE_PROVIDER_UUID)
|
|
|
|
def test_delete_trait(self):
|
|
self.placement_api_client.delete_trait(TRAIT_NAME)
|
|
self.placement_fixture.mock_delete.assert_called_once_with(
|
|
'/traits/%s' % TRAIT_NAME)
|
|
|
|
def test_delete_trait_no_trait(self):
|
|
self.placement_fixture.mock_delete.side_effect = ks_exc.NotFound()
|
|
self.assertRaises(
|
|
n_exc.PlacementTraitNotFound,
|
|
self.placement_api_client.delete_trait,
|
|
TRAIT_NAME)
|
|
|
|
def test_delete_resource_provider_traits(self):
|
|
self.placement_api_client.delete_resource_provider_traits(
|
|
RESOURCE_PROVIDER_UUID)
|
|
self.placement_fixture.mock_delete.assert_called_once_with(
|
|
'/resource_providers/%s/traits' % RESOURCE_PROVIDER_UUID)
|
|
|
|
def test_delete_resource_provider_traits_no_rp(self):
|
|
self.placement_fixture.mock_delete.side_effect = ks_exc.NotFound()
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceProviderNotFound,
|
|
self.placement_api_client.delete_resource_provider_traits,
|
|
RESOURCE_PROVIDER_UUID)
|
|
|
|
def test_list_resource_classes(self):
|
|
self.placement_api_client.list_resource_classes()
|
|
self.placement_fixture.mock_get.assert_called_once_with(
|
|
'/resource_classes'
|
|
)
|
|
|
|
def test_get_resource_class(self):
|
|
self.placement_api_client.get_resource_class(RESOURCE_CLASS_NAME)
|
|
self.placement_fixture.mock_get.assert_called_once_with(
|
|
'/resource_classes/%s' % RESOURCE_CLASS_NAME
|
|
)
|
|
|
|
def test_get_resource_class_no_resource_class(self):
|
|
self.placement_fixture.mock_get.side_effect = ks_exc.NotFound()
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceClassNotFound,
|
|
self.placement_api_client.get_resource_class,
|
|
RESOURCE_CLASS_NAME
|
|
)
|
|
|
|
def test_create_resource_class(self):
|
|
self.placement_api_client.create_resource_class(RESOURCE_CLASS_NAME)
|
|
self.placement_fixture.mock_post.assert_called_once_with(
|
|
'/resource_classes',
|
|
{'name': RESOURCE_CLASS_NAME},
|
|
)
|
|
|
|
def test_update_resource_class(self):
|
|
self.placement_api_client.update_resource_class(RESOURCE_CLASS_NAME)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/resource_classes/%s' % RESOURCE_CLASS_NAME, None)
|
|
|
|
def test_delete_resource_class(self):
|
|
self.placement_api_client.delete_resource_class(RESOURCE_CLASS_NAME)
|
|
self.placement_fixture.mock_delete.assert_called_once_with(
|
|
'/resource_classes/%s' % RESOURCE_CLASS_NAME
|
|
)
|
|
|
|
def test_delete_resource_class_no_resource_class(self):
|
|
self.placement_fixture.mock_delete.side_effect = ks_exc.NotFound()
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceClassNotFound,
|
|
self.placement_api_client.delete_resource_class,
|
|
RESOURCE_CLASS_NAME
|
|
)
|
|
|
|
def test_update_rp_traits_caller_handles_generation_conflict(self):
|
|
mock_resp = mock.Mock()
|
|
mock_resp.text = ''
|
|
mock_resp.json = lambda: {
|
|
'errors': [{'code': 'placement.concurrent_update'}]}
|
|
self.placement_fixture.mock_put.side_effect = ks_exc.Conflict(
|
|
response=mock_resp)
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceProviderGenerationConflict,
|
|
self.placement_api_client.update_resource_provider_traits,
|
|
resource_provider_uuid='resource provider uuid',
|
|
traits=['trait a', 'trait b'],
|
|
resource_provider_generation=3,
|
|
)
|
|
self.placement_fixture.mock_put.assert_called_once()
|
|
|
|
def test_update_rp_traits_callee_handles_generation_conflict(self):
|
|
mock_resp = mock.Mock()
|
|
mock_resp.text = ''
|
|
mock_resp.json = lambda: {
|
|
'errors': [{'code': 'placement.concurrent_update'}]}
|
|
self.placement_fixture.mock_put.side_effect = [
|
|
ks_exc.Conflict(response=mock_resp),
|
|
mock.Mock(),
|
|
]
|
|
self.placement_api_client.update_resource_provider_traits(
|
|
resource_provider_uuid='resource provider uuid',
|
|
traits=['trait a', 'trait b'],
|
|
resource_provider_generation=None,
|
|
)
|
|
self.assertEqual(2, self.placement_fixture.mock_put.call_count)
|
|
|
|
def test_update_rp_traits_reached_max_tries(self):
|
|
mock_resp = mock.Mock()
|
|
mock_resp.text = ''
|
|
mock_resp.json = lambda: {
|
|
'errors': [{'code': 'placement.concurrent_update'}]}
|
|
self.placement_fixture.mock_put.side_effect = 10 * [
|
|
ks_exc.Conflict(response=mock_resp),
|
|
]
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceProviderGenerationConflict,
|
|
self.placement_api_client.update_resource_provider_traits,
|
|
resource_provider_uuid='resource provider uuid',
|
|
traits=['trait a', 'trait b'],
|
|
resource_provider_generation=None,
|
|
)
|
|
self.assertEqual(10, self.placement_fixture.mock_put.call_count)
|
|
|
|
def test_update_rp_traits_raise_other_conflict(self):
|
|
mock_resp = mock.Mock()
|
|
mock_resp.text = ''
|
|
mock_resp.json = lambda: {
|
|
'errors': [{'code': 'some_other_code'}]}
|
|
self.placement_fixture.mock_put.side_effect = [
|
|
ks_exc.Conflict(response=mock_resp),
|
|
mock.Mock(),
|
|
]
|
|
self.assertRaises(
|
|
n_exc.PlacementClientError,
|
|
self.placement_api_client.update_resource_provider_traits,
|
|
resource_provider_uuid='resource provider uuid',
|
|
traits=[],
|
|
resource_provider_generation=None,
|
|
)
|
|
self.assertEqual(1, self.placement_fixture.mock_put.call_count)
|
|
|
|
def test_update_rp_inventory_caller_handles_generation_conflict(self):
|
|
mock_resp = mock.Mock()
|
|
mock_resp.text = ''
|
|
mock_resp.json = lambda: {
|
|
'errors': [{'code': 'placement.concurrent_update'}]}
|
|
self.placement_fixture.mock_put.side_effect = ks_exc.Conflict(
|
|
response=mock_resp)
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceProviderGenerationConflict,
|
|
self.placement_api_client.update_resource_provider_inventory,
|
|
resource_provider_uuid='resource provider uuid',
|
|
inventory={},
|
|
resource_class='a resource class',
|
|
resource_provider_generation=3,
|
|
)
|
|
self.placement_fixture.mock_put.assert_called_once()
|
|
|
|
def test_update_rp_inventory_callee_handles_generation_conflict(self):
|
|
mock_resp = mock.Mock()
|
|
mock_resp.text = ''
|
|
mock_resp.json = lambda: {
|
|
'errors': [{'code': 'placement.concurrent_update'}]}
|
|
self.placement_fixture.mock_put.side_effect = [
|
|
ks_exc.Conflict(response=mock_resp),
|
|
mock.Mock(),
|
|
]
|
|
self.placement_api_client.update_resource_provider_inventory(
|
|
resource_provider_uuid='resource provider uuid',
|
|
inventory={},
|
|
resource_class='a resource class',
|
|
resource_provider_generation=None,
|
|
)
|
|
self.assertEqual(2, self.placement_fixture.mock_put.call_count)
|
|
|
|
def test_update_rp_inventory_reached_max_tries(self):
|
|
mock_resp = mock.Mock()
|
|
mock_resp.text = ''
|
|
mock_resp.json = lambda: {
|
|
'errors': [{'code': 'placement.concurrent_update'}]}
|
|
self.placement_fixture.mock_put.side_effect = 10 * [
|
|
ks_exc.Conflict(response=mock_resp),
|
|
]
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceProviderGenerationConflict,
|
|
self.placement_api_client.update_resource_provider_inventory,
|
|
resource_provider_uuid='resource provider uuid',
|
|
inventory={},
|
|
resource_class='a resource class',
|
|
resource_provider_generation=None,
|
|
)
|
|
self.assertEqual(10, self.placement_fixture.mock_put.call_count)
|
|
|
|
def test_update_rp_inventory_raise_other_conflict(self):
|
|
mock_resp = mock.Mock()
|
|
mock_resp.text = ''
|
|
mock_resp.json = lambda: {
|
|
'errors': [{'code': 'some_other_code'}]}
|
|
self.placement_fixture.mock_put.side_effect = [
|
|
ks_exc.Conflict(response=mock_resp),
|
|
mock.Mock(),
|
|
]
|
|
self.assertRaises(
|
|
n_exc.PlacementClientError,
|
|
self.placement_api_client.update_resource_provider_inventory,
|
|
resource_provider_uuid='resource provider uuid',
|
|
inventory={},
|
|
resource_class='a resource class',
|
|
resource_provider_generation=None,
|
|
)
|
|
self.assertEqual(1, self.placement_fixture.mock_put.call_count)
|
|
|
|
def test_update_rp_inventories_caller_handles_generation_conflict(self):
|
|
mock_resp = mock.Mock()
|
|
mock_resp.text = ''
|
|
mock_resp.json = lambda: {
|
|
'errors': [{'code': 'placement.concurrent_update'}]}
|
|
self.placement_fixture.mock_put.side_effect = ks_exc.Conflict(
|
|
response=mock_resp)
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceProviderGenerationConflict,
|
|
self.placement_api_client.update_resource_provider_inventories,
|
|
resource_provider_uuid='resource provider uuid',
|
|
inventories={},
|
|
resource_provider_generation=3,
|
|
)
|
|
self.placement_fixture.mock_put.assert_called_once()
|
|
|
|
def test_update_rp_inventories_callee_handles_generation_conflict(self):
|
|
mock_resp = mock.Mock()
|
|
mock_resp.text = ''
|
|
mock_resp.json = lambda: {
|
|
'errors': [{'code': 'placement.concurrent_update'}]}
|
|
self.placement_fixture.mock_put.side_effect = [
|
|
ks_exc.Conflict(response=mock_resp),
|
|
mock.Mock(),
|
|
]
|
|
self.placement_api_client.update_resource_provider_inventories(
|
|
resource_provider_uuid='resource provider uuid',
|
|
inventories={},
|
|
resource_provider_generation=None,
|
|
)
|
|
self.assertEqual(2, self.placement_fixture.mock_put.call_count)
|
|
|
|
def test_update_rp_inventories_reached_max_tries(self):
|
|
mock_resp = mock.Mock()
|
|
mock_resp.text = ''
|
|
mock_resp.json = lambda: {
|
|
'errors': [{'code': 'placement.concurrent_update'}]}
|
|
self.placement_fixture.mock_put.side_effect = 10 * [
|
|
ks_exc.Conflict(response=mock_resp),
|
|
]
|
|
self.assertRaises(
|
|
n_exc.PlacementResourceProviderGenerationConflict,
|
|
self.placement_api_client.update_resource_provider_inventories,
|
|
resource_provider_uuid='resource provider uuid',
|
|
inventories={},
|
|
resource_provider_generation=None,
|
|
)
|
|
self.assertEqual(10, self.placement_fixture.mock_put.call_count)
|
|
|
|
def test_update_rp_inventories_raise_other_conflict(self):
|
|
mock_resp = mock.Mock()
|
|
mock_resp.text = ''
|
|
mock_resp.json = lambda: {
|
|
'errors': [{'code': 'some_other_code'}]}
|
|
self.placement_fixture.mock_put.side_effect = [
|
|
ks_exc.Conflict(response=mock_resp),
|
|
mock.Mock(),
|
|
]
|
|
self.assertRaises(
|
|
n_exc.PlacementClientError,
|
|
self.placement_api_client.update_resource_provider_inventories,
|
|
resource_provider_uuid='resource provider uuid',
|
|
inventories={},
|
|
resource_provider_generation=None,
|
|
)
|
|
self.assertEqual(1, self.placement_fixture.mock_put.call_count)
|
|
|
|
def test_list_allocations(self):
|
|
self.placement_api_client.list_allocations(CONSUMER_UUID)
|
|
self.placement_fixture.mock_get.assert_called_once_with(
|
|
'/allocations/%s' % CONSUMER_UUID)
|
|
|
|
def test_update_allocation(self):
|
|
mock_rsp = mock.Mock()
|
|
mock_rsp.json = lambda: {
|
|
'allocations': {
|
|
RESOURCE_PROVIDER_UUID: {'resources': {'a': 10}}
|
|
}
|
|
}
|
|
self.placement_fixture.mock_get.side_effect = [mock_rsp]
|
|
self.placement_api_client.update_allocation(
|
|
CONSUMER_UUID,
|
|
{'allocations': {
|
|
RESOURCE_PROVIDER_UUID: {
|
|
'resources': {'a': 20}}
|
|
}})
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/allocations/%s' % CONSUMER_UUID,
|
|
{'allocations': {
|
|
RESOURCE_PROVIDER_UUID: {
|
|
'resources': {'a': 20}}
|
|
}}
|
|
)
|
|
|
|
def _get_allocation_response(self, allocation):
|
|
mock_rsp_get = mock.Mock()
|
|
mock_rsp_get.json = lambda: {
|
|
'allocations': allocation
|
|
}
|
|
return mock_rsp_get
|
|
|
|
def test_update_qos_allocation(self):
|
|
mock_rsp_get = self._get_allocation_response(
|
|
{RESOURCE_PROVIDER_UUID: {'resources': {'a': 3, 'b': 2}}})
|
|
self.placement_fixture.mock_get.side_effect = [mock_rsp_get]
|
|
self.placement_api_client.update_qos_allocation(
|
|
consumer_uuid=CONSUMER_UUID,
|
|
alloc_diff={RESOURCE_PROVIDER_UUID: {'a': 2, 'b': 2}},
|
|
)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/allocations/%s' % CONSUMER_UUID,
|
|
{'allocations': {
|
|
RESOURCE_PROVIDER_UUID: {
|
|
'resources': {'a': 5, 'b': 4}}
|
|
}}
|
|
)
|
|
|
|
def test_update_qos_allocation_removed(self):
|
|
mock_rsp = mock.Mock()
|
|
mock_rsp.json = lambda: {'allocations': {}}
|
|
self.placement_fixture.mock_get.side_effect = [mock_rsp]
|
|
self.assertRaises(
|
|
n_exc.PlacementAllocationRemoved,
|
|
self.placement_api_client.update_qos_allocation,
|
|
consumer_uuid=CONSUMER_UUID,
|
|
alloc_diff={RESOURCE_PROVIDER_UUID: {'a': 1, 'b': 1}},
|
|
)
|
|
|
|
def test_update_qos_allocation_rp_not_exists(self):
|
|
mock_rsp = mock.Mock()
|
|
mock_rsp.json = lambda: {'allocations': {'other:rp:uuid': {'c': 3}}}
|
|
self.placement_fixture.mock_get.side_effect = [mock_rsp]
|
|
self.assertRaises(
|
|
n_exc.PlacementAllocationRpNotExists,
|
|
self.placement_api_client.update_qos_allocation,
|
|
consumer_uuid=CONSUMER_UUID,
|
|
alloc_diff={RESOURCE_PROVIDER_UUID: {'a': 1, 'b': 1}},
|
|
)
|
|
|
|
def test_update_qos_allocation_max_retries(self):
|
|
mock_rsp_get = self._get_allocation_response(
|
|
{RESOURCE_PROVIDER_UUID: {'c': 3}})
|
|
self.placement_fixture.mock_get.side_effect = 10 * [mock_rsp_get]
|
|
mock_rsp_put = mock.Mock()
|
|
mock_rsp_put.json = lambda: {
|
|
'errors': [{'code': 'placement.concurrent_update'}]}
|
|
self.placement_fixture.mock_put.side_effect = ks_exc.Conflict(
|
|
response=mock_rsp_put)
|
|
self.assertRaises(
|
|
n_exc.PlacementAllocationGenerationConflict,
|
|
self.placement_api_client.update_qos_allocation,
|
|
consumer_uuid=CONSUMER_UUID,
|
|
alloc_diff={RESOURCE_PROVIDER_UUID: {}},
|
|
)
|
|
self.assertEqual(10, self.placement_fixture.mock_put.call_count)
|
|
|
|
def test_update_qos_minbwallocation_generation_conflict_solved(self):
|
|
mock_rsp_get = self._get_allocation_response(
|
|
{RESOURCE_PROVIDER_UUID: {'c': 3}})
|
|
self.placement_fixture.mock_get.side_effect = 2 * [mock_rsp_get]
|
|
mock_rsp_put = mock.Mock()
|
|
mock_rsp_put.json = lambda: {
|
|
'errors': [{'code': 'placement.concurrent_update'}]}
|
|
self.placement_fixture.mock_put.side_effect = [
|
|
ks_exc.Conflict(response=mock_rsp_put),
|
|
mock.Mock()
|
|
]
|
|
self.placement_api_client.update_qos_allocation(
|
|
consumer_uuid=CONSUMER_UUID,
|
|
alloc_diff={RESOURCE_PROVIDER_UUID: {}},
|
|
)
|
|
self.assertEqual(2, self.placement_fixture.mock_put.call_count)
|
|
|
|
def test_update_qos_allocation_other_conflict(self):
|
|
mock_rsp_get = self._get_allocation_response(
|
|
{RESOURCE_PROVIDER_UUID: {'c': 3}})
|
|
self.placement_fixture.mock_get.side_effect = 10 * [mock_rsp_get]
|
|
mock_rsp_put = mock.Mock()
|
|
mock_rsp_put.text = ''
|
|
mock_rsp_put.json = lambda: {
|
|
'errors': [{'code': 'some other error code'}]}
|
|
self.placement_fixture.mock_put.side_effect = ks_exc.Conflict(
|
|
response=mock_rsp_put)
|
|
self.assertRaises(
|
|
ks_exc.Conflict,
|
|
self.placement_api_client.update_qos_allocation,
|
|
consumer_uuid=CONSUMER_UUID,
|
|
alloc_diff={RESOURCE_PROVIDER_UUID: {}},
|
|
)
|
|
self.placement_fixture.mock_put.assert_called_once()
|
|
|
|
def test_update_qos_allocation_to_zero(self):
|
|
mock_rsp_get = self._get_allocation_response(
|
|
{RESOURCE_PROVIDER_UUID: {'resources': {'a': 3, 'b': 2}}})
|
|
self.placement_fixture.mock_get.side_effect = [mock_rsp_get]
|
|
self.placement_api_client.update_qos_allocation(
|
|
consumer_uuid=CONSUMER_UUID,
|
|
alloc_diff={RESOURCE_PROVIDER_UUID: {'a': -3, 'b': -2}},
|
|
)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/allocations/%s' % CONSUMER_UUID,
|
|
{'allocations': {}})
|
|
|
|
def test_update_qos_allocation_one_class_to_zero(self):
|
|
mock_rsp_get = self._get_allocation_response(
|
|
{RESOURCE_PROVIDER_UUID: {'resources': {'a': 3, 'b': 2}}})
|
|
self.placement_fixture.mock_get.side_effect = [mock_rsp_get]
|
|
self.placement_api_client.update_qos_allocation(
|
|
consumer_uuid=CONSUMER_UUID,
|
|
alloc_diff={RESOURCE_PROVIDER_UUID: {'a': -3, 'b': 1}},
|
|
)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/allocations/%s' % CONSUMER_UUID,
|
|
{'allocations': {
|
|
RESOURCE_PROVIDER_UUID: {
|
|
'resources': {'b': 3}}
|
|
}})
|
|
|
|
def test_update_qos_allocation_one_class_to_zero_and_new_class(self):
|
|
mock_rsp_get = self._get_allocation_response(
|
|
{RESOURCE_PROVIDER_UUID: {'resources': {'a': 3}}})
|
|
self.placement_fixture.mock_get.side_effect = [mock_rsp_get]
|
|
self.placement_api_client.update_qos_allocation(
|
|
consumer_uuid=CONSUMER_UUID,
|
|
alloc_diff={RESOURCE_PROVIDER_UUID: {'a': -3, 'b': 1}},
|
|
)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/allocations/%s' % CONSUMER_UUID,
|
|
{'allocations': {
|
|
RESOURCE_PROVIDER_UUID: {
|
|
'resources': {'b': 1}}
|
|
}})
|
|
|
|
def test_update_qos_allocation_multiple_rps(self):
|
|
mock_rsp_get = self._get_allocation_response({
|
|
RESOURCE_PROVIDER_UUID: {'resources': {'a': 3, 'b': 2}},
|
|
SECOND_RESOURCE_PROVIDER_UUID: {'resources': {'c': 1, 'd': 5}},
|
|
})
|
|
self.placement_fixture.mock_get.side_effect = [mock_rsp_get]
|
|
self.placement_api_client.update_qos_allocation(
|
|
consumer_uuid=CONSUMER_UUID,
|
|
alloc_diff={
|
|
RESOURCE_PROVIDER_UUID: {'a': -3, 'b': 2},
|
|
SECOND_RESOURCE_PROVIDER_UUID: {'e': 3, 'd': -5},
|
|
},
|
|
)
|
|
self.placement_fixture.mock_put.assert_called_once_with(
|
|
'/allocations/%s' % CONSUMER_UUID,
|
|
{'allocations': {
|
|
RESOURCE_PROVIDER_UUID: {
|
|
'resources': {'b': 4}},
|
|
SECOND_RESOURCE_PROVIDER_UUID: {
|
|
'resources': {'c': 1, 'e': 3}},
|
|
}}
|
|
)
|