Add recreate test for bug 1798163
Change Icae5038190ab8c7bbdb38d54ae909fcbf9048912 in Rocky attempts to online migrate missing consumers table records when listing allocations for a given resource provider. The problem is when it's doing an insert-from-select, it's not handling multiple allocations on the same provider for the same consumer, like you'd have with a compute instance that has VCPU, MEMORY_MB and DISK_GB allocations against a single compute node resource provider. As a result, the insert statement has duplicate consumer IDs in it which results in a unique constraint violation. The existing tests never caught this because they tested with 3 unique consumers with a single allocation each. The functional test added here hits both online data migration routines: via the API when listing allocations for a resource provider and the direct online data migration CLI. Change-Id: Iba56aa6b227b6455d2437e4fabcd296b1b0f06ee Related-Bug: #1798163
This commit is contained in:
parent
a53e46a759
commit
618b47627d
@ -11,6 +11,7 @@
|
||||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_db import exception as db_exc
|
||||
from oslo_utils.fixture import uuidsentinel as uuids
|
||||
import sqlalchemy as sa
|
||||
|
||||
@ -105,7 +106,7 @@ class CreateIncompleteConsumersTestCase(base.TestCase):
|
||||
self.ctx = self.context
|
||||
|
||||
@db_api.placement_context_manager.writer
|
||||
def _create_incomplete_allocations(self, ctx):
|
||||
def _create_incomplete_allocations(self, ctx, num_of_consumer_allocs=1):
|
||||
# Create some allocations with consumers that don't exist in the
|
||||
# consumers table to represent old allocations that we expect to be
|
||||
# "cleaned up" with consumers table records that point to the sentinel
|
||||
@ -114,8 +115,12 @@ class CreateIncompleteConsumersTestCase(base.TestCase):
|
||||
c2_missing_uuid = uuids.c2_missing
|
||||
c3_missing_uuid = uuids.c3_missing
|
||||
for c_uuid in (c1_missing_uuid, c2_missing_uuid, c3_missing_uuid):
|
||||
# Create $num_of_consumer_allocs allocations per consumer with
|
||||
# different resource classes.
|
||||
for resource_class_id in range(num_of_consumer_allocs):
|
||||
ins_stmt = ALLOC_TBL.insert().values(
|
||||
resource_provider_id=1, resource_class_id=0,
|
||||
resource_provider_id=1,
|
||||
resource_class_id=resource_class_id,
|
||||
consumer_id=c_uuid, used=1)
|
||||
ctx.session.execute(ins_stmt)
|
||||
# Verify there are no records in the projects/users table
|
||||
@ -217,6 +222,31 @@ class CreateIncompleteConsumersTestCase(base.TestCase):
|
||||
res = consumer_obj.create_incomplete_consumers(self.ctx, 10)
|
||||
self.assertEqual((0, 0), res)
|
||||
|
||||
def test_create_incomplete_consumers_multiple_allocs_per_consumer(self):
|
||||
"""Tests that missing consumer records are created when listing
|
||||
allocations against a resource provider or running the online data
|
||||
migration routine when the consumers have multiple allocations on the
|
||||
same provider.
|
||||
"""
|
||||
self._create_incomplete_allocations(self.ctx, num_of_consumer_allocs=2)
|
||||
# Run the online data migration to migrate one consumer. The batch size
|
||||
# needs to be large enough to hit more than one consumer for this test
|
||||
# where each consumer has two allocations.
|
||||
# FIXME(mriedem): This should not raise a UniqueConstraint error once
|
||||
# bug 1798163 is fixed.
|
||||
# res = consumer_obj.create_incomplete_consumers(self.ctx, 2)
|
||||
# self.assertEqual((2, 2), res)
|
||||
self.assertRaises(db_exc.DBDuplicateEntry,
|
||||
consumer_obj.create_incomplete_consumers,
|
||||
self.ctx, 2)
|
||||
# Migrate the rest by listing allocations on the resource provider.
|
||||
rp1 = rp_obj.ResourceProvider(self.ctx, id=1)
|
||||
# FIXME(mriedem): This should not raise a UniqueConstraint error once
|
||||
# bug 1798163 is fixed.
|
||||
self.assertRaises(db_exc.DBDuplicateEntry,
|
||||
rp_obj.AllocationList.get_all_by_resource_provider,
|
||||
self.ctx, rp1)
|
||||
|
||||
|
||||
class DeleteConsumerIfNoAllocsTestCase(tb.PlacementDbBaseTestCase):
|
||||
def test_delete_consumer_if_no_allocs(self):
|
||||
|
Loading…
Reference in New Issue
Block a user