From bfa594f8a39ffa96fc5c7ab88874b1c3625d48d5 Mon Sep 17 00:00:00 2001 From: Erik Olof Gunnar Andersson Date: Fri, 3 Nov 2023 08:55:26 -0700 Subject: [PATCH] Add RecoverShard test coverage Change-Id: Iaf7f4ae485f4d669d42d9c8a95c0305a611278eb --- .../tests/test_worker/test_worker_tasks.py | 151 ++++++++++++++++++ designate/worker/tasks/zone.py | 6 +- 2 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 designate/tests/test_worker/test_worker_tasks.py diff --git a/designate/tests/test_worker/test_worker_tasks.py b/designate/tests/test_worker/test_worker_tasks.py new file mode 100644 index 000000000..d9e8d49b6 --- /dev/null +++ b/designate/tests/test_worker/test_worker_tasks.py @@ -0,0 +1,151 @@ +# 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 oslo_log import log as logging +from oslo_utils import timeutils + +import designate.conf +from designate.tests import fixtures +from designate.worker import processing +from designate.worker.tasks import zone + + +CONF = designate.conf.CONF +LOG = logging.getLogger(__name__) + + +class RecoverShardTest(designate.tests.TestCase): + def setUp(self): + super().setUp() + self.stdlog = fixtures.StandardLogging() + self.useFixture(self.stdlog) + self.executor = processing.Executor() + + def test_recover_error_create(self): + new_zone = self.create_zone(shard=9) + new_zone.status = 'ERROR' + self.storage.update_zone(self.admin_context, new_zone) + self.create_zone(fixture=1, shard=10) + + self.task = zone.RecoverShard( + self.executor, self.admin_context, 0, new_zone.shard + ) + + self.task._worker_api = mock.Mock() + + self.task() + + self.task.worker_api.create_zone.assert_called() + self.task.worker_api.update_zone.assert_not_called() + self.task.worker_api.delete_zone.assert_not_called() + + def test_recover_error_update(self): + new_zone = self.create_zone(shard=9) + new_zone.action = 'UPDATE' + new_zone.status = 'ERROR' + self.storage.update_zone(self.admin_context, new_zone) + self.create_zone(fixture=1, shard=10) + + self.task = zone.RecoverShard( + self.executor, self.admin_context, 0, new_zone.shard + ) + + self.task._worker_api = mock.Mock() + + self.task() + + self.task.worker_api.create_zone.assert_not_called() + self.task.worker_api.update_zone.assert_called() + self.task.worker_api.delete_zone.assert_not_called() + + def test_recover_error_delete(self): + new_zone = self.create_zone(shard=9) + new_zone.action = 'DELETE' + new_zone.status = 'ERROR' + self.storage.update_zone(self.admin_context, new_zone) + + second_zone = self.create_zone(fixture=1, shard=10) + second_zone.action = 'DELETE' + second_zone.status = 'ERROR' + self.storage.update_zone(self.admin_context, second_zone) + + self.task = zone.RecoverShard( + self.executor, self.admin_context, 0, new_zone.shard + ) + + self.task._worker_api = mock.Mock() + + self.task() + + self.task.worker_api.create_zone.assert_not_called() + self.task.worker_api.update_zone.assert_not_called() + self.task.worker_api.delete_zone.assert_called() + + def test_recover_stale(self): + new_zone = self.create_zone( + shard=9, + ) + new_zone.serial = timeutils.utcnow_ts() - 1000 + new_zone.action = 'DELETE' + new_zone.status = 'PENDING' + self.storage.update_zone(self.admin_context, new_zone) + self.create_zone(fixture=1, shard=5) + + self.task = zone.RecoverShard( + self.executor, self.admin_context, 0, new_zone.shard + ) + + self.task._worker_api = mock.Mock() + + self.task() + + self.task.worker_api.create_zone.assert_not_called() + self.task.worker_api.update_zone.assert_not_called() + self.task.worker_api.delete_zone.assert_called() + + def test_recover_nothing_to_do(self): + self.create_zone(shard=0) + self.create_zone(fixture=1, shard=2048) + self.create_zone(fixture=2, shard=4095) + + self.task = zone.RecoverShard( + self.executor, self.admin_context, 0, 4095 + ) + + self.task._worker_api = mock.Mock() + + self.task() + + self.task.worker_api.create_zone.assert_not_called() + self.task.worker_api.update_zone.assert_not_called() + self.task.worker_api.delete_zone.assert_not_called() + + def test_recover_no_valid_actions(self): + new_zone = self.create_zone(shard=9) + new_zone.action = 'NONE' + new_zone.status = 'ERROR' + self.storage.update_zone(self.admin_context, new_zone) + self.create_zone(fixture=1, shard=2048) + self.create_zone(fixture=2, shard=4095) + + self.task = zone.RecoverShard( + self.executor, self.admin_context, 0, 4095 + ) + + self.task._worker_api = mock.Mock() + + self.task() + + self.task.worker_api.create_zone.assert_not_called() + self.task.worker_api.update_zone.assert_not_called() + self.task.worker_api.delete_zone.assert_not_called() diff --git a/designate/worker/tasks/zone.py b/designate/worker/tasks/zone.py index 956a5517a..a8ae89e4c 100644 --- a/designate/worker/tasks/zone.py +++ b/designate/worker/tasks/zone.py @@ -790,7 +790,7 @@ class RecoverShard(base.Task): def _get_zones(self): criterion = { - 'shard': f"BETWEEN {self.begin_shard},{self.end_shard}", + 'shard': f'BETWEEN {self.begin_shard},{self.end_shard}', 'status': 'ERROR' } error_zones = self.storage.find_zones(self.context, criterion) @@ -799,9 +799,9 @@ class RecoverShard(base.Task): # status for longer than they should # Generate the current serial, will provide a UTC Unix TS. stale_criterion = { - 'shard': f"BETWEEN {self.begin_shard},{self.end_shard}", + 'shard': f'BETWEEN {self.begin_shard},{self.end_shard}', 'status': 'PENDING', - 'serial': "<%s" % (timeutils.utcnow_ts() - self.max_prop_time) + 'serial': '<%s' % (timeutils.utcnow_ts() - self.max_prop_time) } stale_zones = self.storage.find_zones(self.context, stale_criterion)