From 25303f1f8df0e91e835360869a61cbf3eca30f60 Mon Sep 17 00:00:00 2001 From: Paul Marshall Date: Thu, 5 Dec 2013 14:42:10 -0600 Subject: [PATCH] Acknowledge Nova VERIFY_RESIZE as RESIZE state After a resize, Nova changes instances to the VERIFY_RESIZE state, which must be confirmed before they return to ACTIVE. However, as far as Trove is concerned instances in VERIFY_RESIZE should still report RESIZE until they're actually done. Additionally, instance status unit tests are added to verify that the correct statuses are reported. Change-Id: I9c1824f8fe420025f329209c41c7aac1d8d7921c Closes-Bug: #1217985 --- trove/instance/models.py | 5 + .../instance/test_instance_status.py | 149 ++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 trove/tests/unittests/instance/test_instance_status.py diff --git a/trove/instance/models.py b/trove/instance/models.py index 86bd4b3070..a389aef7be 100644 --- a/trove/instance/models.py +++ b/trove/instance/models.py @@ -193,6 +193,11 @@ class SimpleInstance(object): "RESIZE"]: return self.db_info.server_status + # As far as Trove is concerned, Nova instances in VERIFY_RESIZE should + # still appear as though they are in RESIZE. + if self.db_info.server_status in ["VERIFY_RESIZE"]: + return InstanceStatus.RESIZE + ### Check if there is a backup running for this instance if Backup.running(self.id): return InstanceStatus.BACKUP diff --git a/trove/tests/unittests/instance/test_instance_status.py b/trove/tests/unittests/instance/test_instance_status.py new file mode 100644 index 0000000000..b2a3ff2fb3 --- /dev/null +++ b/trove/tests/unittests/instance/test_instance_status.py @@ -0,0 +1,149 @@ +# Copyright 2013 OpenStack Foundation +# All Rights Reserved. +# +# 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 testtools import TestCase +from trove.common.instance import ServiceStatuses +from trove.instance.models import InstanceStatus +from trove.instance.models import SimpleInstance +from trove.tests.util import test_config + + +class FakeInstanceTask(object): + + def __init__(self): + self.is_error = False + self.action = None + + +class FakeDBInstance(object): + + def __init__(self): + self.id = None + self.deleted = False + self.datastore_version_id = test_config.dbaas_datastore_version + self.server_status = "ACTIVE" + self.task_status = FakeInstanceTask() + + +class FakeInstanceServiceStatus(object): + + def __init__(self): + self.status = ServiceStatuses.RUNNING + + def set_status(self, status): + self.status = status + + def get_status(self): + return self.status + + +class InstanceStatusTest(TestCase): + + def setUp(self): + super(InstanceStatusTest, self).setUp() + + def tearDown(self): + super(InstanceStatusTest, self).tearDown() + + def test_task_status_error_reports_error(self): + fake_db_info = FakeDBInstance() + fake_status = FakeInstanceServiceStatus() + fake_db_info.task_status.is_error = True + instance = SimpleInstance('dummy context', fake_db_info, fake_status) + self.assertEqual(InstanceStatus.ERROR, instance.status) + + def test_task_status_action_building_reports_build(self): + fake_db_info = FakeDBInstance() + fake_status = FakeInstanceServiceStatus() + fake_db_info.task_status.action = "BUILDING" + instance = SimpleInstance('dummy context', fake_db_info, fake_status) + self.assertEqual(InstanceStatus.BUILD, instance.status) + + def test_task_status_action_rebooting_reports_reboot(self): + fake_db_info = FakeDBInstance() + fake_status = FakeInstanceServiceStatus() + fake_db_info.task_status.action = "REBOOTING" + instance = SimpleInstance('dummy context', fake_db_info, fake_status) + self.assertEqual(InstanceStatus.REBOOT, instance.status) + + def test_task_status_action_resizing_reports_resize(self): + fake_db_info = FakeDBInstance() + fake_status = FakeInstanceServiceStatus() + fake_db_info.task_status.action = "RESIZING" + instance = SimpleInstance('dummy context', fake_db_info, fake_status) + self.assertEqual(InstanceStatus.RESIZE, instance.status) + + def test_task_status_action_deleting_reports_shutdown(self): + fake_db_info = FakeDBInstance() + fake_status = FakeInstanceServiceStatus() + fake_db_info.task_status.action = "DELETING" + instance = SimpleInstance('dummy context', fake_db_info, fake_status) + self.assertEqual(InstanceStatus.SHUTDOWN, instance.status) + + def test_nova_server_build_reports_build(self): + fake_db_info = FakeDBInstance() + fake_status = FakeInstanceServiceStatus() + fake_db_info.server_status = "BUILD" + instance = SimpleInstance('dummy context', fake_db_info, fake_status) + self.assertEqual(InstanceStatus.BUILD, instance.status) + + def test_nova_server_error_reports_error(self): + fake_db_info = FakeDBInstance() + fake_status = FakeInstanceServiceStatus() + fake_db_info.server_status = "ERROR" + instance = SimpleInstance('dummy context', fake_db_info, fake_status) + self.assertEqual(InstanceStatus.ERROR, instance.status) + + def test_nova_server_reboot_reports_reboot(self): + fake_db_info = FakeDBInstance() + fake_status = FakeInstanceServiceStatus() + fake_db_info.server_status = "REBOOT" + instance = SimpleInstance('dummy context', fake_db_info, fake_status) + self.assertEqual(InstanceStatus.REBOOT, instance.status) + + def test_nova_server_resize_reports_resize(self): + fake_db_info = FakeDBInstance() + fake_status = FakeInstanceServiceStatus() + fake_db_info.server_status = "RESIZE" + instance = SimpleInstance('dummy context', fake_db_info, fake_status) + self.assertEqual(InstanceStatus.RESIZE, instance.status) + + def test_nova_server_verify_resize_reports_resize(self): + fake_db_info = FakeDBInstance() + fake_status = FakeInstanceServiceStatus() + fake_db_info.server_status = "VERIFY_RESIZE" + instance = SimpleInstance('dummy context', fake_db_info, fake_status) + self.assertEqual(InstanceStatus.RESIZE, instance.status) + + def test_service_status_paused_reports_reboot(self): + fake_db_info = FakeDBInstance() + fake_status = FakeInstanceServiceStatus() + fake_status.set_status(ServiceStatuses.PAUSED) + instance = SimpleInstance('dummy context', fake_db_info, fake_status) + self.assertEqual(InstanceStatus.REBOOT, instance.status) + + def test_service_status_new_reports_build(self): + fake_db_info = FakeDBInstance() + fake_status = FakeInstanceServiceStatus() + fake_status.set_status(ServiceStatuses.NEW) + instance = SimpleInstance('dummy context', fake_db_info, fake_status) + self.assertEqual(InstanceStatus.BUILD, instance.status) + + def test_service_status_running_reports_active(self): + fake_db_info = FakeDBInstance() + fake_status = FakeInstanceServiceStatus() + fake_status.set_status(ServiceStatuses.RUNNING) + instance = SimpleInstance('dummy context', fake_db_info, fake_status) + self.assertEqual(InstanceStatus.ACTIVE, instance.status)