# -*- coding: utf-8 -*-
##----------------------------------------------------------------------
## Unittests for access system
##----------------------------------------------------------------------
## Copyright (C) 2007-2009 The NOC Project
## See LICENSE for details
##----------------------------------------------------------------------
from unittest import TestCase
from noc.dns.models import *
from noc.ip.models import VRF, Address
##
##
##
class AccessTestCase(TestCase):
    ADDRESSES = [("h1.example.com", "10.0.0.3"),
                 ("h2.example.com", "10.0.0.4"),
                 ("h3.example.com", "10.0.1.3"),
                 ("h4.example.com", "2001:db8::1"),
                 ("h5.example.com", "2001:db8::2")]
    ##
    ## Create default data set
    ##
    def setUp(self):
        # Get default types
        self.ns_type = DNSZoneRecordType.objects.get(type="NS")
        # NS1
        self.ns1 = DNSServer(name="ns1.example.com", generator_name="BINDv9",
                    ip="10.0.0.1")
        self.ns1.save()
        # NS2
        self.ns2 = DNSServer(name="ns2.example.com", generator_name="BINDv9",
                    ip="10.0.0.2", location="Mordor")
        self.ns2.save()
        # P1
        self.profile1 = DNSZoneProfile(name="p1", zone_soa="example.com",
            zone_contact="dns@example.com")
        self.profile1.save()
        self.profile1.masters.add(self.ns1)
        self.profile1.masters.add(self.ns2)
        # P2
        self.profile2 = DNSZoneProfile(name="p2", zone_soa="example.com",
            zone_contact="dns@example.com")
        self.profile2.save()
        self.profile2.masters.add(self.ns1)
        self.profile2.slaves.add(self.ns2)
        # P3
        self.profile3 = DNSZoneProfile(name="p3", zone_soa="example.com",
            zone_contact="dns@example.com")
        self.profile3.save()
        self.profile3.masters.add(self.ns1)
        # Z11
        self.z11 = DNSZone(name="example.com", is_auto_generated=True,
            profile=self.profile1)
        self.z11.save()
        # Z12
        self.z12 = DNSZone(name="z12.example.com", is_auto_generated=True,
            profile=self.profile1)
        self.z12.save()
        # Z21
        self.z21 = DNSZone(name="z21.example.com", is_auto_generated=True,
            profile=self.profile2)
        self.z21.save()
        # Z31
        self.z31 = DNSZone(name="z31.example.com", is_auto_generated=True,
            profile=self.profile3)
        self.z31.save()
        # ZR41
        self.zr41 = DNSZone(name="0.0.10.in-addr.arpa", is_auto_generated=True,
            profile=self.profile1)
        self.zr41.save()
        DNSZoneRecord(zone=self.zr41, left="8/29", type=self.ns_type,
            right="ns3.example.com").save()
        # ZR42
        self.zr42 = DNSZone(name="1.0.10.in-addr.arpa", is_auto_generated=True,
            profile=self.profile1)
        self.zr42.save()
        # ZR61
        self.zr61 = DNSZone(name="8.b.d.0.1.0.0.2.ip6.int",
            is_auto_generated=True,
            profile=self.profile1)
        self.zr61.save()
        # ZR62
        self.zr62 = DNSZone(name="1.9.b.d.0.1.0.0.2.ip6.int",
            is_auto_generated=True,
            profile=self.profile1)
        self.zr62.save()
        #
        vrf = VRF.get_global()
        # Save IPv6 status
        self.has_ipv6 = vrf.afi_ipv6
        if not self.has_ipv6:
            vrf.afi_ipv6 = True
            vrf.save()
        # Add addressess
        for h, a in self.ADDRESSES:
            Address(vrf=vrf, address=a, fqdn=h).save()
    
    ##
    ## Cleanup
    ##
    def tearDown(self):
        self.z11.delete()
        del self.z11
        self.z12.delete()
        del self.z12
        self.z21.delete()
        del self.z21
        self.z31.delete()
        del self.z31
        self.zr41.dnszonerecord_set.all().delete()
        self.zr41.delete()
        del self.zr41
        self.zr42.delete()
        del self.zr42
        self.zr61.delete()
        del self.zr61
        self.zr62.delete()
        del self.zr62
        self.profile1.delete()
        del self.profile1
        self.profile2.delete()
        del self.profile2
        self.profile3.delete()
        del self.profile3
        self.ns1.delete()
        del self.ns1
        self.ns2.delete()
        del self.ns2
        vrf = VRF.get_global()
        for h, a in self.ADDRESSES:
            Address.objects.get(vrf=vrf, address=a, fqdn=h).delete()
        if not self.has_ipv6:
            vrf.afi_ipv6 = False
            vrf.save()
    
    ##
    ## Test __unicode__ methods
    ##
    def test_unicode(self):
        for c in [DNSServer, DNSZoneProfile, DNSZone, DNSZoneRecord]:
            for o in c.objects.all():
                unicode(o)
    
    ##
    ## Test .get_absolute_url methods
    ##
    def test_absolute_url(self):
        for c in [DNSServer, DNSZoneProfile, DNSZone]:
            if hasattr(c, "get_absolute_url"):
                for o in c.objects.all():
                    url = o.get_absolute_url()
                    self.assertTrue(str(o.id) in url,
                        "%s not in %s" % (o.id, url))
    
    ##
    ## Test DNSServer.expand_vars()
    ##
    def test_dnsserver_expand_vars(self):
        s = "TEST: %(ip)s - %(ns)s"
        self.assertEqual(self.ns1.expand_vars(s),
            "TEST: 10.0.0.1 - ns1.example.com")
        self.assertEqual(self.ns2.expand_vars(s),
            "TEST: 10.0.0.2 - ns2.example.com")
    
    ##
    ## Test DNSServer.generator_class
    ##
    def test_dnsserver_generator_class(self):
        self.assertEqual(self.ns1.generator_class.name, "BINDv9")
        self.assertEqual(self.ns2.generator_class.name, "BINDv9")
    
    ##
    ## Test DNSZoneProfile.authoritative_servers
    ##
    def test_profile_authoritative_servers(self):
        # Check profile 1
        self.assertTrue(self.ns1 in self.profile1.authoritative_servers)
        self.assertTrue(self.ns2 in self.profile1.authoritative_servers)
        # Check profile 2
        self.assertTrue(self.ns1 in self.profile2.authoritative_servers)
        self.assertTrue(self.ns2 in self.profile2.authoritative_servers)
        # Check profile 3
        self.assertTrue(self.ns1 in self.profile3.authoritative_servers)
        self.assertFalse(self.ns2 in self.profile3.authoritative_servers)
    
    ##
    ## Test DNSZone managers
    ##
    def test_zone_managers(self):
        fz = list(DNSZone.forward_zones.all())
        rz = list(DNSZone.reverse_zones.all())
        for z in [self.z11, self.z12, self.z21, self.z31]:
            self.assertTrue(z in fz)
            self.assertFalse(z in rz)
        for z in [self.zr41, self.zr42, self.zr61, self.zr62]:
            self.assertTrue(z in rz)
            self.assertFalse(z in fz)
    
    ##
    ## Test DNSZone.type
    ##
    def test_zone_type(self):
        for fz in [self.z11, self.z12, self.z21, self.z31]:
            self.assertEqual(fz.type, "F")
        for r4z in [self.zr41, self.zr42]:
            self.assertEqual(r4z.type, "R4")
        for r6z in [self.zr61, self.zr62]:
            self.assertEqual(r6z.type, "R6")
    
    ##
    ## Test DNSZone.reverse_prefix
    ##
    def test_zone_reverse_prefix(self):
        self.assertEqual(self.zr41.reverse_prefix, "10.0.0.0/24")
        self.assertEqual(self.zr42.reverse_prefix, "10.0.1.0/24")
        self.assertEqual(self.zr61.reverse_prefix, "2001:db8::/32")
        self.assertEqual(self.zr62.reverse_prefix, "2001:db9:1000::/36")
    
    ##
    ## DNSZone.next_serial
    ##
    def test_zone_next_serial(self):
        for z in DNSZone.objects.all():
            s = z.next_serial
            self.assertEqual(len(s), 10)
            self.assertEqual(s[-2:], "00")
            z.serial = z.next_serial
            z.save()
            s = z.next_serial
            self.assertEqual(len(s), 10)
            self.assertEqual(s[-2:], "01")
    
    ##
    ##
    ##
    def test_zone_records(self):
        z11_records = self.z11.records
        for r in [("ns1", "IN A", "10.0.0.1"),
                  ("ns2", "IN A", "10.0.0.2"),
                  ("z12", "IN NS", "ns1.example.com."),
                  ("z12", "IN NS", "ns2.example.com."),
                  ("z21", "IN NS", "ns1.example.com."),
                  ("z21", "IN NS", "ns2.example.com."),
                  ("z31", "IN NS", "ns1.example.com.")]:
            self.assertTrue(r in z11_records)
        zr41_records = self.zr41.records
        # Check classless delegation
        for r in [
                ("8", "CNAME", "8.8/29"),
                ("9", "CNAME", "9.8/29"),
                ("10", "CNAME", "10.8/29"),
                ("11", "CNAME", "11.8/29"),
                ("12", "CNAME", "12.8/29"),
                ("13", "CNAME", "13.8/29"),
                ("14", "CNAME", "14.8/29"),
                ("15", "CNAME", "15.8/29"),
                ("8/29", "IN NS", "ns3.example.com")]:
            self.assertTrue(r in zr41_records,
                "%s not in %s" % (r, zr41_records))
        zr42_records = self.zr42.records
        zr61_records = self.zr61.records
    
    ##
    ##
    ##
    def test_zone_rpsl(self):
        for z in DNSZone.objects.all():
            rpsl = z.rpsl
            if z.type == "F":
                self.assertEqual(rpsl, "")
    
