libcloud-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From to...@apache.org
Subject [1/2] libcloud git commit: Update worldwidedns provider with tests.
Date Sun, 01 Nov 2015 18:36:13 GMT
Repository: libcloud
Updated Branches:
  refs/heads/trunk 26d6ac384 -> 624032598


Update worldwidedns provider with tests.

Closes #621

Signed-off-by: Tomaz Muraus <tomaz@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/e9e5f35e
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/e9e5f35e
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/e9e5f35e

Branch: refs/heads/trunk
Commit: e9e5f35e6cbdb2821bfb23d4061634a3b4eef592
Parents: 26d6ac3
Author: Alejandro Pereira <alepereira.dev@gmail.com>
Authored: Mon Oct 12 12:26:49 2015 -0300
Committer: Tomaz Muraus <tomaz@apache.org>
Committed: Sun Nov 1 19:23:26 2015 +0100

----------------------------------------------------------------------
 libcloud/dns/drivers/worldwidedns.py            |  87 ++++++++-----
 ...ify_asp_CREATE_RECORD_MAX_ENTRIES_WITH_ENTRY |  46 +++++++
 ...ns_list_domain_asp_CREATE_RECORD_MAX_ENTRIES |  46 +++++++
 ...api_dns_list_domain_asp_CREATE_SECOND_RECORD |  46 +++++++
 libcloud/test/dns/test_worldwidedns.py          | 126 +++++++++++++++----
 5 files changed, 293 insertions(+), 58 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/e9e5f35e/libcloud/dns/drivers/worldwidedns.py
----------------------------------------------------------------------
diff --git a/libcloud/dns/drivers/worldwidedns.py b/libcloud/dns/drivers/worldwidedns.py
index e3193bd..69373b1 100644
--- a/libcloud/dns/drivers/worldwidedns.py
+++ b/libcloud/dns/drivers/worldwidedns.py
@@ -144,22 +144,24 @@ class WorldWideDNSDriver(DNSDriver):
         :param zone_id: ID of the required zone
         :type  zone_id: ``str``
 
-        :param record_id: ID of the required record
+        :param record_id: ID number of the required record.
         :type  record_id: ``str``
 
         :rtype: :class:`Record`
         """
         zone = self.get_zone(zone_id)
-        r_entry = [i for i in range(MAX_RECORD_ENTRIES) if
-                   zone.extra.get('S%s' % i) == record_id]
-        if not r_entry:
-            raise RecordDoesNotExistError(value="Record doesn't exists",
-                                          driver=zone.driver,
-                                          record_id=record_id)
-        entry = r_entry[0]
-        type = zone.extra.get('T%s' % entry)
-        data = zone.extra.get('D%s' % entry)
-        record = self._to_record(record_id, type, data, zone)
+        try:
+            if int(record_id) not in range(1, MAX_RECORD_ENTRIES + 1):
+                raise RecordDoesNotExistError(value="Record doesn't exists",
+                                              driver=zone.driver,
+                                              record_id=record_id)
+        except ValueError:
+            raise WorldWideDNSError(
+                value="Record id should be a string number", driver=self)
+        subdomain = zone.extra.get('S%s' % record_id)
+        type = zone.extra.get('T%s' % record_id)
+        data = zone.extra.get('D%s' % record_id)
+        record = self._to_record(record_id, subdomain, type, data, zone)
         return record
 
     def update_zone(self, zone, domain, type='master', ttl=None, extra=None,
@@ -259,7 +261,7 @@ class WorldWideDNSDriver(DNSDriver):
         if (extra is None) or ('entry' not in extra):
             raise WorldWideDNSError(value="You must enter 'entry' parameter",
                                     driver=self)
-        entry = extra.get('entry')
+        record_id = extra.get('entry')
         if name == '':
             name = '@'
         if type not in self.RECORD_TYPE_MAP:
@@ -267,11 +269,11 @@ class WorldWideDNSDriver(DNSDriver):
                               driver=record.zone.driver,
                               record_id=name)
         zone = record.zone
-        extra = {'S%s' % entry: name,
-                 'T%s' % entry: type,
-                 'D%s' % entry: data}
+        extra = {'S%s' % record_id: name,
+                 'T%s' % record_id: type,
+                 'D%s' % record_id: data}
         zone = self.update_zone(zone, zone.domain, extra=extra)
-        record = self.get_record(zone.id, name)
+        record = self.get_record(zone.id, record_id)
         return record
 
     def create_zone(self, domain, type='master', ttl=None, extra=None):
@@ -323,6 +325,9 @@ class WorldWideDNSDriver(DNSDriver):
         """
         Create a new record.
 
