Merge "Base test module/class for functional placement db"
This commit is contained in:
commit
e8b4e5e512
@ -10,88 +10,23 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import os_traits
|
||||
from oslo_utils import uuidutils
|
||||
import six
|
||||
import sqlalchemy as sa
|
||||
|
||||
from nova.api.openstack.placement import exception
|
||||
from nova.api.openstack.placement import lib as placement_lib
|
||||
from nova.api.openstack.placement.objects import resource_provider as rp_obj
|
||||
from nova import context
|
||||
from nova import rc_fields as fields
|
||||
from nova import test
|
||||
from nova.tests import fixtures
|
||||
from nova.tests.functional.api.openstack.placement.db import test_base as tb
|
||||
from nova.tests import uuidsentinel as uuids
|
||||
|
||||
|
||||
def _add_inventory(rp, rc, total, **kwargs):
|
||||
kwargs.setdefault('max_unit', total)
|
||||
inv = rp_obj.Inventory(rp._context, resource_provider=rp,
|
||||
resource_class=rc, total=total, **kwargs)
|
||||
inv.obj_set_defaults()
|
||||
rp.add_inventory(inv)
|
||||
_add_inventory = tb._add_inventory
|
||||
_allocate_from_provider = tb._allocate_from_provider
|
||||
_set_traits = tb._set_traits
|
||||
|
||||
|
||||
def _set_traits(rp, *traits):
|
||||
tlist = []
|
||||
for tname in traits:
|
||||
try:
|
||||
trait = rp_obj.Trait.get_by_name(rp._context, tname)
|
||||
except exception.TraitNotFound:
|
||||
trait = rp_obj.Trait(rp._context, name=tname)
|
||||
trait.create()
|
||||
tlist.append(trait)
|
||||
rp.set_traits(rp_obj.TraitList(objects=tlist))
|
||||
|
||||
|
||||
def _allocate_from_provider(rp, rc, used):
|
||||
# NOTE(efried): Always use a random consumer UUID - we don't want to
|
||||
# override any existing allocations from the test case.
|
||||
rp_obj.AllocationList(
|
||||
rp._context, objects=[
|
||||
rp_obj.Allocation(
|
||||
rp._context, resource_provider=rp, resource_class=rc,
|
||||
consumer_id=uuidutils.generate_uuid(), used=used)]
|
||||
).create_all()
|
||||
|
||||
|
||||
class ProviderDBBase(test.NoDBTestCase):
|
||||
|
||||
USES_DB_SELF = True
|
||||
|
||||
def setUp(self):
|
||||
super(ProviderDBBase, self).setUp()
|
||||
self.useFixture(fixtures.Database())
|
||||
self.api_db = self.useFixture(fixtures.Database(database='api'))
|
||||
# Reset the _TRAITS_SYNCED global before we start and after
|
||||
# we are done since other tests (notably the gabbi tests)
|
||||
# may have caused it to change.
|
||||
self._reset_traits_synced()
|
||||
self.addCleanup(self._reset_traits_synced)
|
||||
self.ctx = context.RequestContext('fake-user', 'fake-project')
|
||||
# For debugging purposes, populated by _create_provider and used by
|
||||
# _validate_allocation_requests to make failure results more readable.
|
||||
self.rp_uuid_to_name = {}
|
||||
|
||||
@staticmethod
|
||||
def _reset_traits_synced():
|
||||
"""Reset the _TRAITS_SYNCED boolean to base state."""
|
||||
rp_obj._TRAITS_SYNCED = False
|
||||
|
||||
def _create_provider(self, name, *aggs, **kwargs):
|
||||
parent = kwargs.get('parent')
|
||||
rp = rp_obj.ResourceProvider(self.ctx, name=name,
|
||||
uuid=getattr(uuids, name))
|
||||
if parent:
|
||||
rp.parent_provider_uuid = parent
|
||||
rp.create()
|
||||
if aggs:
|
||||
rp.set_aggregates(aggs)
|
||||
self.rp_uuid_to_name[rp.uuid] = name
|
||||
return rp
|
||||
|
||||
|
||||
class ProviderDBHelperTestCase(ProviderDBBase):
|
||||
class ProviderDBHelperTestCase(tb.PlacementDbBaseTestCase):
|
||||
|
||||
def test_get_provider_ids_matching(self):
|
||||
# These RPs are named based on whether we expect them to be 'incl'uded
|
||||
@ -305,7 +240,7 @@ class ProviderDBHelperTestCase(ProviderDBBase):
|
||||
run(['CUSTOM_BAR'], [])
|
||||
|
||||
|
||||
class AllocationCandidatesTestCase(ProviderDBBase):
|
||||
class AllocationCandidatesTestCase(tb.PlacementDbBaseTestCase):
|
||||
"""Tests a variety of scenarios with both shared and non-shared resource
|
||||
providers that the AllocationCandidates.get_by_requests() method returns a
|
||||
set of alternative allocation requests and provider summaries that may be
|
||||
|
105
nova/tests/functional/api/openstack/placement/db/test_base.py
Normal file
105
nova/tests/functional/api/openstack/placement/db/test_base.py
Normal file
@ -0,0 +1,105 @@
|
||||
# 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.
|
||||
"""Base class and convenience utilities for functional placement tests."""
|
||||
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from nova.api.openstack.placement import exception
|
||||
from nova.api.openstack.placement.objects import resource_provider as rp_obj
|
||||
from nova import context
|
||||
from nova import test
|
||||
from nova.tests import fixtures
|
||||
from nova.tests import uuidsentinel as uuids
|
||||
|
||||
|
||||
def _add_inventory(rp, rc, total, **kwargs):
|
||||
kwargs.setdefault('max_unit', total)
|
||||
inv = rp_obj.Inventory(rp._context, resource_provider=rp,
|
||||
resource_class=rc, total=total, **kwargs)
|
||||
inv.obj_set_defaults()
|
||||
rp.add_inventory(inv)
|
||||
|
||||
|
||||
def _set_traits(rp, *traits):
|
||||
tlist = []
|
||||
for tname in traits:
|
||||
try:
|
||||
trait = rp_obj.Trait.get_by_name(rp._context, tname)
|
||||
except exception.TraitNotFound:
|
||||
trait = rp_obj.Trait(rp._context, name=tname)
|
||||
trait.create()
|
||||
tlist.append(trait)
|
||||
rp.set_traits(rp_obj.TraitList(objects=tlist))
|
||||
|
||||
|
||||
def _allocate_from_provider(rp, rc, used):
|
||||
# NOTE(efried): Always use a random consumer UUID - we don't want to
|
||||
# override any existing allocations from the test case.
|
||||
rp_obj.AllocationList(
|
||||
rp._context, objects=[
|
||||
rp_obj.Allocation(
|
||||
rp._context, resource_provider=rp, resource_class=rc,
|
||||
consumer_id=uuidutils.generate_uuid(), used=used)]
|
||||
).create_all()
|
||||
|
||||
|
||||
class PlacementDbBaseTestCase(test.NoDBTestCase):
|
||||
USES_DB_SELF = True
|
||||
|
||||
def setUp(self):
|
||||
super(PlacementDbBaseTestCase, self).setUp()
|
||||
self.useFixture(fixtures.Database())
|
||||
self.api_db = self.useFixture(fixtures.Database(database='api'))
|
||||
# Reset the _TRAITS_SYNCED global before we start and after
|
||||
# we are done since other tests (notably the gabbi tests)
|
||||
# may have caused it to change.
|
||||
self._reset_traits_synced()
|
||||
self.addCleanup(self._reset_traits_synced)
|
||||
self.ctx = context.RequestContext('fake-user', 'fake-project')
|
||||
# For debugging purposes, populated by _create_provider and used by
|
||||
# _validate_allocation_requests to make failure results more readable.
|
||||
self.rp_uuid_to_name = {}
|
||||
|
||||
@staticmethod
|
||||
def _reset_traits_synced():
|
||||
"""Reset the _TRAITS_SYNCED boolean to base state."""
|
||||
rp_obj._TRAITS_SYNCED = False
|
||||
|
||||
def _create_provider(self, name, *aggs, **kwargs):
|
||||
parent = kwargs.get('parent')
|
||||
rp = rp_obj.ResourceProvider(self.ctx, name=name,
|
||||
uuid=getattr(uuids, name))
|
||||
if parent:
|
||||
rp.parent_provider_uuid = parent
|
||||
rp.create()
|
||||
if aggs:
|
||||
rp.set_aggregates(aggs)
|
||||
self.rp_uuid_to_name[rp.uuid] = name
|
||||
return rp
|
||||
|
||||
def _make_allocation(self, inv_dict, alloc_dict):
|
||||
rp_uuid = uuids.allocation_resource_provider
|
||||
rp = rp_obj.ResourceProvider(
|
||||
context=self.ctx,
|
||||
uuid=rp_uuid,
|
||||
name=rp_uuid)
|
||||
rp.create()
|
||||
disk_inv = rp_obj.Inventory(context=self.ctx,
|
||||
resource_provider=rp, **inv_dict)
|
||||
inv_list = rp_obj.InventoryList(objects=[disk_inv])
|
||||
rp.set_inventory(inv_list)
|
||||
alloc = rp_obj.Allocation(self.ctx, resource_provider=rp,
|
||||
**alloc_dict)
|
||||
alloc_list = rp_obj.AllocationList(self.ctx, objects=[alloc])
|
||||
alloc_list.create_all()
|
||||
return rp, alloc
|
@ -23,8 +23,10 @@ from nova import context
|
||||
from nova import rc_fields as fields
|
||||
from nova import test
|
||||
from nova.tests import fixtures
|
||||
from nova.tests.functional.api.openstack.placement.db import test_base as tb
|
||||
from nova.tests import uuidsentinel
|
||||
|
||||
|
||||
DISK_INVENTORY = dict(
|
||||
total=200,
|
||||
reserved=10,
|
||||
@ -42,36 +44,7 @@ DISK_ALLOCATION = dict(
|
||||
)
|
||||
|
||||
|
||||
class ResourceProviderBaseCase(test.NoDBTestCase):
|
||||
|
||||
USES_DB_SELF = True
|
||||
|
||||
def setUp(self):
|
||||
super(ResourceProviderBaseCase, self).setUp()
|
||||
self.useFixture(fixtures.Database())
|
||||
self.api_db = self.useFixture(fixtures.Database(database='api'))
|
||||
self.ctx = context.RequestContext('fake-user', 'fake-project')
|
||||
|
||||
def _make_allocation(self, rp_uuid=None, inv_dict=None):
|
||||
rp_uuid = rp_uuid or uuidsentinel.allocation_resource_provider
|
||||
rp = rp_obj.ResourceProvider(
|
||||
context=self.ctx,
|
||||
uuid=rp_uuid,
|
||||
name=rp_uuid)
|
||||
rp.create()
|
||||
inv_dict = inv_dict or DISK_INVENTORY
|
||||
disk_inv = rp_obj.Inventory(context=self.ctx,
|
||||
resource_provider=rp, **inv_dict)
|
||||
inv_list = rp_obj.InventoryList(objects=[disk_inv])
|
||||
rp.set_inventory(inv_list)
|
||||
alloc = rp_obj.Allocation(self.ctx, resource_provider=rp,
|
||||
**DISK_ALLOCATION)
|
||||
alloc_list = rp_obj.AllocationList(self.ctx, objects=[alloc])
|
||||
alloc_list.create_all()
|
||||
return rp, alloc
|
||||
|
||||
|
||||
class ResourceProviderTestCase(ResourceProviderBaseCase):
|
||||
class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
"""Test resource-provider objects' lifecycles."""
|
||||
|
||||
def test_provider_traits_empty_param(self):
|
||||
@ -550,7 +523,7 @@ class ResourceProviderTestCase(ResourceProviderBaseCase):
|
||||
created_resource_provider.destroy)
|
||||
|
||||
def test_destroy_allocated_resource_provider_fails(self):
|
||||
rp, allocation = self._make_allocation()
|
||||
rp, allocation = self._make_allocation(DISK_INVENTORY, DISK_ALLOCATION)
|
||||
self.assertRaises(exception.ResourceProviderInUse,
|
||||
rp.destroy)
|
||||
|
||||
@ -853,7 +826,7 @@ class ResourceProviderTestCase(ResourceProviderBaseCase):
|
||||
str(error))
|
||||
|
||||
def test_delete_inventory_with_allocation(self):
|
||||
rp, allocation = self._make_allocation(inv_dict=DISK_INVENTORY)
|
||||
rp, allocation = self._make_allocation(DISK_INVENTORY, DISK_ALLOCATION)
|
||||
error = self.assertRaises(exception.InventoryInUse,
|
||||
rp.delete_inventory,
|
||||
'DISK_GB')
|
||||
@ -880,7 +853,7 @@ class ResourceProviderTestCase(ResourceProviderBaseCase):
|
||||
# Compute nodes that are reconfigured have to be able to set
|
||||
# their inventory to something that violates allocations so
|
||||
# we need to make that possible.
|
||||
rp, allocation = self._make_allocation()
|
||||
rp, allocation = self._make_allocation(DISK_INVENTORY, DISK_ALLOCATION)
|
||||
# attempt to set inventory to less than currently allocated
|
||||
# amounts
|
||||
new_total = 1
|
||||
@ -964,7 +937,7 @@ class ResourceProviderTestCase(ResourceProviderBaseCase):
|
||||
self.assertEqual(rp1.id, inv.resource_provider.id)
|
||||
|
||||
|
||||
class ResourceProviderListTestCase(ResourceProviderBaseCase):
|
||||
class ResourceProviderListTestCase(tb.PlacementDbBaseTestCase):
|
||||
def setUp(self):
|
||||
super(ResourceProviderListTestCase, self).setUp()
|
||||
self.useFixture(fixtures.Database())
|
||||
@ -1346,7 +1319,7 @@ class TestResourceProviderAggregates(test.NoDBTestCase):
|
||||
expected, rp_obj._anchors_for_sharing_provider(self.ctx, s5.id))
|
||||
|
||||
|
||||
class TestAllocation(ResourceProviderBaseCase):
|
||||
class TestAllocation(tb.PlacementDbBaseTestCase):
|
||||
|
||||
def test_create_list_and_delete_allocation(self):
|
||||
resource_provider = rp_obj.ResourceProvider(
|
||||
@ -1527,7 +1500,7 @@ class TestAllocation(ResourceProviderBaseCase):
|
||||
self.assertEqual(2, len(consumer_allocs))
|
||||
|
||||
def test_get_all_by_resource_provider(self):
|
||||
rp, allocation = self._make_allocation()
|
||||
rp, allocation = self._make_allocation(DISK_INVENTORY, DISK_ALLOCATION)
|
||||
allocations = rp_obj.AllocationList.get_all_by_resource_provider(
|
||||
self.ctx, rp)
|
||||
self.assertEqual(1, len(allocations))
|
||||
@ -1536,7 +1509,7 @@ class TestAllocation(ResourceProviderBaseCase):
|
||||
allocations[0].resource_provider.id)
|
||||
|
||||
|
||||
class TestAllocationListCreateDelete(ResourceProviderBaseCase):
|
||||
class TestAllocationListCreateDelete(tb.PlacementDbBaseTestCase):
|
||||
|
||||
def test_allocation_checking(self):
|
||||
"""Test that allocation check logic works with 2 resource classes on
|
||||
@ -2114,7 +2087,7 @@ class TestAllocationListCreateDelete(ResourceProviderBaseCase):
|
||||
self.assertEqual(0, len(allocations))
|
||||
|
||||
|
||||
class UsageListTestCase(ResourceProviderBaseCase):
|
||||
class UsageListTestCase(tb.PlacementDbBaseTestCase):
|
||||
|
||||
def test_get_all_null(self):
|
||||
for uuid in [uuidsentinel.rp_uuid_1, uuidsentinel.rp_uuid_2]:
|
||||
@ -2126,7 +2099,7 @@ class UsageListTestCase(ResourceProviderBaseCase):
|
||||
self.assertEqual(0, len(usage_list))
|
||||
|
||||
def test_get_all_one_allocation(self):
|
||||
db_rp, _ = self._make_allocation(rp_uuid=uuidsentinel.rp_uuid)
|
||||
db_rp, _ = self._make_allocation(DISK_INVENTORY, DISK_ALLOCATION)
|
||||
inv = rp_obj.Inventory(resource_provider=db_rp,
|
||||
resource_class=fields.ResourceClass.DISK_GB,
|
||||
total=1024)
|
||||
@ -2181,7 +2154,7 @@ class UsageListTestCase(ResourceProviderBaseCase):
|
||||
self.assertEqual(2, len(usage_list))
|
||||
|
||||
|
||||
class ResourceClassListTestCase(ResourceProviderBaseCase):
|
||||
class ResourceClassListTestCase(tb.PlacementDbBaseTestCase):
|
||||
|
||||
def test_get_all_no_custom(self):
|
||||
"""Test that if we haven't yet added any custom resource classes, that
|
||||
@ -2211,7 +2184,7 @@ class ResourceClassListTestCase(ResourceProviderBaseCase):
|
||||
self.assertEqual(expected_count, len(rcs))
|
||||
|
||||
|
||||
class ResourceClassTestCase(ResourceProviderBaseCase):
|
||||
class ResourceClassTestCase(tb.PlacementDbBaseTestCase):
|
||||
|
||||
def test_get_by_name(self):
|
||||
rc = rp_obj.ResourceClass.get_by_name(
|
||||
@ -2438,7 +2411,7 @@ class ResourceClassTestCase(ResourceProviderBaseCase):
|
||||
'CUSTOM_IRON_NFV')
|
||||
|
||||
|
||||
class ResourceProviderTraitTestCase(ResourceProviderBaseCase):
|
||||
class ResourceProviderTraitTestCase(tb.PlacementDbBaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ResourceProviderTraitTestCase, self).setUp()
|
||||
@ -2743,7 +2716,7 @@ class ResourceProviderTraitTestCase(ResourceProviderBaseCase):
|
||||
self.assertEqual(set(std_traits), set(_db_traits(conn)))
|
||||
|
||||
|
||||
class SharedProviderTestCase(ResourceProviderBaseCase):
|
||||
class SharedProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
"""Tests that the queries used to determine placement in deployments with
|
||||
shared resource providers such as a shared disk pool result in accurate
|
||||
reporting of inventory and usage.
|
||||
|
Loading…
x
Reference in New Issue
Block a user