mirror of
https://github.com/github/octodns.git
synced 2024-05-11 05:55:00 +00:00
NS1 rate_limit_delay param, unit tests for rate limit handling
This commit is contained in:
@@ -26,14 +26,15 @@ class Ns1Provider(BaseProvider):
|
||||
SUPPORTS = set(('A', 'AAAA', 'ALIAS', 'CNAME', 'MX', 'NAPTR', 'NS', 'PTR',
|
||||
'SPF', 'SRV', 'TXT'))
|
||||
|
||||
RATE_LIMIT_DELAY = 1
|
||||
ZONE_NOT_FOUND_MESSAGE = 'server error: zone not found'
|
||||
|
||||
def __init__(self, id, api_key, *args, **kwargs):
|
||||
def __init__(self, id, api_key, rate_limit_delay=1, *args, **kwargs):
|
||||
self.log = getLogger('Ns1Provider[{}]'.format(id))
|
||||
self.log.debug('__init__: id=%s, api_key=***', id)
|
||||
self.log.debug('__init__: id=%s, api_key=***, rate_limit_delay=%d', id,
|
||||
rate_limit_delay)
|
||||
super(Ns1Provider, self).__init__(id, *args, **kwargs)
|
||||
self._client = NSONE(apiKey=api_key)
|
||||
self.rate_limit_delay = rate_limit_delay
|
||||
|
||||
def _data_for_A(self, _type, record):
|
||||
return {
|
||||
@@ -179,7 +180,7 @@ class Ns1Provider(BaseProvider):
|
||||
except RateLimitException:
|
||||
self.log.warn('_apply_Create: rate limit encountered, pausing '
|
||||
'and trying again')
|
||||
sleep(self.RATE_LIMIT_DELAY)
|
||||
sleep(self.rate_limit_delay)
|
||||
meth(name, **params)
|
||||
|
||||
def _apply_Update(self, nsone_zone, change):
|
||||
@@ -194,7 +195,7 @@ class Ns1Provider(BaseProvider):
|
||||
except RateLimitException:
|
||||
self.log.warn('_apply_Update: rate limit encountered, pausing '
|
||||
'and trying again')
|
||||
sleep(self.RATE_LIMIT_DELAY)
|
||||
sleep(self.rate_limit_delay)
|
||||
record.update(**params)
|
||||
|
||||
def _apply_Delete(self, nsone_zone, change):
|
||||
@@ -207,7 +208,7 @@ class Ns1Provider(BaseProvider):
|
||||
except RateLimitException:
|
||||
self.log.warn('_apply_Delete: rate limit encountered, pausing '
|
||||
'and trying again')
|
||||
sleep(self.RATE_LIMIT_DELAY)
|
||||
sleep(self.rate_limit_delay)
|
||||
record.delete()
|
||||
|
||||
def _apply(self, plan):
|
||||
|
||||
@@ -6,7 +6,8 @@ from __future__ import absolute_import, division, print_function, \
|
||||
unicode_literals
|
||||
|
||||
from mock import Mock, call, patch
|
||||
from nsone.rest.errors import AuthException, ResourceException
|
||||
from nsone.rest.errors import AuthException, RateLimitException, \
|
||||
ResourceException
|
||||
from unittest import TestCase
|
||||
|
||||
from octodns.record import Delete, Record, Update
|
||||
@@ -192,7 +193,7 @@ class TestNs1Provider(TestCase):
|
||||
@patch('nsone.NSONE.createZone')
|
||||
@patch('nsone.NSONE.loadZone')
|
||||
def test_sync(self, load_mock, create_mock):
|
||||
provider = Ns1Provider('test', 'api-key')
|
||||
provider = Ns1Provider('test', 'api-key', rate_limit_delay=0)
|
||||
|
||||
desired = Zone('unit.tests.', [])
|
||||
desired.records.update(self.expected)
|
||||
@@ -225,7 +226,15 @@ class TestNs1Provider(TestCase):
|
||||
create_mock.reset_mock()
|
||||
load_mock.side_effect = \
|
||||
ResourceException('server error: zone not found')
|
||||
create_mock.side_effect = None
|
||||
# ugh, need a mock zone with a mock prop since we're using getattr, we
|
||||
# can actually control side effects on `meth` with that.
|
||||
mock_zone = Mock()
|
||||
mock_zone.add_SRV = Mock()
|
||||
mock_zone.add_SRV.side_effect = [
|
||||
RateLimitException('boo'),
|
||||
None,
|
||||
]
|
||||
create_mock.side_effect = [mock_zone]
|
||||
got_n = provider.apply(plan)
|
||||
self.assertEquals(expected_n, got_n)
|
||||
|
||||
@@ -245,12 +254,26 @@ class TestNs1Provider(TestCase):
|
||||
self.assertEquals(2, len(plan.changes))
|
||||
self.assertIsInstance(plan.changes[0], Update)
|
||||
self.assertIsInstance(plan.changes[1], Delete)
|
||||
|
||||
# ugh, we need a mock record that can be returned from loadRecord for
|
||||
# the update and delete targets, we can add our side effects to that to
|
||||
# trigger rate limit handling
|
||||
mock_record = Mock()
|
||||
mock_record.update.side_effect = [
|
||||
RateLimitException('one'),
|
||||
None,
|
||||
]
|
||||
mock_record.delete.side_effect = [
|
||||
RateLimitException('two'),
|
||||
None,
|
||||
]
|
||||
nsone_zone.loadRecord.side_effect = [mock_record, mock_record]
|
||||
got_n = provider.apply(plan)
|
||||
self.assertEquals(2, got_n)
|
||||
nsone_zone.loadRecord.assert_has_calls([
|
||||
call('unit.tests', u'A'),
|
||||
call().update(answers=[u'1.2.3.4'], ttl=32),
|
||||
call('delete-me', u'A'),
|
||||
call().delete()
|
||||
])
|
||||
mock_record.assert_has_calls([
|
||||
call.update(answers=[u'1.2.3.4'], ttl=32),
|
||||
call.delete()
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user