summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-04-04 07:52:53 +0000
committerGerrit Code Review <review@openstack.org>2015-04-04 07:52:53 +0000
commitd7d488278495c8afedd391a2170df70c32f7af8f (patch)
treea1e14b40d71670ee72576be56721af7f90752f71
parent1d5303e21287a84f72d771a74e56dc452a895464 (diff)
parent32387f8ffd3ba6e45064d675d2b18cb666397894 (diff)
downloadtrove-d7d488278495c8afedd391a2170df70c32f7af8f.tar.gz
Merge "Fix replica source state validation"
-rw-r--r--trove/instance/models.py12
-rw-r--r--trove/tests/api/replication.py10
-rw-r--r--trove/tests/unittests/instance/test_instance_models.py85
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)