mirror of
https://github.com/github/octodns.git
synced 2024-05-11 05:55:00 +00:00
Add support for LOC records
This commit is contained in:
@@ -9,10 +9,11 @@ from six import text_type
|
||||
from unittest import TestCase
|
||||
|
||||
from octodns.record import ARecord, AaaaRecord, AliasRecord, CaaRecord, \
|
||||
CaaValue, CnameRecord, DnameRecord, Create, Delete, GeoValue, MxRecord, \
|
||||
MxValue, NaptrRecord, NaptrValue, NsRecord, PtrRecord, Record, \
|
||||
SshfpRecord, SshfpValue, SpfRecord, SrvRecord, SrvValue, TxtRecord, \
|
||||
Update, ValidationError, _Dynamic, _DynamicPool, _DynamicRule
|
||||
CaaValue, CnameRecord, DnameRecord, Create, Delete, GeoValue, LocRecord, \
|
||||
LocValue, MxRecord, MxValue, NaptrRecord, NaptrValue, NsRecord, \
|
||||
PtrRecord, Record, SshfpRecord, SshfpValue, SpfRecord, SrvRecord, \
|
||||
SrvValue, TxtRecord, Update, ValidationError, _Dynamic, _DynamicPool, \
|
||||
_DynamicRule
|
||||
from octodns.zone import Zone
|
||||
|
||||
from helpers import DynamicProvider, GeoProvider, SimpleProvider
|
||||
@@ -379,6 +380,98 @@ class TestRecord(TestCase):
|
||||
self.assertSingleValue(DnameRecord, 'target.foo.com.',
|
||||
'other.foo.com.')
|
||||
|
||||
def test_loc(self):
|
||||
a_values = [{
|
||||
'lat_degrees': 31,
|
||||
'lat_minutes': 58,
|
||||
'lat_seconds': 52.1,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': 20,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}]
|
||||
a_data = {'ttl': 30, 'values': a_values}
|
||||
a = LocRecord(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[0]['lat_degrees'], a.values[0].lat_degrees)
|
||||
self.assertEquals(a_values[0]['lat_minutes'], a.values[0].lat_minutes)
|
||||
self.assertEquals(a_values[0]['lat_seconds'], a.values[0].lat_seconds)
|
||||
self.assertEquals(a_values[0]['lat_direction'],
|
||||
a.values[0].lat_direction)
|
||||
self.assertEquals(a_values[0]['long_degrees'],
|
||||
a.values[0].long_degrees)
|
||||
self.assertEquals(a_values[0]['long_minutes'],
|
||||
a.values[0].long_minutes)
|
||||
self.assertEquals(a_values[0]['long_seconds'],
|
||||
a.values[0].long_seconds)
|
||||
self.assertEquals(a_values[0]['long_direction'],
|
||||
a.values[0].long_direction)
|
||||
self.assertEquals(a_values[0]['altitude'], a.values[0].altitude)
|
||||
self.assertEquals(a_values[0]['size'], a.values[0].size)
|
||||
self.assertEquals(a_values[0]['precision_horz'],
|
||||
a.values[0].precision_horz)
|
||||
self.assertEquals(a_values[0]['precision_vert'],
|
||||
a.values[0].precision_vert)
|
||||
|
||||
b_value = {
|
||||
'lat_degrees': 32,
|
||||
'lat_minutes': 7,
|
||||
'lat_seconds': 19,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 116,
|
||||
'long_minutes': 2,
|
||||
'long_seconds': 25,
|
||||
'long_direction': 'E',
|
||||
'altitude': 10,
|
||||
'size': 1,
|
||||
'precision_horz': 10000,
|
||||
'precision_vert': 10,
|
||||
}
|
||||
b_data = {'ttl': 30, 'value': b_value}
|
||||
b = LocRecord(self.zone, 'b', b_data)
|
||||
self.assertEquals(b_value['lat_degrees'], b.values[0].lat_degrees)
|
||||
self.assertEquals(b_value['lat_minutes'], b.values[0].lat_minutes)
|
||||
self.assertEquals(b_value['lat_seconds'], b.values[0].lat_seconds)
|
||||
self.assertEquals(b_value['lat_direction'], b.values[0].lat_direction)
|
||||
self.assertEquals(b_value['long_degrees'], b.values[0].long_degrees)
|
||||
self.assertEquals(b_value['long_minutes'], b.values[0].long_minutes)
|
||||
self.assertEquals(b_value['long_seconds'], b.values[0].long_seconds)
|
||||
self.assertEquals(b_value['long_direction'],
|
||||
b.values[0].long_direction)
|
||||
self.assertEquals(b_value['altitude'], b.values[0].altitude)
|
||||
self.assertEquals(b_value['size'], b.values[0].size)
|
||||
self.assertEquals(b_value['precision_horz'],
|
||||
b.values[0].precision_horz)
|
||||
self.assertEquals(b_value['precision_vert'],
|
||||
b.values[0].precision_vert)
|
||||
self.assertEquals(b_data, b.data)
|
||||
|
||||
target = SimpleProvider()
|
||||
# No changes with self
|
||||
self.assertFalse(a.changes(a, target))
|
||||
# Diff in lat_direction causes change
|
||||
other = LocRecord(self.zone, 'a', {'ttl': 30, 'values': a_values})
|
||||
other.values[0].lat_direction = 'N'
|
||||
change = a.changes(other, target)
|
||||
self.assertEqual(change.existing, a)
|
||||
self.assertEqual(change.new, other)
|
||||
# Diff in altitude causes change
|
||||
other.values[0].altitude = a.values[0].altitude
|
||||
other.values[0].altitude = -10
|
||||
change = a.changes(other, target)
|
||||
self.assertEqual(change.existing, a)
|
||||
self.assertEqual(change.new, other)
|
||||
|
||||
# __repr__ doesn't blow up
|
||||
a.__repr__()
|
||||
|
||||
def test_mx(self):
|
||||
a_values = [{
|
||||
'preference': 10,
|
||||
@@ -1127,6 +1220,93 @@ class TestRecord(TestCase):
|
||||
self.assertTrue(d >= d)
|
||||
self.assertTrue(d <= d)
|
||||
|
||||
def test_loc_value(self):
|
||||
a = LocValue({
|
||||
'lat_degrees': 31,
|
||||
'lat_minutes': 58,
|
||||
'lat_seconds': 52.1,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': 20,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
})
|
||||
b = LocValue({
|
||||
'lat_degrees': 32,
|
||||
'lat_minutes': 7,
|
||||
'lat_seconds': 19,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 116,
|
||||
'long_minutes': 2,
|
||||
'long_seconds': 25,
|
||||
'long_direction': 'E',
|
||||
'altitude': 10,
|
||||
'size': 1,
|
||||
'precision_horz': 10000,
|
||||
'precision_vert': 10,
|
||||
})
|
||||
c = LocValue({
|
||||
'lat_degrees': 53,
|
||||
'lat_minutes': 14,
|
||||
'lat_seconds': 10,
|
||||
'lat_direction': 'N',
|
||||
'long_degrees': 2,
|
||||
'long_minutes': 18,
|
||||
'long_seconds': 26,
|
||||
'long_direction': 'W',
|
||||
'altitude': 10,
|
||||
'size': 1,
|
||||
'precision_horz': 1000,
|
||||
'precision_vert': 10,
|
||||
})
|
||||
|
||||
self.assertEqual(a, a)
|
||||
self.assertEqual(b, b)
|
||||
self.assertEqual(c, c)
|
||||
|
||||
self.assertNotEqual(a, b)
|
||||
self.assertNotEqual(a, c)
|
||||
self.assertNotEqual(b, a)
|
||||
self.assertNotEqual(b, c)
|
||||
self.assertNotEqual(c, a)
|
||||
self.assertNotEqual(c, b)
|
||||
|
||||
self.assertTrue(a < b)
|
||||
self.assertTrue(a < c)
|
||||
|
||||
self.assertTrue(b > a)
|
||||
self.assertTrue(b < c)
|
||||
|
||||
self.assertTrue(c > a)
|
||||
self.assertTrue(c > b)
|
||||
|
||||
self.assertTrue(a <= b)
|
||||
self.assertTrue(a <= c)
|
||||
self.assertTrue(a <= a)
|
||||
self.assertTrue(a >= a)
|
||||
|
||||
self.assertTrue(b >= a)
|
||||
self.assertTrue(b <= c)
|
||||
self.assertTrue(b >= b)
|
||||
self.assertTrue(b <= b)
|
||||
|
||||
self.assertTrue(c >= a)
|
||||
self.assertTrue(c >= b)
|
||||
self.assertTrue(c >= c)
|
||||
self.assertTrue(c <= c)
|
||||
|
||||
# Hash
|
||||
values = set()
|
||||
values.add(a)
|
||||
self.assertTrue(a in values)
|
||||
self.assertFalse(b in values)
|
||||
values.add(b)
|
||||
self.assertTrue(b in values)
|
||||
|
||||
def test_mx_value(self):
|
||||
a = MxValue({'preference': 0, 'priority': 'a', 'exchange': 'v',
|
||||
'value': '1'})
|
||||
@@ -1960,6 +2140,306 @@ class TestRecordValidation(TestCase):
|
||||
self.assertEquals(['DNAME value "foo.bar.com" missing trailing .'],
|
||||
ctx.exception.reasons)
|
||||
|
||||
def test_LOC(self):
|
||||
# doesn't blow up
|
||||
Record.new(self.zone, '', {
|
||||
'type': 'LOC',
|
||||
'ttl': 600,
|
||||
'value': {
|
||||
'lat_degrees': 31,
|
||||
'lat_minutes': 58,
|
||||
'lat_seconds': 52.1,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': 20,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}
|
||||
})
|
||||
|
||||
# missing int key
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, '', {
|
||||
'type': 'LOC',
|
||||
'ttl': 600,
|
||||
'value': {
|
||||
'lat_minutes': 58,
|
||||
'lat_seconds': 52.1,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': 20,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEquals(['missing lat_degrees'], ctx.exception.reasons)
|
||||
|
||||
# missing float key
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, '', {
|
||||
'type': 'LOC',
|
||||
'ttl': 600,
|
||||
'value': {
|
||||
'lat_degrees': 31,
|
||||
'lat_minutes': 58,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': 20,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEquals(['missing lat_seconds'], ctx.exception.reasons)
|
||||
|
||||
# missing text key
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, '', {
|
||||
'type': 'LOC',
|
||||
'ttl': 600,
|
||||
'value': {
|
||||
'lat_degrees': 31,
|
||||
'lat_minutes': 58,
|
||||
'lat_seconds': 52.1,
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': 20,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEquals(['missing lat_direction'], ctx.exception.reasons)
|
||||
|
||||
# invalid direction
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, '', {
|
||||
'type': 'LOC',
|
||||
'ttl': 600,
|
||||
'value': {
|
||||
'lat_degrees': 31,
|
||||
'lat_minutes': 58,
|
||||
'lat_seconds': 52.1,
|
||||
'lat_direction': 'U',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': 20,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEquals(['invalid direction for lat_direction "U"'],
|
||||
ctx.exception.reasons)
|
||||
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, '', {
|
||||
'type': 'LOC',
|
||||
'ttl': 600,
|
||||
'value': {
|
||||
'lat_degrees': 31,
|
||||
'lat_minutes': 58,
|
||||
'lat_seconds': 52.1,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'N',
|
||||
'altitude': 20,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEquals(['invalid direction for long_direction "N"'],
|
||||
ctx.exception.reasons)
|
||||
|
||||
# invalid degrees
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, '', {
|
||||
'type': 'LOC',
|
||||
'ttl': 600,
|
||||
'value': {
|
||||
'lat_degrees': 360,
|
||||
'lat_minutes': 58,
|
||||
'lat_seconds': 52.1,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': 20,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEquals(['invalid value for lat_degrees "360"'],
|
||||
ctx.exception.reasons)
|
||||
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, '', {
|
||||
'type': 'LOC',
|
||||
'ttl': 600,
|
||||
'value': {
|
||||
'lat_degrees': 'nope',
|
||||
'lat_minutes': 58,
|
||||
'lat_seconds': 52.1,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': 20,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEquals(['invalid lat_degrees "nope"'],
|
||||
ctx.exception.reasons)
|
||||
|
||||
# invalid minutes
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, '', {
|
||||
'type': 'LOC',
|
||||
'ttl': 600,
|
||||
'value': {
|
||||
'lat_degrees': 31,
|
||||
'lat_minutes': 60,
|
||||
'lat_seconds': 52.1,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': 20,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEquals(['invalid value for lat_minutes "60"'],
|
||||
ctx.exception.reasons)
|
||||
|
||||
# invalid seconds
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, '', {
|
||||
'type': 'LOC',
|
||||
'ttl': 600,
|
||||
'value': {
|
||||
'lat_degrees': 31,
|
||||
'lat_minutes': 58,
|
||||
'lat_seconds': 60,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': 20,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEquals(['invalid value for lat_seconds "60"'],
|
||||
ctx.exception.reasons)
|
||||
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, '', {
|
||||
'type': 'LOC',
|
||||
'ttl': 600,
|
||||
'value': {
|
||||
'lat_degrees': 31,
|
||||
'lat_minutes': 58,
|
||||
'lat_seconds': 'nope',
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': 20,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEquals(['invalid lat_seconds "nope"'],
|
||||
ctx.exception.reasons)
|
||||
|
||||
# invalid altitude
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, '', {
|
||||
'type': 'LOC',
|
||||
'ttl': 600,
|
||||
'value': {
|
||||
'lat_degrees': 31,
|
||||
'lat_minutes': 58,
|
||||
'lat_seconds': 52.1,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': -666666,
|
||||
'size': 10,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEquals(['invalid value for altitude "-666666"'],
|
||||
ctx.exception.reasons)
|
||||
|
||||
# invalid size
|
||||
with self.assertRaises(ValidationError) as ctx:
|
||||
Record.new(self.zone, '', {
|
||||
'type': 'LOC',
|
||||
'ttl': 600,
|
||||
'value': {
|
||||
'lat_degrees': 31,
|
||||
'lat_minutes': 58,
|
||||
'lat_seconds': 52.1,
|
||||
'lat_direction': 'S',
|
||||
'long_degrees': 115,
|
||||
'long_minutes': 49,
|
||||
'long_seconds': 11.7,
|
||||
'long_direction': 'E',
|
||||
'altitude': 20,
|
||||
'size': 99999999.99,
|
||||
'precision_horz': 10,
|
||||
'precision_vert': 2,
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEquals(['invalid value for size "99999999.99"'],
|
||||
ctx.exception.reasons)
|
||||
|
||||
def test_MX(self):
|
||||
# doesn't blow up
|
||||
Record.new(self.zone, '', {
|
||||
|
||||
Reference in New Issue
Block a user