def test_unsupporting(self): class NoAaaaProvider(object): id = 'no-aaaa' SUPPORTS_GEO = False SUPPORTS_DYNAMIC = False def supports(self, record): return record._type != 'AAAA' current = Zone('unit.tests.', []) desired = Zone('unit.tests.', []) a = ARecord(desired, 'a', {'ttl': 42, 'value': '1.1.1.1'}) desired.add_record(a) aaaa = AaaaRecord(desired, 'b', {'ttl': 42, 'value': '1:1:1::1'}) desired.add_record(aaaa) # Only create the supported A, not the AAAA changes = current.changes(desired, NoAaaaProvider()) self.assertEqual(1, len(changes)) self.assertIsInstance(changes[0], Create) # Only delete the supported A, not the AAAA changes = desired.changes(current, NoAaaaProvider()) self.assertEqual(1, len(changes)) self.assertIsInstance(changes[0], Delete)
def test_changes(self): before = Zone('unit.tests.', []) a = ARecord(before, 'a', {'ttl': 42, 'value': '1.1.1.1'}) before.add_record(a) b = AaaaRecord(before, 'b', {'ttl': 42, 'value': '1:1:1::1'}) before.add_record(b) after = Zone('unit.tests.', []) after.add_record(a) after.add_record(b) target = SimpleProvider() # before == after -> no changes self.assertFalse(before.changes(after, target)) # add a record, delete a record -> [Delete, Create] c = ARecord(before, 'c', {'ttl': 42, 'value': '1.1.1.1'}) after.add_record(c) after._remove_record(b) self.assertEquals(after.records, set([a, c])) changes = before.changes(after, target) self.assertEquals(2, len(changes)) for change in changes: if isinstance(change, Create): create = change elif isinstance(change, Delete): delete = change self.assertEquals(b, delete.existing) self.assertFalse(delete.new) self.assertEquals(c, create.new) self.assertFalse(create.existing) delete.__repr__() create.__repr__() after = Zone('unit.tests.', []) changed = ARecord(before, 'a', {'ttl': 42, 'value': '2.2.2.2'}) after.add_record(changed) after.add_record(b) changes = before.changes(after, target) self.assertEquals(1, len(changes)) update = changes[0] self.assertIsInstance(update, Update) # Using changes here to get a full equality self.assertFalse(a.changes(update.existing, target)) self.assertFalse(changed.changes(update.new, target)) update.__repr__()
def test_add_record(self): zone = Zone('unit.tests.', []) a = ARecord(zone, 'a', {'ttl': 42, 'value': '1.1.1.1'}) b = ARecord(zone, 'b', {'ttl': 42, 'value': '1.1.1.1'}) zone.add_record(a) self.assertEquals(zone.records, set([a])) # Can't add record with same name & type with self.assertRaises(DuplicateRecordException) as ctx: zone.add_record(a) self.assertEquals('Duplicate record a.unit.tests., type A', ctx.exception.message) self.assertEquals(zone.records, set([a])) # Can add dup name, with different type zone.add_record(b) self.assertEquals(zone.records, set([a, b]))
def test_root_ns(self): zone = Zone('unit.tests.', []) a = ARecord(zone, 'a', {'ttl': 42, 'value': '1.1.1.1'}) zone.add_record(a) # No root NS yet self.assertFalse(zone.root_ns) non_root_ns = NsRecord( zone, 'sub', { 'ttl': 42, 'values': ('ns1.unit.tests.', 'ns2.unit.tests.') }, ) zone.add_record(non_root_ns) # No root NS yet b/c this was a sub self.assertFalse(zone.root_ns) root_ns = NsRecord( zone, '', { 'ttl': 42, 'values': ('ns3.unit.tests.', 'ns4.unit.tests.') }, ) zone.add_record(root_ns) # Now we have a root NS self.assertEqual(root_ns, zone.root_ns) # make a copy, it has a root_ns copy = zone.copy() self.assertEqual(root_ns, copy.root_ns) # remove the root NS from it and we don't copy.remove_record(root_ns) self.assertFalse(copy.root_ns) # original still does though self.assertEqual(root_ns, zone.root_ns) # remove the A, still has root NS zone.remove_record(a) self.assertEqual(root_ns, zone.root_ns) # remove the sub NS, still has root NS zone.remove_record(non_root_ns) self.assertEqual(root_ns, zone.root_ns) # finally remove the root NS, no more zone.remove_record(root_ns) self.assertFalse(zone.root_ns)
def test_geo(self): geo_data = {'ttl': 42, 'values': ['5.2.3.4', '6.2.3.4'], 'geo': {'AF': ['1.1.1.1'], 'AS-JP': ['2.2.2.2', '3.3.3.3'], 'NA-US': ['4.4.4.4', '5.5.5.5'], 'NA-US-CA': ['6.6.6.6', '7.7.7.7']}} geo = ARecord(self.zone, 'geo', geo_data) self.assertEquals(geo_data, geo.data) other_data = {'ttl': 42, 'values': ['5.2.3.4', '6.2.3.4'], 'geo': {'AF': ['1.1.1.1'], 'AS-JP': ['2.2.2.2', '3.3.3.3'], 'NA-US': ['4.4.4.4', '5.5.5.5'], 'NA-US-CA': ['6.6.6.6', '7.7.7.7']}} other = ARecord(self.zone, 'geo', other_data) self.assertEquals(other_data, other.data) simple_target = SimpleProvider() geo_target = GeoProvider() # Geo provider doesn't consider identical geo to be changes self.assertFalse(geo.changes(geo, geo_target)) # geo values don't impact equality other.geo['AF'].values = ['9.9.9.9'] self.assertTrue(geo == other) # Non-geo supporting provider doesn't consider geo diffs to be changes self.assertFalse(geo.changes(other, simple_target)) # Geo provider does consider geo diffs to be changes self.assertTrue(geo.changes(other, geo_target)) # Object without geo doesn't impact equality other.geo = {} self.assertTrue(geo == other) # Non-geo supporting provider doesn't consider lack of geo a diff self.assertFalse(geo.changes(other, simple_target)) # Geo provider does consider lack of geo diffs to be changes self.assertTrue(geo.changes(other, geo_target)) # __repr__ doesn't blow up geo.__repr__()
def test_add_record(self): zone = Zone('unit.tests.', []) a = ARecord(zone, 'a', {'ttl': 42, 'value': '1.1.1.1'}) b = ARecord(zone, 'b', {'ttl': 42, 'value': '1.1.1.1'}) c = ARecord(zone, 'a', {'ttl': 43, 'value': '2.2.2.2'}) zone.add_record(a) self.assertEquals(zone.records, set([a])) # Can't add record with same name & type with self.assertRaises(DuplicateRecordException) as ctx: zone.add_record(a) self.assertEquals('Duplicate record a.unit.tests., type A', text_type(ctx.exception)) self.assertEquals(zone.records, set([a])) # can add duplicate with replace=True zone.add_record(c, replace=True) self.assertEquals('2.2.2.2', list(zone.records)[0].values[0]) # Can add dup name, with different type zone.add_record(b) self.assertEquals(zone.records, set([a, b]))
def test_a_and_record(self): a_values = ['1.2.3.4', '2.2.3.4'] a_data = {'ttl': 30, 'values': a_values} a = ARecord(self.zone, 'a', a_data) self.assertEquals('a', a.name) self.assertEquals('a.unit.tests.', a.fqdn) self.assertEquals(30, a.ttl) self.assertEquals(a_values, a.values) self.assertEquals(a_data, a.data) b_value = '3.2.3.4' b_data = {'ttl': 30, 'value': b_value} b = ARecord(self.zone, 'b', b_data) self.assertEquals([b_value], b.values) self.assertEquals(b_data, b.data) # top-level data = {'ttl': 30, 'value': '4.2.3.4'} self.assertEquals(self.zone.name, ARecord(self.zone, '', data).fqdn) self.assertEquals(self.zone.name, ARecord(self.zone, None, data).fqdn) # ARecord equate with itself self.assertTrue(a == a) # Records with differing names and same type don't equate self.assertFalse(a == b) # Records with same name & type equate even if ttl is different self.assertTrue(a == ARecord(self.zone, 'a', { 'ttl': 31, 'values': a_values })) # Records with same name & type equate even if values are different self.assertTrue(a == ARecord(self.zone, 'a', { 'ttl': 30, 'value': b_value })) target = SimpleProvider() # no changes if self self.assertFalse(a.changes(a, target)) # no changes if clone other = ARecord(self.zone, 'a', {'ttl': 30, 'values': a_values}) self.assertFalse(a.changes(other, target)) # changes if ttl modified other.ttl = 31 update = a.changes(other, target) self.assertEquals(a, update.existing) self.assertEquals(other, update.new) # changes if values modified other.ttl = a.ttl other.values = ['4.4.4.4'] update = a.changes(other, target) self.assertEquals(a, update.existing) self.assertEquals(other, update.new) # Hashing records = set() records.add(a) self.assertTrue(a in records) self.assertFalse(b in records) records.add(b) self.assertTrue(b in records) # __repr__ doesn't blow up a.__repr__() # Record.__repr__ does with self.assertRaises(NotImplementedError): class DummyRecord(Record): def __init__(self): pass DummyRecord().__repr__()