diff options
author | Jenkins <jenkins@review.openstack.org> | 2015-04-04 07:52:53 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2015-04-04 07:52:53 +0000 |
commit | d7d488278495c8afedd391a2170df70c32f7af8f (patch) | |
tree | a1e14b40d71670ee72576be56721af7f90752f71 | |
parent | 1d5303e21287a84f72d771a74e56dc452a895464 (diff) | |
parent | 32387f8ffd3ba6e45064d675d2b18cb666397894 (diff) | |
download | trove-d7d488278495c8afedd391a2170df70c32f7af8f.tar.gz |
Merge "Fix replica source state validation"
-rw-r--r-- | trove/instance/models.py | 12 | ||||
-rw-r--r-- | trove/tests/api/replication.py | 10 | ||||
-rw-r--r-- | trove/tests/unittests/instance/test_instance_models.py | 85 |
3 files changed, 85 insertions, 22 deletions
diff --git a/trove/instance/models.py b/trove/instance/models.py index d1d0a0ae..0a416019 100644 --- a/trove/instance/models.py +++ b/trove/instance/models.py @@ -729,6 +729,18 @@ class Instance(BuiltInstance): raise exception.Forbidden( _("Cannot create a replica of a replica %(id)s.") % {'id': slave_of_id}) + # load the replica source status to check if + # source is available + load_simple_instance_server_status( + context, + replica_source) + replica_source_instance = Instance( + context, replica_source, + None, + InstanceServiceStatus.find_by( + context, + instance_id=slave_of_id)) + replica_source_instance.validate_can_perform_action() except exception.ModelNotFoundError: LOG.exception( _("Cannot create a replica of %(id)s " diff --git a/trove/tests/api/replication.py b/trove/tests/api/replication.py index 905b8bfa..9b57c4f7 100644 --- a/trove/tests/api/replication.py +++ b/trove/tests/api/replication.py @@ -107,6 +107,16 @@ def validate_master(master, slaves): class CreateReplicationSlave(object): @test + def test_replica_provisioning_with_missing_replica_source(self): + assert_raises(exceptions.NotFound, + instance_info.dbaas.instances.create, + instance_info.name + "_slave", + instance_info.dbaas_flavor_href, + instance_info.volume, + slave_of="Missing replica source") + assert_equal(404, instance_info.dbaas.last_http_code) + + @test def test_create_db_on_master(self): databases = [{'name': existing_db_on_master}] # Ensure that the auth_token in the dbaas client is not stale diff --git a/trove/tests/unittests/instance/test_instance_models.py b/trove/tests/unittests/instance/test_instance_models.py index 8c80dd7c..1183afe9 100644 --- a/trove/tests/unittests/instance/test_instance_models.py +++ b/trove/tests/unittests/instance/test_instance_models.py @@ -18,7 +18,6 @@ from trove.common import cfg from trove.common import exception from trove.backup import models as backup_models from trove.datastore import models as datastore_models -from trove.datastore.models import DBDatastoreVersion from trove.common.instance import ServiceStatuses from trove.instance.models import filter_ips from trove.instance.models import InstanceServiceStatus @@ -216,35 +215,77 @@ class TestReplication(TestCase): def setUp(self): util.init_db() - self.replica_datastore_version = Mock(spec=DBDatastoreVersion) - self.replica_datastore_version.id = "UUID" - self.replica_datastore_version.manager = 'mysql' - self.root_info = DBInstance( - InstanceTasks.NONE, - id="Another_instance", - name="TestInstance", - datastore_version_id=self.replica_datastore_version.id) - self.root_info.save() - self.replica_info = DBInstance( + + self.datastore = datastore_models.DBDatastore.create( + id=str(uuid.uuid4()), + name='name', + default_version_id=str(uuid.uuid4())) + + self.datastore_version = datastore_models.DBDatastoreVersion.create( + id=self.datastore.default_version_id, + name='name', + image_id=str(uuid.uuid4()), + packages=str(uuid.uuid4()), + datastore_id=self.datastore.id, + manager='mysql', + active=1) + + self.master = DBInstance( InstanceTasks.NONE, - id="UUID", - name="TestInstance", - datastore_version_id=self.replica_datastore_version.id, - slave_of_id="Another_instance") - self.replica_info.save() - self.safe_nova = models.create_nova_client - models.create_nova_client = nova.fake_create_nova_client + id=str(uuid.uuid4()), + name="TestMasterInstance", + datastore_version_id=self.datastore_version.id) + self.master.set_task_status(InstanceTasks.NONE) + self.master.save() + self.master_status = InstanceServiceStatus( + ServiceStatuses.RUNNING, + id=str(uuid.uuid4()), + instance_id=self.master.id) + self.master_status.save() + self.safe_nova_client = models.create_nova_client + models.create_nova_client = nova.fake_create_nova_client super(TestReplication, self).setUp() def tearDown(self): - models.create_nova_client = self.safe_nova - self.replica_info.delete() - self.root_info.delete() + self.master.delete() + self.master_status.delete() + self.datastore.delete() + self.datastore_version.delete() + models.create_nova_client = self.safe_nova_client super(TestReplication, self).tearDown() + def test_replica_of_not_active_master(self): + self.master.set_task_status(InstanceTasks.BUILDING) + self.master.save() + self.master_status.set_status(ServiceStatuses.BUILDING) + self.master_status.save() + self.assertRaises(exception.UnprocessableEntity, + Instance.create, + None, 'name', 1, "UUID", [], [], None, + self.datastore_version, 1, + None, slave_of_id=self.master.id) + + def test_replica_with_invalid_slave_of_id(self): + self.assertRaises(exception.NotFound, + Instance.create, + None, 'name', 1, "UUID", [], [], None, + self.datastore_version, 1, + None, slave_of_id=str(uuid.uuid4())) + def test_create_replica_from_replica(self): + self.replica_datastore_version = Mock( + spec=datastore_models.DBDatastoreVersion) + self.replica_datastore_version.id = "UUID" + self.replica_datastore_version.manager = 'mysql' + self.replica_info = DBInstance( + InstanceTasks.NONE, + id="UUID", + name="TestInstance", + datastore_version_id=self.replica_datastore_version.id, + slave_of_id=self.master.id) + self.replica_info.save() self.assertRaises(exception.Forbidden, Instance.create, None, 'name', 2, "UUID", [], [], None, - self.replica_datastore_version, 1, + self.datastore_version, 1, None, slave_of_id=self.replica_info.id) |