Merge "Base test module/class for functional placement db"

This commit is contained in:
Zuul 2018-05-04 19:07:26 +00:00 committed by Gerrit Code Review
commit e8b4e5e512
3 changed files with 127 additions and 114 deletions

View File

@ -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

View 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

View File

@ -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.