Пример #1
0
 def test_invalid_a(self):
     with self.assertRaises(Exception) as ctx:
         ARecord(self.zone, 'a', {
             'ttl': 30,
             'value': 'foo',
         })
     self.assertTrue('Invalid record' in ctx.exception.message)
     with self.assertRaises(Exception) as ctx:
         ARecord(self.zone, 'a', {
             'ttl': 30,
             'values': ['1.2.3.4', 'bar'],
         })
     self.assertTrue('Invalid record' in ctx.exception.message)
Пример #2
0
    def test_copy(self):
        zone = Zone('unit.tests.', [])

        a = ARecord(zone, 'a', {'ttl': 42, 'value': '1.1.1.1'})
        zone.add_record(a)
        b = ARecord(zone, 'b', {'ttl': 42, 'value': '1.1.1.2'})
        zone.add_record(b)

        # Sanity check
        self.assertEqualsNameAndValues(set((a, b)), zone.records)

        copy = zone.copy()
        # We have an origin set and it is the source/original zone
        self.assertEquals(zone, copy._origin)
        # Our records are zone's records to start (references)
        self.assertEqualsNameAndValues(zone.records, copy.records)

        # If we try and change something that's already there we realize and
        # then get an error about a duplicate
        b_prime = ARecord(zone, 'b', {'ttl': 42, 'value': '1.1.1.3'})
        with self.assertRaises(DuplicateRecordException):
            copy.add_record(b_prime)
        self.assertIsNone(copy._origin)
        # Unchanged, straight copies
        self.assertEqualsNameAndValues(zone.records, copy.records)

        # If we add with replace things will be realized and the record will
        # have changed
        copy = zone.copy()
        copy.add_record(b_prime, replace=True)
        self.assertIsNone(copy._origin)
        self.assertEqualsNameAndValues(set((a, b_prime)), copy.records)

        # If we add another record, things are reliazed and it has been added
        copy = zone.copy()
        c = ARecord(zone, 'c', {'ttl': 42, 'value': '1.1.1.3'})
        copy.add_record(c)
        self.assertEqualsNameAndValues(set((a, b, c)), copy.records)

        # If we remove a record, things are reliazed and it has been removed
        copy = zone.copy()
        copy.remove_record(a)
        self.assertEqualsNameAndValues(set((b, )), copy.records)

        # Re-realizing is a noop
        copy = zone.copy()
        # Happens the first time
        self.assertTrue(copy.hydrate())
        # Doesn't the second
        self.assertFalse(copy.hydrate())
Пример #3
0
    def test_unsupporting(self):

        class NoAaaaProvider(object):
            id = 'no-aaaa'
            SUPPORTS_GEO = 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.assertEquals(1, len(changes))
        self.assertIsInstance(changes[0], Create)

        # Only delete the supported A, not the AAAA
        changes = desired.changes(current, NoAaaaProvider())
        self.assertEquals(1, len(changes))
        self.assertIsInstance(changes[0], Delete)
Пример #4
0
 def test_lowering(self):
     record = ARecord(self.zone, 'MiXeDcAsE', {
         'ttl': 30,
         'type': 'A',
         'value': '1.2.3.4',
     })
     self.assertEquals('mixedcase', record.name)
Пример #5
0
    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]))
Пример #6
0
    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)
Пример #7
0
    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]))
Пример #8
0
    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__()
Пример #9
0
    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__()
Пример #10
0
    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__()