From 0d958e9b1c5ae7394b356ce488fd2c868984494f Mon Sep 17 00:00:00 2001 From: Mike Fuller Date: Fri, 30 Jan 2015 17:12:51 +1100 Subject: [PATCH] Added read replica support --- README.md | 3 --- moto/rds2/models.py | 6 +++-- moto/rds2/responses.py | 16 +++++------ tests/test_rds2/test_rds2.py | 51 +++++++++++++++--------------------- 4 files changed, 33 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index a20e3f379..fb6b43593 100644 --- a/README.md +++ b/README.md @@ -80,9 +80,6 @@ It gets even better! Moto isn't just S3. Here's the status of the other AWS serv | RDS | @mock_rds | core endpoints done | |------------------------------------------------------------------------------| | RDS2 | @mock_rds2 | core endpoints done | -| - Database | | core endpoints done | -| - Security Group | | not done | -| - Option Group | | core endpoints done | |------------------------------------------------------------------------------| | Route53 | @mock_route53 | core endpoints done | |------------------------------------------------------------------------------| diff --git a/moto/rds2/models.py b/moto/rds2/models.py index 915386c00..82349aa06 100644 --- a/moto/rds2/models.py +++ b/moto/rds2/models.py @@ -88,14 +88,12 @@ class Database(object): def address(self): return "{0}.aaaaaaaaaa.{1}.rds.amazonaws.com".format(self.db_instance_identifier, self.region) - # TODO: confirm how this should represent in the RESULT JSON def add_replica(self, replica): self.replicas.append(replica.db_instance_identifier) def remove_replica(self, replica): self.replicas.remove(replica.db_instance_identifier) - # TODO: confirm how this should represent in the RESULT JSON def set_as_replica(self): self.is_replica = True self.replicas = [] @@ -210,7 +208,11 @@ class Database(object): "{{ replica }}" {%- endfor -%} ], + {%- if database.source_db_identifier -%} + "ReadReplicaSourceDBInstanceIdentifier": "{{ database.source_db_identifier }}", + {%- else -%} "ReadReplicaSourceDBInstanceIdentifier": null, + {%- endif -%} "SecondaryAvailabilityZone": null, "StatusInfos": null, "VpcSecurityGroups": [ diff --git a/moto/rds2/responses.py b/moto/rds2/responses.py index c4753e603..8df22f467 100644 --- a/moto/rds2/responses.py +++ b/moto/rds2/responses.py @@ -293,14 +293,14 @@ CREATE_DATABASE_TEMPLATE = """{ } }""" -CREATE_DATABASE_REPLICA_TEMPLATE = """{ - "CreateDBInstanceResponse": { - "CreateDBInstanceResult": { - {{ database.to_json() }} - }, - "ResponseMetadata": { "RequestId": "523e3218-afc7-11c3-90f5-f90431260ab4" } +CREATE_DATABASE_REPLICA_TEMPLATE = """{"CreateDBInstanceReadReplicaResponse": { + "ResponseMetadata": { + "RequestId": "5e60c46d-a844-11e4-bb68-17f36418e58f" + }, + "CreateDBInstanceReadReplicaResult": { + "DBInstance": {{ database.to_json() }} } -}""" +}}""" DESCRIBE_DATABASES_TEMPLATE = """{ "DescribeDBInstancesResponse": { @@ -336,7 +336,7 @@ REBOOT_DATABASE_TEMPLATE = """{"RebootDBInstanceResponse": { } }""" -# TODO: update delete DB TEMPLATE + DELETE_DATABASE_TEMPLATE = """{ "DeleteDBInstanceResponse": { "DeleteDBInstanceResult": { "DBInstance": {{ database.to_json() }} diff --git a/tests/test_rds2/test_rds2.py b/tests/test_rds2/test_rds2.py index a6d930ea0..81e8a54bf 100644 --- a/tests/test_rds2/test_rds2.py +++ b/tests/test_rds2/test_rds2.py @@ -4,7 +4,6 @@ import boto.rds2 import boto.vpc from boto.exception import BotoServerError import sure # noqa -import json from moto import mock_ec2, mock_rds2 from tests.helpers import disable_on_py3 @@ -543,36 +542,28 @@ def test_delete_database_subnet_group(): conn.delete_db_subnet_group.when.called_with("db_subnet1").should.throw(BotoServerError) +@disable_on_py3() +@mock_rds2 +def test_create_database_replica(): + conn = boto.rds2.connect_to_region("us-west-2") -#@disable_on_py3() -#@mock_rds2 -#def test_create_database_replica(): -# conn = boto.rds2.connect_to_region("us-west-2") -# -# conn.create_db_instance(db_instance_identifier='db-master-1', -# allocated_storage=10, -# engine='postgres', -# db_instance_class='db.m1.small', -# master_username='root', -# master_user_password='hunter2', -# db_security_groups=["my_sg"]) -# -# # TODO: confirm the RESULT JSON -# replica = conn.create_db_instance_read_replica("replica", "db-master-1", "db.m1.small") -# print replica - #replica.id.should.equal("replica") - #replica.instance_class.should.equal("db.m1.small") - #status_info = replica.status_infos[0] - #status_info.normal.should.equal(True) - #status_info.status_type.should.equal('read replication') - #status_info.status.should.equal('replicating') + conn.create_db_instance(db_instance_identifier='db-master-1', + allocated_storage=10, + engine='postgres', + db_instance_class='db.m1.small', + master_username='root', + master_user_password='hunter2', + db_security_groups=["my_sg"]) - # TODO: formulate checks on read replica status -# primary = conn.describe_db_instances("db-master-1") -# print primary - #primary.read_replica_dbinstance_identifiers[0].should.equal("replica") + replica = conn.create_db_instance_read_replica("db-replica-1", "db-master-1", "db.m1.small") + replica['CreateDBInstanceReadReplicaResponse']['CreateDBInstanceReadReplicaResult']['DBInstance']['ReadReplicaSourceDBInstanceIdentifier'].should.equal('db-master-1') + replica['CreateDBInstanceReadReplicaResponse']['CreateDBInstanceReadReplicaResult']['DBInstance']['DBInstanceClass'].should.equal('db.m1.small') + replica['CreateDBInstanceReadReplicaResponse']['CreateDBInstanceReadReplicaResult']['DBInstance']['DBInstanceIdentifier'].should.equal('db-replica-1') - #conn.delete_dbinstance("replica") + master = conn.describe_db_instances("db-master-1") + master['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances'][0]['ReadReplicaDBInstanceIdentifiers'].should.equal(['db-replica-1']) - #primary = conn.get_all_dbinstances("db-master-1")[0] - #list(primary.read_replica_dbinstance_identifiers).should.have.length_of(0) + conn.delete_db_instance("db-replica-1") + + master = conn.describe_db_instances("db-master-1") + master['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances'][0]['ReadReplicaDBInstanceIdentifiers'].should.equal([])