Make test_archive_task_logs deterministic

The 'nova-manage db archive_deleted_rows --task-log' functional tests
involve manipulating time to assert archive behaviors when the --before
flag is also used.

While timedelta was used, set_time_override was not, so depending on
the date the test ran on + the number of days in the current month and
next two months, the test could fail. Task log audit periods are one
calendar month by default and the compute manager calls
last_completed_audit_period() without specifying a unit.

This changes the tests to use a time override to ensure predictable
behavior with regard to the audit period boundaries. The tests were
moved into their own test case classes in order to override the time
before services were started, so that the "service up" calculations
work as expected.

Closes-Bug: #1934519

Change-Id: I9b16a3a849937aba5b90ed1ab9a80b7f0103f673
This commit is contained in:
melanie witt 2021-07-09 22:22:15 +00:00
parent 9cdecc81fb
commit 87dba379ac
2 changed files with 76 additions and 9 deletions

View File

@ -743,9 +743,12 @@ class SubclassSignatureTestCase(testtools.TestCase, metaclass=abc.ABCMeta):
class TimeOverride(fixtures.Fixture):
"""Fixture to start and remove time override."""
def __init__(self, override_time=None):
self.override_time = override_time
def setUp(self):
super(TimeOverride, self).setUp()
timeutils.set_time_override()
timeutils.set_time_override(override_time=self.override_time)
self.addCleanup(timeutils.clear_time_override)

View File

@ -1687,6 +1687,26 @@ class TestDBArchiveDeletedRows(integrated_helpers._IntegratedTestBase):
self.assertEqual(
1, len(self.api.get_server_group(group['id'])['members']))
class TestDBArchiveDeletedRowsTaskLog(integrated_helpers._IntegratedTestBase):
"""Functional tests for the
"nova-manage db archive_deleted_rows --task-log" CLI.
"""
api_major_version = 'v2.1'
def setUp(self):
# Override time to ensure we cross audit period boundaries in a
# predictable way.
faketoday = datetime.datetime(2021, 7, 1)
# This needs to be done before setUp() starts services, else they will
# be considered "down" by the ComputeFilter.
self.useFixture(test.TimeOverride(override_time=faketoday))
super(TestDBArchiveDeletedRowsTaskLog, self).setUp()
self.enforce_fk_constraints()
self.cli = manage.DbCommands()
self.output = StringIO()
self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.output))
def test_archive_task_logs(self):
# Enable the generation of task_log records by the instance usage audit
# nova-compute periodic task.
@ -1702,9 +1722,11 @@ class TestDBArchiveDeletedRows(integrated_helpers._IntegratedTestBase):
# The instance usage audit periodic task only processes servers that
# were active during the last audit period. The audit period defaults
# to 1 month, so the last audit period would be the previous calendar
# month. Advance time 30 days into the future in order to generate a
# task_log record for the servers we created.
for days in (30, 60, 90):
# month. Advance time one month, two months, and three months to
# generate a task_log record for the servers we created, for each of
# three audit periods.
# July has 31 days, August has 31 days, September has 30 days.
for days in (31, 31 + 31, 31 + 31 + 30):
future = timeutils.utcnow() + datetime.timedelta(days=days)
with osloutils_fixture.TimeFixture(future):
# task_log records are generated by the _instance_usage_audit
@ -1725,7 +1747,7 @@ class TestDBArchiveDeletedRows(integrated_helpers._IntegratedTestBase):
# Next try archiving with --task-log and --before.
# We'll archive records that were last updated before the second audit
# period.
before = timeutils.utcnow() + datetime.timedelta(days=30)
before = timeutils.utcnow() + datetime.timedelta(days=31)
self.cli.archive_deleted_rows(
task_log=True, before=before.isoformat(), verbose=True)
# Verify that only 1 task_log record was archived.
@ -1820,6 +1842,46 @@ class TestDBArchiveDeletedRowsMultiCell(integrated_helpers.InstanceHelperMixin,
objects.Instance.get_by_uuid,
cctxt, server_id)
class TestDBArchiveDeletedRowsMultiCellTaskLog(
integrated_helpers.InstanceHelperMixin, test.TestCase):
"""Functional tests for the "nova-manage db archive_deleted_rows
--all-cells --task-log" CLI.
"""
NUMBER_OF_CELLS = 2
def setUp(self):
# Override time to ensure we cross audit period boundaries in a
# predictable way.
faketoday = datetime.datetime(2021, 7, 1)
# This needs to be done before setUp() starts services, else they will
# be considered "down" by the ComputeFilter.
self.useFixture(test.TimeOverride(override_time=faketoday))
super(TestDBArchiveDeletedRowsMultiCellTaskLog, self).setUp()
self.enforce_fk_constraints()
self.useFixture(nova_fixtures.NeutronFixture(self))
self.useFixture(nova_fixtures.GlanceFixture(self))
self.useFixture(func_fixtures.PlacementFixture())
api_fixture = self.useFixture(nova_fixtures.OSAPIFixture(
api_version='v2.1'))
# We need the admin api to forced_host for server create
self.api = api_fixture.admin_api
self.start_service('conductor')
self.start_service('scheduler')
self.context = context.RequestContext('fake-user', 'fake-project')
self.cli = manage.DbCommands()
self.output = StringIO()
self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.output))
# Start two compute services, one per cell
self.compute1 = self.start_service('compute', host='host1',
cell_name='cell1')
self.compute2 = self.start_service('compute', host='host2',
cell_name='cell2')
def test_archive_task_logs(self):
# Enable the generation of task_log records by the instance usage audit
# nova-compute periodic task.
@ -1840,9 +1902,11 @@ class TestDBArchiveDeletedRowsMultiCell(integrated_helpers.InstanceHelperMixin,
# The instance usage audit periodic task only processes servers that
# were active during the last audit period. The audit period defaults
# to 1 month, so the last audit period would be the previous calendar
# month. Advance time 30 days into the future in order to generate a
# task_log record for the servers we created.
for days in (30, 60, 90):
# month. Advance time one month, two months, and three months to
# generate a task_log record for the servers we created, for each of
# three audit periods.
# July has 31 days, August has 31 days, September has 30 days.
for days in (31, 31 + 31, 31 + 31 + 30):
future = timeutils.utcnow() + datetime.timedelta(days=days)
with osloutils_fixture.TimeFixture(future):
# task_log records are generated by the _instance_usage_audit
@ -1871,7 +1935,7 @@ class TestDBArchiveDeletedRowsMultiCell(integrated_helpers.InstanceHelperMixin,
# Next try archiving with --task-log and --before.
# We'll archive records that were last updated before the second audit
# period.
before = timeutils.utcnow() + datetime.timedelta(days=30)
before = timeutils.utcnow() + datetime.timedelta(days=31)
self.cli.archive_deleted_rows(
all_cells=True, task_log=True, before=before.isoformat(),
verbose=True)