mirror of
https://github.com/github/octodns.git
synced 2024-05-11 05:55:00 +00:00
182 lines
6.1 KiB
Python
182 lines
6.1 KiB
Python
#
|
|
#
|
|
#
|
|
|
|
from unittest import TestCase
|
|
|
|
from helpers import SimpleProvider
|
|
|
|
from octodns.record import Record
|
|
from octodns.record.a import ARecord
|
|
from octodns.record.exception import ValidationError
|
|
from octodns.zone import Zone
|
|
|
|
|
|
class TestRecordA(TestCase):
|
|
zone = Zone('unit.tests.', [])
|
|
|
|
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.assertEqual('a', a.name)
|
|
self.assertEqual('a.unit.tests.', a.fqdn)
|
|
self.assertEqual(30, a.ttl)
|
|
self.assertEqual(a_values, a.values)
|
|
self.assertEqual(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.assertEqual([b_value], b.values)
|
|
self.assertEqual(b_data, b.data)
|
|
|
|
# top-level
|
|
data = {'ttl': 30, 'value': '4.2.3.4'}
|
|
self.assertEqual(self.zone.name, ARecord(self.zone, '', data).fqdn)
|
|
self.assertEqual(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.assertEqual(a, update.existing)
|
|
self.assertEqual(other, update.new)
|
|
# changes if values modified
|
|
other.ttl = a.ttl
|
|
other.values = ['4.4.4.4']
|
|
update = a.changes(other, target)
|
|
self.assertEqual(a, update.existing)
|
|
self.assertEqual(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__()
|
|
|
|
def test_validation_and_values_mixin(self):
|
|
# doesn't blow up
|
|
Record.new(self.zone, '', {'type': 'A', 'ttl': 600, 'value': '1.2.3.4'})
|
|
Record.new(
|
|
self.zone, '', {'type': 'A', 'ttl': 600, 'values': ['1.2.3.4']}
|
|
)
|
|
Record.new(
|
|
self.zone,
|
|
'',
|
|
{'type': 'A', 'ttl': 600, 'values': ['1.2.3.4', '1.2.3.5']},
|
|
)
|
|
|
|
# missing value(s), no value or value
|
|
with self.assertRaises(ValidationError) as ctx:
|
|
Record.new(self.zone, '', {'type': 'A', 'ttl': 600})
|
|
self.assertEqual(['missing value(s)'], ctx.exception.reasons)
|
|
|
|
# missing value(s), empty values
|
|
with self.assertRaises(ValidationError) as ctx:
|
|
Record.new(
|
|
self.zone, 'www', {'type': 'A', 'ttl': 600, 'values': []}
|
|
)
|
|
self.assertEqual(['missing value(s)'], ctx.exception.reasons)
|
|
|
|
# missing value(s), None values
|
|
with self.assertRaises(ValidationError) as ctx:
|
|
Record.new(
|
|
self.zone, 'www', {'type': 'A', 'ttl': 600, 'values': None}
|
|
)
|
|
self.assertEqual(['missing value(s)'], ctx.exception.reasons)
|
|
|
|
# missing value(s) and empty value
|
|
with self.assertRaises(ValidationError) as ctx:
|
|
Record.new(
|
|
self.zone,
|
|
'www',
|
|
{'type': 'A', 'ttl': 600, 'values': [None, '']},
|
|
)
|
|
self.assertEqual(
|
|
['missing value(s)', 'empty value'], ctx.exception.reasons
|
|
)
|
|
|
|
# missing value(s), None value
|
|
with self.assertRaises(ValidationError) as ctx:
|
|
Record.new(
|
|
self.zone, 'www', {'type': 'A', 'ttl': 600, 'value': None}
|
|
)
|
|
self.assertEqual(['missing value(s)'], ctx.exception.reasons)
|
|
|
|
# empty value, empty string value
|
|
with self.assertRaises(ValidationError) as ctx:
|
|
Record.new(self.zone, 'www', {'type': 'A', 'ttl': 600, 'value': ''})
|
|
self.assertEqual(['empty value'], ctx.exception.reasons)
|
|
|
|
# missing value(s) & ttl
|
|
with self.assertRaises(ValidationError) as ctx:
|
|
Record.new(self.zone, '', {'type': 'A'})
|
|
self.assertEqual(
|
|
['missing ttl', 'missing value(s)'], ctx.exception.reasons
|
|
)
|
|
|
|
# invalid ipv4 address
|
|
with self.assertRaises(ValidationError) as ctx:
|
|
Record.new(
|
|
self.zone, '', {'type': 'A', 'ttl': 600, 'value': 'hello'}
|
|
)
|
|
self.assertEqual(
|
|
['invalid IPv4 address "hello"'], ctx.exception.reasons
|
|
)
|
|
|
|
# invalid ipv4 addresses
|
|
with self.assertRaises(ValidationError) as ctx:
|
|
Record.new(
|
|
self.zone,
|
|
'',
|
|
{'type': 'A', 'ttl': 600, 'values': ['hello', 'goodbye']},
|
|
)
|
|
self.assertEqual(
|
|
['invalid IPv4 address "hello"', 'invalid IPv4 address "goodbye"'],
|
|
ctx.exception.reasons,
|
|
)
|
|
|
|
# invalid & valid ipv4 addresses, no ttl
|
|
with self.assertRaises(ValidationError) as ctx:
|
|
Record.new(
|
|
self.zone,
|
|
'',
|
|
{'type': 'A', 'values': ['1.2.3.4', 'hello', '5.6.7.8']},
|
|
)
|
|
self.assertEqual(
|
|
['missing ttl', 'invalid IPv4 address "hello"'],
|
|
ctx.exception.reasons,
|
|
)
|