mirror of
https://github.com/github/octodns.git
synced 2024-05-11 05:55:00 +00:00
Add tests for full coverage
This commit is contained in:
@@ -394,6 +394,47 @@ class TestBaseProvider(TestCase):
|
||||
record2.dynamic.pools['one'].data['values'][0]['status'], 'obey'
|
||||
)
|
||||
|
||||
# SUPPORTS_DYNAMIC_SUBNETS
|
||||
provider.SUPPORTS_POOL_VALUE_STATUS = False
|
||||
zone1 = Zone('unit.tests.', [])
|
||||
record1 = Record.new(
|
||||
zone1,
|
||||
'a',
|
||||
{
|
||||
'dynamic': {
|
||||
'pools': {
|
||||
'one': {'values': [{'value': '1.1.1.1'}]},
|
||||
'two': {'values': [{'value': '2.2.2.2'}]},
|
||||
'three': {'values': [{'value': '3.3.3.3'}]},
|
||||
},
|
||||
'rules': [
|
||||
{'subnets': ['10.1.0.0/16'], 'pool': 'two'},
|
||||
{
|
||||
'subnets': ['11.1.0.0/16'],
|
||||
'geos': ['NA'],
|
||||
'pool': 'three',
|
||||
},
|
||||
{'pool': 'one'},
|
||||
],
|
||||
},
|
||||
'type': 'A',
|
||||
'ttl': 3600,
|
||||
'values': ['2.2.2.2'],
|
||||
},
|
||||
)
|
||||
zone1.add_record(record1)
|
||||
|
||||
zone2 = provider._process_desired_zone(zone1.copy())
|
||||
record2 = list(zone2.records)[0]
|
||||
dynamic = record2.dynamic
|
||||
# subnet-only rule is dropped
|
||||
self.assertNotEqual('two', dynamic.rules[0].data['pool'])
|
||||
self.assertEqual(2, len(dynamic.rules))
|
||||
# subnets are dropped from subnet+geo rule
|
||||
self.assertFalse('subnets' in dynamic.rules[0].data)
|
||||
# unused pool is dropped
|
||||
self.assertFalse('two' in record2.dynamic.pools)
|
||||
|
||||
# SUPPORTS_ROOT_NS
|
||||
provider.SUPPORTS_ROOT_NS = False
|
||||
zone1 = Zone('unit.tests.', [])
|
||||
|
||||
@@ -871,6 +871,54 @@ class TestRecordDynamic(TestCase):
|
||||
ctx.exception.reasons,
|
||||
)
|
||||
|
||||
# rule with invalid subnets
|
||||
a_data = {
|
||||
'dynamic': {
|
||||
'pools': {
|
||||
'one': {'values': [{'value': '3.3.3.3'}]},
|
||||
'two': {
|
||||
'values': [{'value': '4.4.4.4'}, {'value': '5.5.5.5'}]
|
||||
},
|
||||
},
|
||||
'rules': [
|
||||
{'subnets': '10.1.0.0/16', 'pool': 'two'},
|
||||
{'pool': 'one'},
|
||||
],
|
||||
},
|
||||
'ttl': 60,
|
||||
'type': 'A',
|
||||
'values': ['1.1.1.1', '2.2.2.2'],
|
||||
}
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, 'bad', a_data)
|
||||
self.assertEqual(
|
||||
['rule 1 subnets must be a list'], ctx.exception.reasons
|
||||
)
|
||||
|
||||
# rule with invalid subnet
|
||||
a_data = {
|
||||
'dynamic': {
|
||||
'pools': {
|
||||
'one': {'values': [{'value': '3.3.3.3'}]},
|
||||
'two': {
|
||||
'values': [{'value': '4.4.4.4'}, {'value': '5.5.5.5'}]
|
||||
},
|
||||
},
|
||||
'rules': [
|
||||
{'subnets': ['invalid'], 'pool': 'two'},
|
||||
{'pool': 'one'},
|
||||
],
|
||||
},
|
||||
'ttl': 60,
|
||||
'type': 'A',
|
||||
'values': ['1.1.1.1', '2.2.2.2'],
|
||||
}
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, 'bad', a_data)
|
||||
self.assertEqual(
|
||||
['rule 1 invalid subnet "invalid"'], ctx.exception.reasons
|
||||
)
|
||||
|
||||
# rule with invalid geos
|
||||
a_data = {
|
||||
'dynamic': {
|
||||
@@ -1354,3 +1402,162 @@ class TestRecordDynamic(TestCase):
|
||||
['final rule has "subnets" and/or "geos" and is not catchall'],
|
||||
reasons,
|
||||
)
|
||||
|
||||
def test_dynamic_subnet_rule_ordering(self):
|
||||
# boiler plate
|
||||
a_data = {
|
||||
'dynamic': {
|
||||
'pools': {
|
||||
'one': {'values': [{'value': '3.3.3.3'}]},
|
||||
'two': {
|
||||
'values': [{'value': '4.4.4.4'}, {'value': '5.5.5.5'}]
|
||||
},
|
||||
'three': {'values': [{'value': '2.2.2.2'}]},
|
||||
}
|
||||
},
|
||||
'ttl': 60,
|
||||
'type': 'A',
|
||||
'values': ['1.1.1.1', '2.2.2.2'],
|
||||
}
|
||||
dynamic = a_data['dynamic']
|
||||
|
||||
def validate_rules(rules):
|
||||
dynamic['rules'] = rules
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, 'bad', a_data)
|
||||
return ctx.exception.reasons
|
||||
|
||||
# valid subnet-only → subnet+geo
|
||||
dynamic['rules'] = [
|
||||
{'subnets': ['10.1.0.0/16'], 'pool': 'one'},
|
||||
{'subnets': ['11.1.0.0/16'], 'geos': ['NA'], 'pool': 'two'},
|
||||
{'pool': 'three'},
|
||||
]
|
||||
record = Record.new(self.zone, 'good', a_data)
|
||||
self.assertEqual(
|
||||
'10.1.0.0/16', record.dynamic.rules[0].data['subnets'][0]
|
||||
)
|
||||
|
||||
# geo-only → subnet-only
|
||||
self.assertEqual(
|
||||
[
|
||||
'rule 2 with only subnet targeting should appear before all geo targeting rules'
|
||||
],
|
||||
validate_rules(
|
||||
[
|
||||
{'geos': ['NA'], 'pool': 'two'},
|
||||
{'subnets': ['10.1.0.0/16'], 'pool': 'one'},
|
||||
{'pool': 'three'},
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
# geo-only → subnet+geo
|
||||
self.assertEqual(
|
||||
[
|
||||
'rule 2 with subnet(s) and geo(s) should appear before all geo-only rules'
|
||||
],
|
||||
validate_rules(
|
||||
[
|
||||
{'geos': ['NA'], 'pool': 'two'},
|
||||
{'subnets': ['10.1.0.0/16'], 'geos': ['AS'], 'pool': 'one'},
|
||||
{'pool': 'three'},
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
# subnet+geo → subnet-only
|
||||
self.assertEqual(
|
||||
[
|
||||
'rule 2 with only subnet targeting should appear before all geo targeting rules'
|
||||
],
|
||||
validate_rules(
|
||||
[
|
||||
{'subnets': ['11.1.0.0/16'], 'geos': ['NA'], 'pool': 'two'},
|
||||
{'subnets': ['10.1.0.0/16'], 'pool': 'one'},
|
||||
{'pool': 'three'},
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
# geo-only → subnet+geo → subnet-only
|
||||
self.assertEqual(
|
||||
[
|
||||
'rule 2 with subnet(s) and geo(s) should appear before all geo-only rules',
|
||||
'rule 3 with only subnet targeting should appear before all geo targeting rules',
|
||||
],
|
||||
validate_rules(
|
||||
[
|
||||
{'geos': ['NA'], 'pool': 'two'},
|
||||
{'subnets': ['10.1.0.0/16'], 'geos': ['AS'], 'pool': 'one'},
|
||||
{'subnets': ['11.1.0.0/16'], 'pool': 'three'},
|
||||
{'pool': 'one'},
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
def test_dynanic_subnet_ordering(self):
|
||||
# boiler plate
|
||||
a_data = {
|
||||
'dynamic': {
|
||||
'pools': {
|
||||
'one': {'values': [{'value': '3.3.3.3'}]},
|
||||
'two': {
|
||||
'values': [{'value': '4.4.4.4'}, {'value': '5.5.5.5'}]
|
||||
},
|
||||
'three': {'values': [{'value': '2.2.2.2'}]},
|
||||
}
|
||||
},
|
||||
'ttl': 60,
|
||||
'type': 'A',
|
||||
'values': ['1.1.1.1', '2.2.2.2'],
|
||||
}
|
||||
dynamic = a_data['dynamic']
|
||||
|
||||
def validate_rules(rules):
|
||||
dynamic['rules'] = rules
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, 'bad', a_data)
|
||||
return ctx.exception.reasons
|
||||
|
||||
# duplicate subnet
|
||||
self.assertEqual(
|
||||
[
|
||||
'rule 2 targets subnet 10.1.0.0/16 which has previously been seen in rule 1'
|
||||
],
|
||||
validate_rules(
|
||||
[
|
||||
{'subnets': ['10.1.0.0/16'], 'pool': 'two'},
|
||||
{'subnets': ['10.1.0.0/16'], 'pool': 'one'},
|
||||
{'pool': 'three'},
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
# more specific subnet than previous
|
||||
self.assertEqual(
|
||||
[
|
||||
'rule 2 targets subnet 10.1.1.0/24 which is more specific than the previously seen 10.1.0.0/16 in rule 1'
|
||||
],
|
||||
validate_rules(
|
||||
[
|
||||
{'subnets': ['10.1.0.0/16'], 'pool': 'two'},
|
||||
{'subnets': ['10.1.1.0/24'], 'pool': 'one'},
|
||||
{'pool': 'three'},
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
# sub-subnet in the same rule
|
||||
self.assertEqual(
|
||||
[
|
||||
'rule 1 targets subnet 10.1.1.0/24 which is more specific than the previously seen 10.1.0.0/16 in rule 1'
|
||||
],
|
||||
validate_rules(
|
||||
[
|
||||
{'subnets': ['10.1.0.0/16', '10.1.1.0/24'], 'pool': 'two'},
|
||||
{'subnets': ['11.1.0.0/16'], 'pool': 'one'},
|
||||
{'pool': 'three'},
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user