diff options
Diffstat (limited to 'tests/unit/route53')
-rw-r--r-- | tests/unit/route53/test_connection.py | 133 | ||||
-rw-r--r-- | tests/unit/route53/test_zone.py | 63 |
2 files changed, 187 insertions, 9 deletions
diff --git a/tests/unit/route53/test_connection.py b/tests/unit/route53/test_connection.py index 16df3747..3c696c7a 100644 --- a/tests/unit/route53/test_connection.py +++ b/tests/unit/route53/test_connection.py @@ -20,10 +20,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # -from tests.compat import mock, unittest +from tests.compat import mock import re import xml.dom.minidom - from boto.exception import BotoServerError from boto.route53.connection import Route53Connection from boto.route53.exception import DNSServerError @@ -33,6 +32,9 @@ from boto.route53.zone import Zone from nose.plugins.attrib import attr from tests.unit import AWSMockServiceTestCase +from boto.compat import six +urllib = six.moves.urllib + @attr(route53=True) class TestRoute53Connection(AWSMockServiceTestCase): @@ -52,7 +54,7 @@ class TestRoute53Connection(AWSMockServiceTestCase): def test_typical_400(self): self.set_http_response(status_code=400, header=[ - ['Code', 'Throttling'], + ['Code', 'AccessDenied'], ]) with self.assertRaises(DNSServerError) as err: @@ -60,11 +62,22 @@ class TestRoute53Connection(AWSMockServiceTestCase): self.assertTrue('It failed.' in str(err.exception)) - @mock.patch('time.sleep') - def test_retryable_400(self, sleep_mock): + def test_retryable_400_prior_request_not_complete(self): + # Test ability to retry on ``PriorRequestNotComplete``. self.set_http_response(status_code=400, header=[ ['Code', 'PriorRequestNotComplete'], ]) + self.do_retry_handler() + + def test_retryable_400_throttling(self): + # Test ability to rety on ``Throttling``. + self.set_http_response(status_code=400, header=[ + ['Code', 'Throttling'], + ]) + self.do_retry_handler() + + @mock.patch('time.sleep') + def do_retry_handler(self, sleep_mock): def incr_retry_handler(func): def _wrapper(*args, **kwargs): @@ -88,6 +101,7 @@ class TestRoute53Connection(AWSMockServiceTestCase): # Unpatch. self.service_connection._retry_handler = orig_retry + @attr(route53=True) class TestCreateZoneRoute53(AWSMockServiceTestCase): connection_class = Route53Connection @@ -138,6 +152,7 @@ class TestCreateZoneRoute53(AWSMockServiceTestCase): self.assertEqual(response['CreateHostedZoneResponse']['DelegationSet']['NameServers'], ['ns-100.awsdns-01.com', 'ns-1000.awsdns-01.co.uk', 'ns-1000.awsdns-01.org', 'ns-900.awsdns-01.net']) + @attr(route53=True) class TestGetZoneRoute53(AWSMockServiceTestCase): connection_class = Route53Connection @@ -195,6 +210,7 @@ class TestGetZoneRoute53(AWSMockServiceTestCase): self.assertTrue(isinstance(response, Zone)) self.assertEqual(response.name, "example.com.") + @attr(route53=True) class TestGetHostedZoneRoute53(AWSMockServiceTestCase): connection_class = Route53Connection @@ -232,6 +248,7 @@ class TestGetHostedZoneRoute53(AWSMockServiceTestCase): self.assertEqual(response['GetHostedZoneResponse']['DelegationSet']['NameServers'], ['ns-1000.awsdns-40.org', 'ns-200.awsdns-30.com', 'ns-900.awsdns-50.net', 'ns-1000.awsdns-00.co.uk']) + @attr(route53=True) class TestGetAllRRSetsRoute53(AWSMockServiceTestCase): connection_class = Route53Connection @@ -321,10 +338,9 @@ class TestGetAllRRSetsRoute53(AWSMockServiceTestCase): self.set_http_response(status_code=200) response = self.service_connection.get_all_rrsets("Z1111", "A", "example.com.") - self.assertIn(self.actual_request.path, - ("/2013-04-01/hostedzone/Z1111/rrset?type=A&name=example.com.", - "/2013-04-01/hostedzone/Z1111/rrset?name=example.com.&type=A")) + ("/2013-04-01/hostedzone/Z1111/rrset?type=A&name=example.com.", + "/2013-04-01/hostedzone/Z1111/rrset?name=example.com.&type=A")) self.assertTrue(isinstance(response, ResourceRecordSets)) self.assertEqual(response.hosted_zone_id, "Z1111") @@ -371,6 +387,104 @@ class TestGetAllRRSetsRoute53(AWSMockServiceTestCase): self.assertEqual(healthcheck_record.identifier, 'latency-example-us-west-2-evaluate-health-healthcheck') self.assertEqual(healthcheck_record.alias_dns_name, 'example-123456-evaluate-health-healthcheck.us-west-2.elb.amazonaws.com.') + +@attr(route53=True) +class TestTruncatedGetAllRRSetsRoute53(AWSMockServiceTestCase): + connection_class = Route53Connection + + def setUp(self): + super(TestTruncatedGetAllRRSetsRoute53, self).setUp() + + def default_body(self): + return b""" +<ListResourceRecordSetsResponse xmlns="https://route53.amazonaws.com/doc/2013-04-01/"> + <ResourceRecordSets> + <ResourceRecordSet> + <Name>example.com.</Name> + <Type>NS</Type> + <TTL>900</TTL> + <ResourceRecords> + <ResourceRecord> + <Value>ns-91.awsdns-41.co.uk.</Value> + </ResourceRecord> + <ResourceRecord> + <Value>ns-1929.awsdns-93.net.</Value> + </ResourceRecord> + <ResourceRecord> + <Value>ns-12.awsdns-21.org.</Value> + </ResourceRecord> + <ResourceRecord> + <Value>ns-102.awsdns-96.com.</Value> + </ResourceRecord> + </ResourceRecords> + </ResourceRecordSet> + <ResourceRecordSet> + <Name>example.com.</Name> + <Type>SOA</Type> + <TTL>1800</TTL> + <ResourceRecords> + <ResourceRecord> + <Value>ns-1929.awsdns-93.net. hostmaster.awsdns.net. 1 10800 3600 604800 1800</Value> + </ResourceRecord> + </ResourceRecords> + </ResourceRecordSet> + <ResourceRecordSet> + <Name>wrr.example.com.</Name> + <Type>A</Type> + <SetIdentifier>primary</SetIdentifier> + <Weight>100</Weight> + <TTL>300</TTL> + <ResourceRecords> + <ResourceRecord><Value>127.0.0.1</Value></ResourceRecord> + </ResourceRecords> + </ResourceRecordSet> + </ResourceRecordSets> + <IsTruncated>true</IsTruncated> + <NextRecordName>wrr.example.com.</NextRecordName> + <NextRecordType>A</NextRecordType> + <NextRecordIdentifier>secondary</NextRecordIdentifier> + <MaxItems>3</MaxItems> +</ListResourceRecordSetsResponse>""" + + def paged_body(self): + return b""" +<ListResourceRecordSetsResponse xmlns="https://route53.amazonaws.com/doc/2013-04-01/"> + <ResourceRecordSets> + <ResourceRecordSet> + <Name>wrr.example.com.</Name> + <Type>A</Type> + <SetIdentifier>secondary</SetIdentifier> + <Weight>50</Weight> + <TTL>300</TTL> + <ResourceRecords> + <ResourceRecord><Value>127.0.0.2</Value></ResourceRecord> + </ResourceRecords> + </ResourceRecordSet> + </ResourceRecordSets> + <IsTruncated>false</IsTruncated> + <MaxItems>3</MaxItems> +</ListResourceRecordSetsResponse>""" + + + def test_get_all_rr_sets(self): + self.set_http_response(status_code=200) + response = self.service_connection.get_all_rrsets("Z1111", maxitems=3) + + # made first request + self.assertEqual(self.actual_request.path, '/2013-04-01/hostedzone/Z1111/rrset?maxitems=3') + + # anticipate a second request when we page it + self.set_http_response(status_code=200, body=self.paged_body()) + + # this should trigger another call to get_all_rrsets + self.assertEqual(len(list(response)), 4) + + url_parts = urllib.parse.urlparse(self.actual_request.path) + self.assertEqual(url_parts.path, '/2013-04-01/hostedzone/Z1111/rrset') + self.assertEqual(urllib.parse.parse_qs(url_parts.query), + dict(type=['A'], name=['wrr.example.com.'], identifier=['secondary'])) + + @attr(route53=True) class TestCreateHealthCheckRoute53IpAddress(AWSMockServiceTestCase): connection_class = Route53Connection @@ -414,6 +528,7 @@ class TestCreateHealthCheckRoute53IpAddress(AWSMockServiceTestCase): self.assertEqual(hc_resp['SearchString'], 'OK') self.assertEqual(response['CreateHealthCheckResponse']['HealthCheck']['Id'], '34778cf8-e31e-4974-bad0-b108bd1623d3') + @attr(route53=True) class TestCreateHealthCheckRoute53FQDN(AWSMockServiceTestCase): connection_class = Route53Connection @@ -455,6 +570,7 @@ class TestCreateHealthCheckRoute53FQDN(AWSMockServiceTestCase): self.assertEqual(hc_resp['ResourcePath'], '/health_check') self.assertEqual(response['CreateHealthCheckResponse']['HealthCheck']['Id'], 'f9abfe10-8d2a-4bbd-8f35-796f0f8572f2') + @attr(route53=True) class TestChangeResourceRecordSetsRoute53(AWSMockServiceTestCase): connection_class = Route53Connection @@ -569,4 +685,3 @@ class TestChangeResourceRecordSetsRoute53(AWSMockServiceTestCase): # Note: the alias XML should not include the TTL, even if it's specified in the object model self.assertEqual(actual_xml, expected_xml) - diff --git a/tests/unit/route53/test_zone.py b/tests/unit/route53/test_zone.py new file mode 100644 index 00000000..12d1d254 --- /dev/null +++ b/tests/unit/route53/test_zone.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# Copyright (c) 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, dis- +# tribute, sublicense, and/or sell copies of the Software, and to permit +# persons to whom the Software is furnished to do so, subject to the fol- +# lowing conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- +# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +from boto.route53.zone import Zone +from tests.compat import mock, unittest + + +class TestZone(unittest.TestCase): + def test_find_records(self): + mock_connection = mock.Mock() + zone = Zone(mock_connection, {}) + zone.id = None + rr_names = ['amazon.com', 'amazon.com', 'aws.amazon.com', + 'aws.amazon.com'] + mock_rrs = [] + # Create some mock resource records. + for rr_name in rr_names: + mock_rr = mock.Mock() + mock_rr.name = rr_name + mock_rr.type = 'A' + mock_rr.weight = None + mock_rr.region = None + mock_rrs.append(mock_rr) + + # Set the last resource record to ``None``. The ``find_records`` loop + # should never hit this. + mock_rrs[3] = None + + mock_connection.get_all_rrsets.return_value = mock_rrs + mock_connection._make_qualified.return_value = 'amazon.com' + + # Ensure that the ``None`` type object was not iterated over. + try: + result_rrs = zone.find_records('amazon.com', 'A', all=True) + except AttributeError as e: + self.fail("find_records() iterated too far into resource" + " record list.") + + # Determine that the resulting records are correct. + self.assertEqual(result_rrs, [mock_rrs[0], mock_rrs[1]]) + + +if __name__ == "__main__": + unittest.main() |