pvl/hosts/tests.py
author Tero Marttila <tero.marttila@aalto.fi>
Wed, 25 Feb 2015 15:06:28 +0200
changeset 468 3e7cb8dd5708
parent 467 3bb00e5e79d3
child 469 cd1f1b51f3a0
permissions -rw-r--r--
pvl.hosts.zone: raise HostZoneError on alias4/alias6 without ip/ip6
import ipaddr
import unittest

from pvl.hosts import config, host, zone
from StringIO import StringIO

class Options(object):
    hosts_charset   = 'utf-8'
    hosts_domain    = None
    hosts_include   = None

class ConfFile(StringIO):
    def __init__(self, name, buffer):
        StringIO.__init__(self, buffer)
        self.name = name

class TestConfig(unittest.TestCase):
    def setUp(self):
        self.options = Options()

    def assertHostEqual(self, host, host_str, attrs):
        self.assertEquals(str(host), host_str)

        for attr, value in attrs.iteritems():
            self.assertEquals(getattr(host, attr), value)

    def assertHostsEqual(self, hosts, expected):
        for host, expect in zip(hosts, expected):
            host_str, attrs = expect

            self.assertHostEqual(host, host_str, attrs)
 
    def testApplyHostsFileError(self):
        with self.assertRaises(config.HostConfigError):
            list(config.apply_hosts(self.options, ['nonexistant']))

    def testApplyHosts(self):
        conf_file = ConfFile('test', """
[foo]
    ip = 127.0.0.1

[bar]
    ip = 127.0.0.2
        """)
        expected = [
                ('foo@test', dict(ip=ipaddr.IPAddress('127.0.0.1'))),
                ('bar@test', dict(ip=ipaddr.IPAddress('127.0.0.2'))),
        ]

        self.assertHostsEqual(config.apply_hosts_file(self.options, conf_file), expected)

    def testApply(self):
        self.assertHostsEqual(config.apply(self.options, ['etc/hosts/test']), [
                ('foo@test', dict(
                    ip          = ipaddr.IPAddress('127.0.0.1'),
                    ethernet    = {None: '00:11:22:33:44:55'},
                )),
                ('bar@test', dict(
                    ip          = ipaddr.IPAddress('127.0.0.2'),
                    ethernet    = {None: '01:23:45:67:89:ab'},
                )),
        ])

    def testApplyHostsExpand(self):
        self.assertHostsEqual(config.apply_host_config(self.options, 'asdf', 'asdf{1-3}', ip='10.100.100.$'), [
                ('asdf1@asdf', dict(ip=ipaddr.IPAddress('10.100.100.1'))),
                ('asdf2@asdf', dict(ip=ipaddr.IPAddress('10.100.100.2'))),
                ('asdf3@asdf', dict(ip=ipaddr.IPAddress('10.100.100.3'))),
        ])

    def testApplyHostConfigDict(self):
        host = config.apply_host(self.options, 'foo', 'test', {
            'ethernet.eth0': '00:11:22:33:44:55',
        })

        self.assertHostEqual(host, 'foo@test', dict(
                ethernet    = { 'eth0': '00:11:22:33:44:55' }
        ))
   
    def testApplyHostsConfigError(self):
        with self.assertRaises(config.HostConfigError):
            config.apply_host(self.options, 'foo', 'test', {
                'ethernet': 'foo',
                'ethernet.eth0': 'bar',
            })