+        We can create 40 record per domain. If all slots are full, we can
+        replace one of them by choosing a specific entry in ``extra`` argument.
+
         :param name: Record name without the domain name (e.g. www).
                      Note: If you want to create a record for a base domain
                      name, you should specify empty string ('') for this
@@ -344,20 +349,25 @@ class WorldWideDNSDriver(DNSDriver):
         :rtype: :class:`Record`
         """
         if (extra is None) or ('entry' not in extra):
-            raise WorldWideDNSError(value="You must enter 'entry' parameter",
-                                    driver=zone.driver)
-        entry = extra.get('entry')
+            # If no entry is specified, we look for an available one. If all
+            # are full, raise error.
+            record_id = self._get_available_record_entry(zone)
+            if not record_id:
+                raise WorldWideDNSError(value="All record entries are full",
+                                        driver=zone.driver)
+        else:
+            record_id = extra.get('entry')
         if name == '':
             name = '@'
         if type not in self.RECORD_TYPE_MAP:
             raise RecordError(value="Record type is not allowed",
                               driver=zone.driver,
-                              record_id=name)
-        extra = {'S%s' % entry: name,
-                 'T%s' % entry: type,
-                 'D%s' % entry: data}
+                              record_id=record_id)
+        extra = {'S%s' % record_id: name,
+                 'T%s' % record_id: type,
+                 'D%s' % record_id: data}
         zone = self.update_zone(zone, zone.domain, extra=extra)
-        record = self.get_record(zone.id, name)
+        record = self.get_record(zone.id, record_id)
         return record
 
     def delete_zone(self, zone):
@@ -454,6 +464,17 @@ class WorldWideDNSDriver(DNSDriver):
                                            params=params)
         return response.success()
 
+    def _get_available_record_entry(self, zone):
+        """Return an available entry to store a record."""
+        entries = zone.extra
+        for entry in range(1, MAX_RECORD_ENTRIES + 1):
+            subdomain = entries.get('S%s' % entry)
+            _type = entries.get('T%s' % entry)
+            data = entries.get('D%s' % entry)
+            if not any([subdomain, _type, data]):
+                return entry
+        return None
+
     def _to_zones(self, data):
         domain_list = re.split('\r?\n', data)
         zones = []
@@ -479,7 +500,8 @@ class WorldWideDNSDriver(DNSDriver):
             for line in range(MAX_RECORD_ENTRIES):
                 line_data = zone_data[line].split('\x1f')
                 extra['S%s' % (line + 1)] = line_data[0]
-                extra['T%s' % (line + 1)] = line_data[1]
+                _type = line_data[1]
+                extra['T%s' % (line + 1)] = _type if _type != 'NONE' else ''
                 try:
                     extra['D%s' % (line + 1)] = line_data[2]
                 except IndexError:
@@ -499,14 +521,15 @@ class WorldWideDNSDriver(DNSDriver):
 
     def _to_records(self, zone):
         records = []
-        for entry in range(MAX_RECORD_ENTRIES):
-            subdomain = zone.extra['S%s' % (entry + 1)]
-            type = zone.extra['T%s' % (entry + 1)]
-            data = zone.extra['D%s' % (entry + 1)]
+        for record_id in range(1, MAX_RECORD_ENTRIES + 1):
+            subdomain = zone.extra['S%s' % (record_id)]
+            type = zone.extra['T%s' % (record_id)]
+            data = zone.extra['D%s' % (record_id)]
             if subdomain and type and data:
-                record = self._to_record(subdomain, type, data, zone)
+                record = self._to_record(
+                    record_id, subdomain, type, data, zone)
                 records.append(record)
         return records
 
-    def _to_record(self, subdomain, type, data, zone):
-        return Record(subdomain, subdomain, type, data, zone, zone.driver)
+    def _to_record(self, _id, subdomain, type, data, zone):
+        return Record(_id, subdomain, type, data, zone, zone.driver)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e9e5f35e/libcloud/test/dns/fixtures/worldwidedns/_api_dns_modify_asp_CREATE_RECORD_MAX_ENTRIES_WITH_ENTRY
----------------------------------------------------------------------
diff --git a/libcloud/test/dns/fixtures/worldwidedns/_api_dns_modify_asp_CREATE_RECORD_MAX_ENTRIES_WITH_ENTRY
b/libcloud/test/dns/fixtures/worldwidedns/_api_dns_modify_asp_CREATE_RECORD_MAX_ENTRIES_WITH_ENTRY
new file mode 100644
index 0000000..c001c0c
--- /dev/null
+++ b/libcloud/test/dns/fixtures/worldwidedns/_api_dns_modify_asp_CREATE_RECORD_MAX_ENTRIES_WITH_ENTRY
@@ -0,0 +1,46 @@
+hostmaster.niteowebsponsoredthisone.com
+21600
+10800
+604800
+43200
+
+wwwA0.0.0.0
+domain2A0.0.0.2
+@MX10 niteowebsponsoredthisone.com
+domain4A0.0.0.4
+domain5A0.0.0.5
+domain6A0.0.0.6
+domain7A0.0.0.7
+domain8A0.0.0.8
+domain9A0.0.0.9
+domain10A0.0.0.10
+domain11A0.0.0.11
+domain12A0.0.0.12
+domain13A0.0.0.13
+domain14A0.0.0.14
+domain15A0.0.0.15
+domain16A0.0.0.16
+domain17A0.0.0.17
+domain18A0.0.0.18
+domain19A0.0.0.19
+domain20A0.0.0.20
+domain21A0.0.0.21
+domain22A0.0.0.22
+domain23bA0.0.0.41
+domain24A0.0.0.24
+domain25A0.0.0.25
+domain26A0.0.0.26
+domain27A0.0.0.27
+domain28A0.0.0.28
+domain29A0.0.0.29
+domain30A0.0.0.30
+domain31A0.0.0.31
+domain32A0.0.0.32
+domain33A0.0.0.33
+domain34A0.0.0.34
+domain35A0.0.0.35
+domain36A0.0.0.36
+domain37A0.0.0.37
+domain38A0.0.0.38
+domain39A0.0.0.39
+domain40A0.0.0.40
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e9e5f35e/libcloud/test/dns/fixtures/worldwidedns/api_dns_list_domain_asp_CREATE_RECORD_MAX_ENTRIES
----------------------------------------------------------------------
diff --git a/libcloud/test/dns/fixtures/worldwidedns/api_dns_list_domain_asp_CREATE_RECORD_MAX_ENTRIES
b/libcloud/test/dns/fixtures/worldwidedns/api_dns_list_domain_asp_CREATE_RECORD_MAX_ENTRIES
new file mode 100644
index 0000000..ff570e5
--- /dev/null
+++ b/libcloud/test/dns/fixtures/worldwidedns/api_dns_list_domain_asp_CREATE_RECORD_MAX_ENTRIES
@@ -0,0 +1,46 @@
+hostmaster.niteowebsponsoredthisone.com
+21600
+10800
+604800
+43200
+
+wwwA0.0.0.0
+domain2A0.0.0.2
+@MX10 niteowebsponsoredthisone.com
+domain4A0.0.0.4
+domain5A0.0.0.5
+domain6A0.0.0.6
+domain7A0.0.0.7
+domain8A0.0.0.8
+domain9A0.0.0.9
+domain10A0.0.0.10
+domain11A0.0.0.11
+domain12A0.0.0.12
+domain13A0.0.0.13
+domain14A0.0.0.14
+domain15A0.0.0.15
+domain16A0.0.0.16
+domain17A0.0.0.17
+domain18A0.0.0.18
+domain19A0.0.0.19
+domain20A0.0.0.20
+domain21A0.0.0.21
+domain22A0.0.0.22
+domain23A0.0.0.23
+domain24A0.0.0.24
+domain25A0.0.0.25
+domain26A0.0.0.26
+domain27A0.0.0.27
+domain28A0.0.0.28
+domain29A0.0.0.29
+domain30A0.0.0.30
+domain31A0.0.0.31
+domain32A0.0.0.32
+domain33A0.0.0.33
+domain34A0.0.0.34
+domain35A0.0.0.35
+domain36A0.0.0.36
+domain37A0.0.0.37
+domain38A0.0.0.38
+domain39A0.0.0.39
+domain40A0.0.0.40
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e9e5f35e/libcloud/test/dns/fixtures/worldwidedns/api_dns_list_domain_asp_CREATE_SECOND_RECORD
----------------------------------------------------------------------
diff --git a/libcloud/test/dns/fixtures/worldwidedns/api_dns_list_domain_asp_CREATE_SECOND_RECORD
b/libcloud/test/dns/fixtures/worldwidedns/api_dns_list_domain_asp_CREATE_SECOND_RECORD
new file mode 100644
index 0000000..b6b7701
--- /dev/null
+++ b/libcloud/test/dns/fixtures/worldwidedns/api_dns_list_domain_asp_CREATE_SECOND_RECORD
@@ -0,0 +1,46 @@
+hostmaster.niteowebsponsoredthisone.com
+21600
+10800
+604800
+43200
+
+wwwA0.0.0.0
+domain2A0.0.0.2
+@MX10 niteowebsponsoredthisone.com
+domain4A0.0.0.4
+domain1A0.0.0.1
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
+NONE
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e9e5f35e/libcloud/test/dns/test_worldwidedns.py
----------------------------------------------------------------------
diff --git a/libcloud/test/dns/test_worldwidedns.py b/libcloud/test/dns/test_worldwidedns.py
index 3b19722..388e5c0 100644
--- a/libcloud/test/dns/test_worldwidedns.py
+++ b/libcloud/test/dns/test_worldwidedns.py
@@ -70,7 +70,7 @@ class WorldWideDNSTests(unittest.TestCase):
         self.assertEqual(len(records), 3)
 
         www = records[0]
-        self.assertEqual(www.id, 'www')
+        self.assertEqual(www.id, '1')
         self.assertEqual(www.name, 'www')
         self.assertEqual(www.type, RecordType.A)
         self.assertEqual(www.data, '0.0.0.0')
@@ -109,8 +109,8 @@ class WorldWideDNSTests(unittest.TestCase):
 
     def test_get_record_success(self):
         record = self.driver.get_record(zone_id='niteowebsponsoredthisone.com',
-                                        record_id='www')
-        self.assertEqual(record.id, 'www')
+                                        record_id='1')
+        self.assertEqual(record.id, '1')
         self.assertEqual(record.name, 'www')
         self.assertEqual(record.type, RecordType.A)
         self.assertEqual(record.data, '0.0.0.0')
@@ -195,56 +195,77 @@ class WorldWideDNSTests(unittest.TestCase):
                                            type=RecordType.A, data='0.0.0.4',
                                            extra={'entry': 4})
 
-        self.assertEqual(record.id, 'domain4')
+        self.assertEqual(record.id, '4')
         self.assertEqual(record.name, 'domain4')
         self.assertNotEqual(record.zone.extra.get('S4'), zone.extra.get('S4'))
         self.assertNotEqual(record.zone.extra.get('D4'), zone.extra.get('D4'))
         self.assertEqual(record.type, RecordType.A)
         self.assertEqual(record.data, '0.0.0.4')
 
-    def test_create_record_missing_entry(self):
+    def test_create_record_finding_entry(self):
         zone = self.driver.list_zones()[0]
         WorldWideDNSMockHttp.type = 'CREATE_RECORD'
+        record = self.driver.create_record(name='domain4', zone=zone,
+                                           type=RecordType.A, data='0.0.0.4')
+        WorldWideDNSMockHttp.type = 'CREATE_SECOND_RECORD'
+        zone = record.zone
+        record2 = self.driver.create_record(name='domain1', zone=zone,
+                                            type=RecordType.A, data='0.0.0.1')
+        self.assertEqual(record.id, '4')
+        self.assertEqual(record2.id, '5')
+
+    def test_create_record_max_entry_reached(self):
+        zone = self.driver.list_zones()[0]
+        WorldWideDNSMockHttp.type = 'CREATE_RECORD_MAX_ENTRIES'
+        record = self.driver.create_record(name='domain40', zone=zone,
+                                           type=RecordType.A, data='0.0.0.40')
+        WorldWideDNSMockHttp.type = 'CREATE_RECORD'
+        zone = record.zone
         try:
-            self.driver.create_record(name='domain1', zone=zone,
-                                      type=RecordType.A, data='0.0.0.1',
-                                      extra={'non_entry': 1})
+            self.driver.create_record(
+                name='domain41', zone=zone, type=RecordType.A, data='0.0.0.41')
         except WorldWideDNSError:
             e = sys.exc_info()[1]
-            self.assertEqual(e.value, "You must enter 'entry' parameter")
+            self.assertEqual(e.value, 'All record entries are full')
         else:
             self.fail('Exception was not thrown')
 
+    def test_create_record_max_entry_reached_give_entry(self):
+        WorldWideDNSMockHttp.type = 'CREATE_RECORD_MAX_ENTRIES'
+        zone = self.driver.list_zones()[0]
+        record = self.driver.get_record(zone.id, '23')
+        self.assertEqual(record.id, '23')
+        self.assertEqual(record.name, 'domain23')
+        self.assertEqual(record.type, 'A')
+        self.assertEqual(record.data, '0.0.0.23')
+
+        # No matter if we have all entries full, if we choose a specific
+        # entry, the record will be replaced with the new one.
+        WorldWideDNSMockHttp.type = 'CREATE_RECORD_MAX_ENTRIES_WITH_ENTRY'
+        record = self.driver.create_record(name='domain23b', zone=zone,
+                                           type=RecordType.A, data='0.0.0.41',
+                                           extra={'entry': 23})
+        zone = record.zone
+        self.assertEqual(record.id, '23')
+        self.assertEqual(record.name, 'domain23b')
+        self.assertEqual(record.type, 'A')
+        self.assertEqual(record.data, '0.0.0.41')
+
     def test_update_record_success(self):
         zone = self.driver.list_zones()[0]
-        record = self.driver.get_record(zone.id, 'www')
+        record = self.driver.get_record(zone.id, '1')
         WorldWideDNSMockHttp.type = 'UPDATE_RECORD'
         record = self.driver.update_record(record=record, name='domain1',
                                            type=RecordType.A, data='0.0.0.1',
                                            extra={'entry': 1})
 
-        self.assertEqual(record.id, 'domain1')
+        self.assertEqual(record.id, '1')
         self.assertEqual(record.name, 'domain1')
         self.assertNotEqual(record.zone.extra.get('S1'), zone.extra.get('S1'))
         self.assertNotEqual(record.zone.extra.get('D1'), zone.extra.get('D1'))
         self.assertEqual(record.type, RecordType.A)
         self.assertEqual(record.data, '0.0.0.1')
 
-    def test_update_record_missing_entry(self):
-        zone = self.driver.list_zones()[0]
-        record = self.driver.get_record(zone.id, 'www')
-        WorldWideDNSMockHttp.type = 'UPDATE_RECORD'
-        try:
-            record = self.driver.update_record(record=record, name='domain1',
-                                               type=RecordType.A,
-                                               data='0.0.0.1',
-                                               extra={'non_entry': 1})
-        except WorldWideDNSError:
-            e = sys.exc_info()[1]
-            self.assertEqual(e.value, "You must enter 'entry' parameter")
-        else:
-            self.fail('Exception was not thrown')
-
     def test_delete_zone_success(self):
         zone = self.driver.list_zones()[0]
         status = self.driver.delete_zone(zone=zone)
@@ -323,15 +344,68 @@ class WorldWideDNSMockHttp(MockHttp):
         body = self.fixtures.load('api_dns_list')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
+    def _api_dns_list_asp_CREATE_SECOND_RECORD(self, method, url, body,
+                                               headers):
+        body = self.fixtures.load('api_dns_list')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
     def _api_dns_modify_asp_CREATE_RECORD(self, method, url, body, headers):
         return (httplib.OK, '211\r\n212\r\n213', {},
                 httplib.responses[httplib.OK])
 
+    def _api_dns_modify_asp_CREATE_SECOND_RECORD(self, method, url, body,
+                                                 headers):
+        return (httplib.OK, '211\r\n212\r\n213', {},
+                httplib.responses[httplib.OK])
+
     def _api_dns_list_domain_asp_CREATE_RECORD(self, method, url, body,
                                                headers):
         body = self.fixtures.load('api_dns_list_domain_asp_CREATE_RECORD')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
+    def _api_dns_list_domain_asp_CREATE_SECOND_RECORD(self, method, url, body,
+                                                      headers):
+        body = self.fixtures.load(
+            'api_dns_list_domain_asp_CREATE_SECOND_RECORD')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_dns_list_domain_asp_CREATE_RECORD_MAX_ENTRIES(self, method, url,
+                                                           body, headers):
+        body = self.fixtures.load(
+            'api_dns_list_domain_asp_CREATE_RECORD_MAX_ENTRIES')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_dns_modify_asp_CREATE_RECORD_MAX_ENTRIES(self, method, url, body,
+                                                      headers):
+        return (httplib.OK, '211\r\n212\r\n213', {},
+                httplib.responses[httplib.OK])
+
+    def _api_dns_list_asp_CREATE_RECORD_MAX_ENTRIES(self, method, url, body,
+                                                    headers):
+        body = self.fixtures.load('api_dns_list')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_dns_list_domain_asp_CREATE_RECORD_MAX_ENTRIES_WITH_ENTRY(self,
+                                                                      method,
+                                                                      url,
+                                                                      body,
+                                                                      headers):
+        body = self.fixtures.load(
+            '_api_dns_modify_asp_CREATE_RECORD_MAX_ENTRIES_WITH_ENTRY')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_dns_modify_asp_CREATE_RECORD_MAX_ENTRIES_WITH_ENTRY(self, method,
+                                                                 url, body,
+                                                                 headers):
+        return (httplib.OK, '211\r\n212\r\n213', {},
+                httplib.responses[httplib.OK])
+
+    def _api_dns_list_asp_CREATE_RECORD_MAX_ENTRIES_WITH_ENTRY(self, method,
+                                                               url, body,
+                                                               headers):
+        body = self.fixtures.load('api_dns_list')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
     def _api_dns_list_asp_UPDATE_RECORD(self, method, url, body, headers):
         body = self.fixtures.load('api_dns_list')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])


Mime
View raw message