|
|
|
@ -99,6 +99,81 @@ class TestRecord(TestCase): |
|
|
|
self.assertTrue(f'{encoded}.{zone.name}', record.fqdn) |
|
|
|
self.assertTrue(f'{utf8}.{zone.decoded_name}', record.decoded_fqdn) |
|
|
|
|
|
|
|
def test_utf8_values(self): |
|
|
|
zone = Zone('unit.tests.', []) |
|
|
|
utf8 = 'гэрбүл.mn.' |
|
|
|
encoded = idna_encode(utf8) |
|
|
|
|
|
|
|
# ALIAS |
|
|
|
record = Record.new( |
|
|
|
zone, '', {'type': 'ALIAS', 'ttl': 300, 'value': utf8} |
|
|
|
) |
|
|
|
self.assertEqual(encoded, record.value) |
|
|
|
|
|
|
|
# CNAME |
|
|
|
record = Record.new( |
|
|
|
zone, 'cname', {'type': 'CNAME', 'ttl': 300, 'value': utf8} |
|
|
|
) |
|
|
|
self.assertEqual(encoded, record.value) |
|
|
|
|
|
|
|
# DNAME |
|
|
|
record = Record.new( |
|
|
|
zone, 'dname', {'type': 'DNAME', 'ttl': 300, 'value': utf8} |
|
|
|
) |
|
|
|
self.assertEqual(encoded, record.value) |
|
|
|
|
|
|
|
# MX |
|
|
|
record = Record.new( |
|
|
|
zone, |
|
|
|
'mx', |
|
|
|
{ |
|
|
|
'type': 'MX', |
|
|
|
'ttl': 300, |
|
|
|
'value': {'preference': 10, 'exchange': utf8}, |
|
|
|
}, |
|
|
|
) |
|
|
|
self.assertEqual( |
|
|
|
MxValue({'preference': 10, 'exchange': encoded}), record.values[0] |
|
|
|
) |
|
|
|
|
|
|
|
# NS |
|
|
|
record = Record.new( |
|
|
|
zone, 'ns', {'type': 'NS', 'ttl': 300, 'value': utf8} |
|
|
|
) |
|
|
|
self.assertEqual(encoded, record.values[0]) |
|
|
|
|
|
|
|
# PTR |
|
|
|
another_utf8 = 'niño.mx.' |
|
|
|
another_encoded = idna_encode(another_utf8) |
|
|
|
record = Record.new( |
|
|
|
zone, |
|
|
|
'ptr', |
|
|
|
{'type': 'PTR', 'ttl': 300, 'values': [utf8, another_utf8]}, |
|
|
|
) |
|
|
|
self.assertEqual([encoded, another_encoded], record.values) |
|
|
|
|
|
|
|
# SRV |
|
|
|
record = Record.new( |
|
|
|
zone, |
|
|
|
'_srv._tcp', |
|
|
|
{ |
|
|
|
'type': 'SRV', |
|
|
|
'ttl': 300, |
|
|
|
'value': { |
|
|
|
'priority': 0, |
|
|
|
'weight': 10, |
|
|
|
'port': 80, |
|
|
|
'target': utf8, |
|
|
|
}, |
|
|
|
}, |
|
|
|
) |
|
|
|
self.assertEqual( |
|
|
|
SrvValue( |
|
|
|
{'priority': 0, 'weight': 10, 'port': 80, 'target': encoded} |
|
|
|
), |
|
|
|
record.values[0], |
|
|
|
) |
|
|
|
|
|
|
|
def test_alias_lowering_value(self): |
|
|
|
upper_record = AliasRecord( |
|
|
|
self.zone, |
|
|
|
@ -238,9 +313,6 @@ class TestRecord(TestCase): |
|
|
|
): |
|
|
|
self.assertEqual(s, Ipv4Address.parse_rdata_text(s)) |
|
|
|
|
|
|
|
# since we're a noop there's no need/way to check whether validate or |
|
|
|
# __init__ call parse_rdata_text |
|
|
|
|
|
|
|
zone = Zone('unit.tests.', []) |
|
|
|
a = ARecord(zone, 'a', {'ttl': 42, 'value': '1.2.3.4'}) |
|
|
|
self.assertEqual('1.2.3.4', a.values[0].rdata_text) |
|
|
|
@ -429,9 +501,6 @@ class TestRecord(TestCase): |
|
|
|
): |
|
|
|
self.assertEqual(s, _TargetValue.parse_rdata_text(s)) |
|
|
|
|
|
|
|
# since we're a noop there's no need/way to check whether validate or |
|
|
|
# __init__ call parse_rdata_text |
|
|
|
|
|
|
|
zone = Zone('unit.tests.', []) |
|
|
|
a = AliasRecord(zone, 'a', {'ttl': 42, 'value': 'some.target.'}) |
|
|
|
self.assertEqual('some.target.', a.value.rdata_text) |
|
|
|
@ -525,32 +594,17 @@ class TestRecord(TestCase): |
|
|
|
CaaValue.parse_rdata_text('0 tag 99148c81'), |
|
|
|
) |
|
|
|
|
|
|
|
# make sure that validate is using parse_rdata_text when passed string |
|
|
|
# value(s) |
|
|
|
reasons = CaaRecord.validate( |
|
|
|
'caa', 'caa.unit.tests.', {'ttl': 32, 'value': ''} |
|
|
|
) |
|
|
|
self.assertEqual(['failed to parse string value as RR text'], reasons) |
|
|
|
reasons = CaaRecord.validate( |
|
|
|
'caa', 'caa.unit.tests.', {'ttl': 32, 'values': ['nope']} |
|
|
|
) |
|
|
|
self.assertEqual(['failed to parse string value as RR text'], reasons) |
|
|
|
reasons = CaaRecord.validate( |
|
|
|
'caa', 'caa.unit.tests.', {'ttl': 32, 'value': '0 tag 99148c81'} |
|
|
|
) |
|
|
|
self.assertFalse(reasons) |
|
|
|
|
|
|
|
# make sure that the cstor is using parse_rdata_text |
|
|
|
zone = Zone('unit.tests.', []) |
|
|
|
a = CaaRecord(zone, 'caa', {'ttl': 32, 'value': '0 tag 99148c81'}) |
|
|
|
self.assertEqual(0, a.values[0].flags) |
|
|
|
self.assertEqual('tag', a.values[0].tag) |
|
|
|
self.assertEqual('99148c81', a.values[0].value) |
|
|
|
self.assertEqual('0 tag 99148c81', a.values[0].rdata_text) |
|
|
|
a = CaaRecord( |
|
|
|
zone, |
|
|
|
'caa', |
|
|
|
{'ttl': 32, 'values': ['1 tag1 99148c81', '2 tag2 99148c44']}, |
|
|
|
{ |
|
|
|
'ttl': 32, |
|
|
|
'values': [ |
|
|
|
{'flags': 1, 'tag': 'tag1', 'value': '99148c81'}, |
|
|
|
{'flags': 2, 'tag': 'tag2', 'value': '99148c44'}, |
|
|
|
], |
|
|
|
}, |
|
|
|
) |
|
|
|
self.assertEqual(1, a.values[0].flags) |
|
|
|
self.assertEqual('tag1', a.values[0].tag) |
|
|
|
@ -711,19 +765,30 @@ class TestRecord(TestCase): |
|
|
|
LocValue.parse_rdata_text(s), |
|
|
|
) |
|
|
|
|
|
|
|
# make sure validate is using parse_rdata_text when passed string values |
|
|
|
reasons = LocRecord.validate( |
|
|
|
'loc', 'loc.unit.tests', {'ttl': 42, 'value': ''} |
|
|
|
) |
|
|
|
self.assertEqual(['failed to parse string value as RR text'], reasons) |
|
|
|
reasons = LocRecord.validate( |
|
|
|
'loc', 'loc.unit.tests', {'ttl': 42, 'value': s} |
|
|
|
) |
|
|
|
self.assertFalse(reasons) |
|
|
|
|
|
|
|
# make sure that the cstor is using parse_rdata_text |
|
|
|
zone = Zone('unit.tests.', []) |
|
|
|
a = LocRecord(zone, 'mx', {'ttl': 32, 'value': s}) |
|
|
|
a = LocRecord( |
|
|
|
zone, |
|
|
|
'mx', |
|
|
|
{ |
|
|
|
'type': 'LOC', |
|
|
|
'ttl': 42, |
|
|
|
'value': { |
|
|
|
'altitude': 6.6, |
|
|
|
'lat_degrees': 0, |
|
|
|
'lat_direction': 'N', |
|
|
|
'lat_minutes': 1, |
|
|
|
'lat_seconds': 2.2, |
|
|
|
'long_degrees': 3, |
|
|
|
'long_direction': 'E', |
|
|
|
'long_minutes': 4, |
|
|
|
'long_seconds': 5.5, |
|
|
|
'precision_horz': 8.8, |
|
|
|
'precision_vert': 9.9, |
|
|
|
'size': 7.7, |
|
|
|
}, |
|
|
|
}, |
|
|
|
) |
|
|
|
self.assertEqual(0, a.values[0].lat_degrees) |
|
|
|
self.assertEqual(1, a.values[0].lat_minutes) |
|
|
|
self.assertEqual(2.2, a.values[0].lat_seconds) |
|
|
|
@ -815,33 +880,16 @@ class TestRecord(TestCase): |
|
|
|
MxValue.parse_rdata_text('10 mx.unit.tests.'), |
|
|
|
) |
|
|
|
|
|
|
|
# make sure that validate is using parse_rdata_text when passed string |
|
|
|
# value(s) |
|
|
|
reasons = MxRecord.validate( |
|
|
|
'mx', 'mx.unit.tests.', {'ttl': 32, 'value': ''} |
|
|
|
) |
|
|
|
self.assertEqual(['failed to parse string value as RR text'], reasons) |
|
|
|
reasons = MxRecord.validate( |
|
|
|
'mx', 'mx.unit.tests.', {'ttl': 32, 'values': ['nope']} |
|
|
|
) |
|
|
|
self.assertEqual(['failed to parse string value as RR text'], reasons) |
|
|
|
reasons = MxRecord.validate( |
|
|
|
'mx', 'mx.unit.tests.', {'ttl': 32, 'value': '10 mail.unit.tests.'} |
|
|
|
) |
|
|
|
self.assertFalse(reasons) |
|
|
|
|
|
|
|
# make sure that the cstor is using parse_rdata_text |
|
|
|
zone = Zone('unit.tests.', []) |
|
|
|
a = MxRecord(zone, 'mx', {'ttl': 32, 'value': '10 mail.unit.tests.'}) |
|
|
|
self.assertEqual(10, a.values[0].preference) |
|
|
|
self.assertEqual('mail.unit.tests.', a.values[0].exchange) |
|
|
|
self.assertEqual('10 mail.unit.tests.', a.values[0].rdata_text) |
|
|
|
a = MxRecord( |
|
|
|
zone, |
|
|
|
'mx', |
|
|
|
{ |
|
|
|
'ttl': 32, |
|
|
|
'values': ['11 mail1.unit.tests.', '12 mail2.unit.tests.'], |
|
|
|
'values': [ |
|
|
|
{'preference': 11, 'exchange': 'mail1.unit.tests.'}, |
|
|
|
{'preference': 12, 'exchange': 'mail2.unit.tests.'}, |
|
|
|
], |
|
|
|
}, |
|
|
|
) |
|
|
|
self.assertEqual(11, a.values[0].preference) |
|
|
|
@ -1181,33 +1229,30 @@ class TestRecord(TestCase): |
|
|
|
NaptrValue.parse_rdata_text('1 2 three four five six'), |
|
|
|
) |
|
|
|
|
|
|
|
# make sure that validate is using parse_rdata_text when passed string |
|
|
|
# value(s) |
|
|
|
reasons = NaptrRecord.validate( |
|
|
|
'naptr', 'naptr.unit.tests.', {'ttl': 32, 'value': ''} |
|
|
|
) |
|
|
|
self.assertEqual(['failed to parse string value as RR text'], reasons) |
|
|
|
reasons = NaptrRecord.validate( |
|
|
|
'naptr', 'naptr.unit.tests.', {'ttl': 32, 'value': ['']} |
|
|
|
) |
|
|
|
self.assertEqual(['failed to parse string value as RR text'], reasons) |
|
|
|
reasons = NaptrRecord.validate( |
|
|
|
'naptr', |
|
|
|
'naptr.unit.tests.', |
|
|
|
{'ttl': 32, 'value': ['1 2 S service regexp replacement']}, |
|
|
|
) |
|
|
|
self.assertFalse(reasons) |
|
|
|
|
|
|
|
# make sure that the cstor is using parse_rdata_text |
|
|
|
zone = Zone('unit.tests.', []) |
|
|
|
s = '1 2 S service regexp replacement' |
|
|
|
a = NaptrRecord(zone, 'naptr', {'ttl': 32, 'value': s}) |
|
|
|
a = NaptrRecord( |
|
|
|
zone, |
|
|
|
'naptr', |
|
|
|
{ |
|
|
|
'ttl': 32, |
|
|
|
'value': { |
|
|
|
'order': 1, |
|
|
|
'preference': 2, |
|
|
|
'flags': 'S', |
|
|
|
'service': 'service', |
|
|
|
'regexp': 'regexp', |
|
|
|
'replacement': 'replacement', |
|
|
|
}, |
|
|
|
}, |
|
|
|
) |
|
|
|
self.assertEqual(1, a.values[0].order) |
|
|
|
self.assertEqual(2, a.values[0].preference) |
|
|
|
self.assertEqual('S', a.values[0].flags) |
|
|
|
self.assertEqual('service', a.values[0].service) |
|
|
|
self.assertEqual('regexp', a.values[0].regexp) |
|
|
|
self.assertEqual('replacement', a.values[0].replacement) |
|
|
|
s = '1 2 S service regexp replacement' |
|
|
|
self.assertEqual(s, a.values[0].rdata_text) |
|
|
|
|
|
|
|
def test_ns(self): |
|
|
|
@ -1241,9 +1286,6 @@ class TestRecord(TestCase): |
|
|
|
): |
|
|
|
self.assertEqual(s, _NsValue.parse_rdata_text(s)) |
|
|
|
|
|
|
|
# since we're a noop there's no need/way to check whether validate or |
|
|
|
# __init__ call parse_rdata_text |
|
|
|
|
|
|
|
zone = Zone('unit.tests.', []) |
|
|
|
a = NsRecord(zone, 'a', {'ttl': 42, 'value': 'some.target.'}) |
|
|
|
self.assertEqual('some.target.', a.values[0].rdata_text) |
|
|
|
@ -1346,24 +1388,19 @@ class TestRecord(TestCase): |
|
|
|
SshfpValue.parse_rdata_text('1 2 00479b27'), |
|
|
|
) |
|
|
|
|
|
|
|
# make sure that validate is using parse_rdata_text when passed string |
|
|
|
# value(s) |
|
|
|
reasons = SshfpRecord.validate( |
|
|
|
'sshfp', 'sshfp.unit.tests.', {'ttl': 32, 'value': ''} |
|
|
|
) |
|
|
|
self.assertEqual(['failed to parse string value as RR text'], reasons) |
|
|
|
reasons = SshfpRecord.validate( |
|
|
|
'sshfp', 'sshfp.unit.tests.', {'ttl': 32, 'values': ['nope']} |
|
|
|
) |
|
|
|
self.assertEqual(['failed to parse string value as RR text'], reasons) |
|
|
|
reasons = SshfpRecord.validate( |
|
|
|
'sshfp', 'sshfp.unit.tests.', {'ttl': 32, 'value': '1 2 00479b27'} |
|
|
|
) |
|
|
|
self.assertFalse(reasons) |
|
|
|
|
|
|
|
# make sure that the cstor is using parse_rdata_text |
|
|
|
zone = Zone('unit.tests.', []) |
|
|
|
a = SshfpRecord(zone, 'sshfp', {'ttl': 32, 'value': '1 2 00479b27'}) |
|
|
|
a = SshfpRecord( |
|
|
|
zone, |
|
|
|
'sshfp', |
|
|
|
{ |
|
|
|
'ttl': 32, |
|
|
|
'value': { |
|
|
|
'algorithm': 1, |
|
|
|
'fingerprint_type': 2, |
|
|
|
'fingerprint': '00479b27', |
|
|
|
}, |
|
|
|
}, |
|
|
|
) |
|
|
|
self.assertEqual(1, a.values[0].algorithm) |
|
|
|
self.assertEqual(2, a.values[0].fingerprint_type) |
|
|
|
self.assertEqual('00479b27', a.values[0].fingerprint) |
|
|
|
@ -1374,7 +1411,7 @@ class TestRecord(TestCase): |
|
|
|
b_value = 'spf1 -other' |
|
|
|
self.assertMultipleValues(SpfRecord, a_values, b_value) |
|
|
|
|
|
|
|
def test_chunked_value_rr_text(self): |
|
|
|
def test_chunked_value_rdata_text(self): |
|
|
|
for s in ( |
|
|
|
None, |
|
|
|
'', |
|
|
|
@ -1464,7 +1501,7 @@ class TestRecord(TestCase): |
|
|
|
# __repr__ doesn't blow up |
|
|
|
a.__repr__() |
|
|
|
|
|
|
|
def test_srv_value_rr_text(self): |
|
|
|
def test_srv_value_rdata_text(self): |
|
|
|
|
|
|
|
# empty string won't parse |
|
|
|
with self.assertRaises(RrParseError): |
|
|
|
@ -1508,23 +1545,19 @@ class TestRecord(TestCase): |
|
|
|
SrvValue.parse_rdata_text('1 2 3 srv.unit.tests.'), |
|
|
|
) |
|
|
|
|
|
|
|
# make sure that validate is using parse_rdata_text when passed string |
|
|
|
# value(s) |
|
|
|
reasons = SrvRecord.validate( |
|
|
|
'_srv._tcp', '_srv._tcp.unit.tests.', {'ttl': 32, 'value': ''} |
|
|
|
) |
|
|
|
self.assertEqual(['failed to parse string value as RR text'], reasons) |
|
|
|
reasons = SrvRecord.validate( |
|
|
|
'_srv._tcp', |
|
|
|
'_srv._tcp.unit.tests.', |
|
|
|
{'ttl': 32, 'value': '1 2 3 srv.unit.tests.'}, |
|
|
|
) |
|
|
|
self.assertFalse(reasons) |
|
|
|
|
|
|
|
# make sure that the cstor is using parse_rdata_text |
|
|
|
zone = Zone('unit.tests.', []) |
|
|
|
a = SrvRecord( |
|
|
|
zone, '_srv._tcp', {'ttl': 32, 'value': '1 2 3 srv.unit.tests.'} |
|
|
|
zone, |
|
|
|
'_srv._tcp', |
|
|
|
{ |
|
|
|
'ttl': 32, |
|
|
|
'value': { |
|
|
|
'priority': 1, |
|
|
|
'weight': 2, |
|
|
|
'port': 3, |
|
|
|
'target': 'srv.unit.tests.', |
|
|
|
}, |
|
|
|
}, |
|
|
|
) |
|
|
|
self.assertEqual(1, a.values[0].priority) |
|
|
|
self.assertEqual(2, a.values[0].weight) |
|
|
|
@ -1632,7 +1665,7 @@ class TestRecord(TestCase): |
|
|
|
# __repr__ doesn't blow up |
|
|
|
a.__repr__() |
|
|
|
|
|
|
|
def test_tsla_value_rr_text(self): |
|
|
|
def test_tsla_value_rdata_text(self): |
|
|
|
|
|
|
|
# empty string won't parse |
|
|
|
with self.assertRaises(RrParseError): |
|
|
|
@ -1676,20 +1709,20 @@ class TestRecord(TestCase): |
|
|
|
TlsaValue.parse_rdata_text('1 2 3 abcd'), |
|
|
|
) |
|
|
|
|
|
|
|
# make sure that validate is using parse_rdata_text when passed string |
|
|
|
# value(s) |
|
|
|
reasons = TlsaRecord.validate( |
|
|
|
'tlsa', 'tlsa.unit.tests.', {'ttl': 32, 'value': ''} |
|
|
|
) |
|
|
|
self.assertEqual(['failed to parse string value as RR text'], reasons) |
|
|
|
reasons = TlsaRecord.validate( |
|
|
|
'tlsa', 'tlsa.unit.tests.', {'ttl': 32, 'value': '2 1 0 abcd'} |
|
|
|
) |
|
|
|
self.assertFalse(reasons) |
|
|
|
|
|
|
|
# make sure that the cstor is using parse_rdata_text |
|
|
|
zone = Zone('unit.tests.', []) |
|
|
|
a = TlsaRecord(zone, 'tlsa', {'ttl': 32, 'value': '2 1 0 abcd'}) |
|
|
|
a = TlsaRecord( |
|
|
|
zone, |
|
|
|
'tlsa', |
|
|
|
{ |
|
|
|
'ttl': 32, |
|
|
|
'value': { |
|
|
|
'certificate_usage': 2, |
|
|
|
'selector': 1, |
|
|
|
'matching_type': 0, |
|
|
|
'certificate_association_data': 'abcd', |
|
|
|
}, |
|
|
|
}, |
|
|
|
) |
|
|
|
self.assertEqual(2, a.values[0].certificate_usage) |
|
|
|
self.assertEqual(1, a.values[0].selector) |
|
|
|
self.assertEqual(0, a.values[0].matching_type) |
|
|
|
@ -3165,7 +3198,7 @@ class TestRecordValidation(TestCase): |
|
|
|
) |
|
|
|
self.assertEqual(['missing value'], ctx.exception.reasons) |
|
|
|
|
|
|
|
def test_CNAME(self): |
|
|
|
def test_cname_validation(self): |
|
|
|
# doesn't blow up |
|
|
|
Record.new( |
|
|
|
self.zone, |
|
|
|
@ -3714,6 +3747,19 @@ class TestRecordValidation(TestCase): |
|
|
|
ctx.exception.reasons, |
|
|
|
) |
|
|
|
|
|
|
|
# if exchange doesn't exist value can not be None/falsey |
|
|
|
with self.assertRaises(ValidationError) as ctx: |
|
|
|
Record.new( |
|
|
|
self.zone, |
|
|
|
'', |
|
|
|
{ |
|
|
|
'type': 'MX', |
|
|
|
'ttl': 600, |
|
|
|
'value': {'preference': 10, 'value': ''}, |
|
|
|
}, |
|
|
|
) |
|
|
|
self.assertEqual(['missing exchange'], ctx.exception.reasons) |
|
|
|
|
|
|
|
# exchange can be a single `.` |
|
|
|
record = Record.new( |
|
|
|
self.zone, |
|
|
|
@ -4209,6 +4255,24 @@ class TestRecordValidation(TestCase): |
|
|
|
ctx.exception.reasons, |
|
|
|
) |
|
|
|
|
|
|
|
# falsey target |
|
|
|
with self.assertRaises(ValidationError) as ctx: |
|
|
|
Record.new( |
|
|
|
self.zone, |
|
|
|
'_srv._tcp', |
|
|
|
{ |
|
|
|
'type': 'SRV', |
|
|
|
'ttl': 600, |
|
|
|
'value': { |
|
|
|
'priority': 1, |
|
|
|
'weight': 2, |
|
|
|
'port': 3, |
|
|
|
'target': '', |
|
|
|
}, |
|
|
|
}, |
|
|
|
) |
|
|
|
self.assertEqual(['missing target'], ctx.exception.reasons) |
|
|
|
|
|
|
|
# target must be a valid FQDN |
|
|
|
with self.assertRaises(ValidationError) as ctx: |
|
|
|
Record.new( |
|
|
|
@ -5894,7 +5958,6 @@ class TestDynamicRecords(TestCase): |
|
|
|
'pools': { |
|
|
|
'one': {'values': [{'value': '3.3.3.3'}]}, |
|
|
|
'two': { |
|
|
|
# Testing out of order value sorting here |
|
|
|
'values': [{'value': '5.5.5.5'}, {'value': '4.4.4.4'}] |
|
|
|
}, |
|
|
|
'three': { |
|
|
|
@ -5922,9 +5985,12 @@ class TestDynamicRecords(TestCase): |
|
|
|
) |
|
|
|
|
|
|
|
def test_dynamic_eqs(self): |
|
|
|
|
|
|
|
pool_one = _DynamicPool('one', {'values': [{'value': '1.2.3.4'}]}) |
|
|
|
pool_two = _DynamicPool('two', {'values': [{'value': '1.2.3.5'}]}) |
|
|
|
pool_one = _DynamicPool( |
|
|
|
'one', {'values': [{'value': '1.2.3.4'}]}, Ipv4Address |
|
|
|
) |
|
|
|
pool_two = _DynamicPool( |
|
|
|
'two', {'values': [{'value': '1.2.3.5'}]}, Ipv4Address |
|
|
|
) |
|
|
|
self.assertEqual(pool_one, pool_one) |
|
|
|
self.assertNotEqual(pool_one, pool_two) |
|
|
|
self.assertNotEqual(pool_one, 42) |
|
|
|
@ -5943,6 +6009,61 @@ class TestDynamicRecords(TestCase): |
|
|
|
self.assertNotEqual(dynamic, other) |
|
|
|
self.assertNotEqual(dynamic, 42) |
|
|
|
|
|
|
|
def test_dynamic_cname_idna(self): |
|
|
|
a_utf8 = 'natación.mx.' |
|
|
|
a_encoded = idna_encode(a_utf8) |
|
|
|
b_utf8 = 'гэрбүл.mn.' |
|
|
|
b_encoded = idna_encode(b_utf8) |
|
|
|
cname_data = { |
|
|
|
'dynamic': { |
|
|
|
'pools': { |
|
|
|
'one': { |
|
|
|
# Testing out of order value sorting here |
|
|
|
'values': [ |
|
|
|
{'value': 'b.unit.tests.'}, |
|
|
|
{'value': 'a.unit.tests.'}, |
|
|
|
] |
|
|
|
}, |
|
|
|
'two': { |
|
|
|
'values': [ |
|
|
|
# some utf8 values we expect to be idna encoded |
|
|
|
{'weight': 10, 'value': a_utf8}, |
|
|
|
{'weight': 12, 'value': b_utf8}, |
|
|
|
] |
|
|
|
}, |
|
|
|
}, |
|
|
|
'rules': [ |
|
|
|
{'geos': ['NA-US-CA'], 'pool': 'two'}, |
|
|
|
{'pool': 'one'}, |
|
|
|
], |
|
|
|
}, |
|
|
|
'type': 'CNAME', |
|
|
|
'ttl': 60, |
|
|
|
'value': a_utf8, |
|
|
|
} |
|
|
|
cname = Record.new(self.zone, 'cname', cname_data) |
|
|
|
self.assertEqual(a_encoded, cname.value) |
|
|
|
self.assertEqual( |
|
|
|
{ |
|
|
|
'fallback': None, |
|
|
|
'values': [ |
|
|
|
{'weight': 1, 'value': 'a.unit.tests.', 'status': 'obey'}, |
|
|
|
{'weight': 1, 'value': 'b.unit.tests.', 'status': 'obey'}, |
|
|
|
], |
|
|
|
}, |
|
|
|
cname.dynamic.pools['one'].data, |
|
|
|
) |
|
|
|
self.assertEqual( |
|
|
|
{ |
|
|
|
'fallback': None, |
|
|
|
'values': [ |
|
|
|
{'weight': 12, 'value': b_encoded, 'status': 'obey'}, |
|
|
|
{'weight': 10, 'value': a_encoded, 'status': 'obey'}, |
|
|
|
], |
|
|
|
}, |
|
|
|
cname.dynamic.pools['two'].data, |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
class TestChanges(TestCase): |
|
|
|
zone = Zone('unit.tests.', []) |
|
|
|
|