class TestForwardZone(unittest.TestCase):
    def setUp(self):
        self.options = Options()
        self.options.add_origin = False

    def assertZoneEquals(self, rrs, expected):
        gather = { }

        for rr in rrs:
            key = (rr.name.lower(), rr.type.upper())

            self.assertNotIn(key, gather)

            gather[key] = rr.data

        self.assertDictEqual(gather, expected)

    def testResolve(self):
        self.assertEquals(zone.resolve(None, None, 'host'), 'host.')
        self.assertEquals(zone.resolve(None, 'domain', 'host'), 'host.domain.')

        with self.assertRaises(zone.HostZoneError):
            zone.resolve('origin', 'domain', 'host')

        self.assertEquals(zone.resolve('domain', 'domain', 'host'), 'host')
        self.assertEquals(zone.resolve('origin', 'domain.origin', 'host'), 'host.domain')
        
        with self.assertRaises(zone.HostZoneError):
            zone.resolve('origin', 'domainorigin', 'host')

        with self.assertRaises(zone.HostZoneError):
            zone.resolve('origin', None, 'host.domain')

    def testHostForwardOutOfOrigin(self):
        h = host.Host('host', 'domain', ip=ipaddr.IPAddress('10.0.0.1'))

        self.assertZoneEquals(zone.host_forward(h, 'test'), { })

    def testHostIP(self):
        h = host.Host.build('host', 'domain',
                ip  = '192.0.2.1',
                ip6 = '2001:db8::192.0.2.1',
        )

        self.assertZoneEquals(zone.host_forward(h, 'domain'), {
            ('host', 'A'): ['192.0.2.1'],
            ('host', 'AAAA'): ['2001:db8::c000:201'],
        })

        self.assertZoneEquals((rr for ip, rr in zone.host_reverse(h, ipaddr.IPNetwork('192.0.2.1/24'))), {
            ('1', 'PTR'): ['host.domain.'],
        })

        self.assertZoneEquals((rr for ip, rr in zone.host_reverse(h, ipaddr.IPNetwork('2001:db8::/64'))), {
            ('1.0.2.0.0.0.0.c.0.0.0.0.0.0.0.0', 'PTR'): ['host.domain.'],
        })
    
    def testHostAlias(self):
        h = host.Host.build('host', 'domain',
                ip      = '192.0.2.1',
                alias   = 'test *.test',
        )

        self.assertEquals(h.alias, ['test', '*.test'])

        self.assertZoneEquals(zone.host_forward(h, 'domain'), {
            ('host', 'A'): ['192.0.2.1'],
            ('test', 'CNAME'): ['host'],
            ('*.test', 'CNAME'): ['host'],
        })

    def testHostAlias46(self):
        h = host.Host.build('host', 'domain',
                ip      = '192.0.2.1',
                ip6     = '2001:db8::192.0.2.1',
                alias4  = 'test4',
                alias6  = 'test6',
        )

        self.assertZoneEquals(zone.host_forward(h, 'domain'), {
            ('host', 'A'): ['192.0.2.1'],
            ('host', 'AAAA'): ['2001:db8::c000:201'],
            ('test4', 'A'): ['192.0.2.1'],
            ('test6', 'AAAA'): ['2001:db8::c000:201'],
        })

    def testHostAlias4Missing(self):
        h = host.Host.build('host', 'domain',
                ip6     = '2001:db8::192.0.2.1',
                alias4  = 'test4',
                alias6  = 'test6',
        )

        with self.assertRaises(zone.HostZoneError):
            self.assertZoneEquals(zone.host_forward(h, 'domain'), { })

    def testHostAlias6Missing(self):
        h = host.Host.build('host', 'domain',
                ip      = '192.0.2.1',
                alias4  = 'test4',
                alias6  = 'test6',
        )

        with self.assertRaises(zone.HostZoneError):
            self.assertZoneEquals(zone.host_forward(h, 'domain'), { })

    def testHostForwardAlias(self):
        h = host.Host.build('host', 'domain',
                forward = 'host.example.net',
                alias   = 'test',
        )

        self.assertZoneEquals(zone.host_forward(h, 'domain'), {
            ('host', 'CNAME'): ['host.example.net.'],
            ('test', 'CNAME'): ['host'],
        })

    def testHostDelegateForward(self):
        h = host.Host.build('host', 'example.com',
                forward = 'host.example.net',
        )

        self.assertZoneEquals(zone.host_forward(h, 'example.com'), {
            ('host', 'CNAME'): ['host.example.net.'],
        })

    def testHostDelegate(self):
        h = host.Host.build('host', 'example.com',
                ip      = '192.0.2.1',
                ip6     = '2001:db8::192.0.2.1',
                forward = '',
                reverse = '1.0/28.2.0.192.in-addr.arpa',
        )

        self.assertZoneEquals(zone.host_forward(h, 'example.com'), {

        })

        self.assertZoneEquals((rr for ip, rr in zone.host_reverse(h, ipaddr.IPNetwork('192.0.2.1/24'))), {
            ('1', 'CNAME'): ['1.0/28.2.0.192.in-addr.arpa.'],
        })
        
        self.assertZoneEquals((rr for ip, rr in zone.host_reverse(h, ipaddr.IPNetwork('2001:db8::/64'))), {

        })

if __name__ == '__main__':
    unittest.main()