diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2010-03-29 16:08:11 +0200 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2010-03-29 18:05:29 +0200 |
commit | 4bbc3ff037026c72f3249f59c1b5af69a6ad6d69 (patch) | |
tree | 125857a1edbf3246579e51b10f6e62ec875062bc /lib/dnspython/tests | |
parent | 89aa3b766b926d19dac4805a7e72433e497ce872 (diff) | |
download | samba-4bbc3ff037026c72f3249f59c1b5af69a6ad6d69.tar.gz samba-4bbc3ff037026c72f3249f59c1b5af69a6ad6d69.tar.bz2 samba-4bbc3ff037026c72f3249f59c1b5af69a6ad6d69.zip |
s4-python: Move dnspython to lib/, like the other Python modules
This also avoids it from being installed if it's already present on the
system.
Diffstat (limited to 'lib/dnspython/tests')
-rw-r--r-- | lib/dnspython/tests/Makefile | 26 | ||||
-rw-r--r-- | lib/dnspython/tests/bugs.py | 44 | ||||
-rw-r--r-- | lib/dnspython/tests/example | 225 | ||||
-rw-r--r-- | lib/dnspython/tests/example1.good | 121 | ||||
-rw-r--r-- | lib/dnspython/tests/example2.good | 121 | ||||
-rw-r--r-- | lib/dnspython/tests/flags.py | 59 | ||||
-rw-r--r-- | lib/dnspython/tests/message.py | 179 | ||||
-rw-r--r-- | lib/dnspython/tests/name.py | 697 | ||||
-rw-r--r-- | lib/dnspython/tests/namedict.py | 102 | ||||
-rw-r--r-- | lib/dnspython/tests/ntoaaton.py | 156 | ||||
-rw-r--r-- | lib/dnspython/tests/rdtypeandclass.py | 123 | ||||
-rw-r--r-- | lib/dnspython/tests/resolver.py | 105 | ||||
-rw-r--r-- | lib/dnspython/tests/rrset.py | 54 | ||||
-rw-r--r-- | lib/dnspython/tests/set.py | 208 | ||||
-rw-r--r-- | lib/dnspython/tests/tokenizer.py | 190 | ||||
-rw-r--r-- | lib/dnspython/tests/update.py | 114 | ||||
-rw-r--r-- | lib/dnspython/tests/zone.py | 389 |
17 files changed, 2913 insertions, 0 deletions
diff --git a/lib/dnspython/tests/Makefile b/lib/dnspython/tests/Makefile new file mode 100644 index 0000000000..584f6a7da7 --- /dev/null +++ b/lib/dnspython/tests/Makefile @@ -0,0 +1,26 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +# $Id: Makefile,v 1.5 2004/03/19 00:17:27 halley Exp $ + +PYTHON=python + +check: test + +test: + @for i in *.py; do \ + echo "Running $$i:"; \ + ${PYTHON} $$i || exit 1; \ + done diff --git a/lib/dnspython/tests/bugs.py b/lib/dnspython/tests/bugs.py new file mode 100644 index 0000000000..0896e3f02d --- /dev/null +++ b/lib/dnspython/tests/bugs.py @@ -0,0 +1,44 @@ +# Copyright (C) 2006, 2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import unittest + +import dns.rdata +import dns.rdataclass +import dns.rdatatype +import dns.ttl + +class BugsTestCase(unittest.TestCase): + + def test_float_LOC(self): + rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.LOC, + "30 30 0.000 N 100 30 0.000 W 10.00m 20m 2000m 20m") + self.failUnless(rdata.float_latitude == 30.5) + self.failUnless(rdata.float_longitude == -100.5) + + def test_SOA_BIND8_TTL(self): + rdata1 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, + "a b 100 1s 1m 1h 1d") + rdata2 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, + "a b 100 1 60 3600 86400") + self.failUnless(rdata1 == rdata2) + + def test_TTL_bounds_check(self): + def bad(): + ttl = dns.ttl.from_text("2147483648") + self.failUnlessRaises(dns.ttl.BadTTL, bad) + +if __name__ == '__main__': + unittest.main() diff --git a/lib/dnspython/tests/example b/lib/dnspython/tests/example new file mode 100644 index 0000000000..d87c63a393 --- /dev/null +++ b/lib/dnspython/tests/example @@ -0,0 +1,225 @@ +; Copyright (C) 2000, 2001 Internet Software Consortium. +; +; Permission to use, copy, modify, and distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM +; DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL +; INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING +; FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +; NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +; WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +; $Id: example,v 1.13 2004/03/19 00:06:37 halley Exp $ + +$ORIGIN . +$TTL 300 ; 5 minutes +example IN SOA ns1.example. hostmaster.example. ( + 1 ; serial + 2000 ; refresh (2000 seconds) + 2000 ; retry (2000 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) +example. NS ns1.example. +ns1.example. A 10.53.0.1 +example. NS ns2.example. +ns2.example. A 10.53.0.2 + +$ORIGIN example. +* MX 10 mail +a TXT "foo foo foo" + PTR foo.net. +;; The next line not starting with ';;' is leading whitespace followed by +;; EOL. We want to treat that as if EOL had appeared alone. + +;; The next line not starting with ';;' is leading whitespace followed by +;; a comment followed by EOL. We want to treat that as if EOL had appeared +;; alone. + ; foo +$TTL 3600 ; 1 hour +a01 A 0.0.0.0 +a02 A 255.255.255.255 +;; +;; XXXRTH dnspython doesn't currently implement A6, and since +;; A6 records are effectively dead, it may never do so. +;; +;;a601 A6 0 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +;; A6 64 ::ffff:ffff:ffff:ffff foo. +;; A6 127 ::1 foo. +;; A6 128 . +aaaa01 AAAA ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +aaaa02 AAAA ::1 +afsdb01 AFSDB 0 hostname +afsdb02 AFSDB 65535 . +$TTL 300 ; 5 minutes +b CNAME foo.net. +c A 73.80.65.49 +$TTL 3600 ; 1 hour +cert01 CERT 65534 65535 PRIVATEOID ( + MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi + WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl + d80jEeC8aTrO+KKmCaY= ) +cname01 CNAME cname-target. +cname02 CNAME cname-target +cname03 CNAME . +$TTL 300 ; 5 minutes +d A 73.80.65.49 +$TTL 3600 ; 1 hour +dhcid01 DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69l + OjxfNuVAA2kjEA= ) +dhcid02 DHCID ( AAEBOSD+XR3Os/0LozeXVqcNc7FwCfQdW + L3b/NaiUDlW2No= ) +dhcid03 DHCID ( AAABxLmlskllE0MVjd57zHcWmEH3pCQ6V + ytcKD//7es/deY= ) +dname01 DNAME dname-target. +dname02 DNAME dname-target +dname03 DNAME . +$TTL 300 ; 5 minutes +e MX 10 mail + TXT "one" + TXT "three" + TXT "two" + A 73.80.65.49 + A 73.80.65.50 + A 73.80.65.52 + A 73.80.65.51 +f A 73.80.65.52 +$TTL 3600 ; 1 hour +gpos01 GPOS "-22.6882" "116.8652" "250.0" +;; +;; XXXRTH I have commented out the following line because I don't think +;; it is a valid GPOS record. +;; +;;gpos02 GPOS "" "" "" +hinfo01 HINFO "Generic PC clone" "NetBSD-1.4" +hinfo02 HINFO "PC" "NetBSD" +isdn01 ISDN "isdn-address" +isdn02 ISDN "isdn-address" "subaddress" +isdn03 ISDN "isdn-address" +isdn04 ISDN "isdn-address" "subaddress" +key01 KEY 512 255 1 ( + AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aR + yzWZriO6i2odGWWQVucZqKVsENW91IOW4vqudngPZsY3 + GvQ/xVA8/7pyFj6b7Esga60zyGW6LFe9r8n6paHrlG5o + jqf0BaqHT+8= ) +key02 KEY HOST|FLAG4 DNSSEC RSAMD5 ( + AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aR + yzWZriO6i2odGWWQVucZqKVsENW91IOW4vqudngPZsY3 + GvQ/xVA8/7pyFj6b7Esga60zyGW6LFe9r8n6paHrlG5o + jqf0BaqHT+8= ) +kx01 KX 10 kdc +kx02 KX 10 . +loc01 LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20m 2000m 20m +loc02 LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20m 2000m 20m +loc03 LOC 60 9 0.000 N 24 39 0.000 E 10.00m 90000000.00m 2000m 20m +loc04 LOC 60 9 1.5 N 24 39 0.000 E 10.00m 20m 2000m 20m +loc05 LOC 60 9 1.51 N 24 39 0.000 E 10.00m 20m 2000m 20m +;; +;; XXXRTH These are all obsolete and unused. dnspython doesn't implement +;; them +;;mb01 MG madname +;;mb02 MG . +;;mg01 MG mgmname +;;mg02 MG . +;;minfo01 MINFO rmailbx emailbx +;;minfo02 MINFO . . +;;mr01 MR mrname +;;mr02 MR . +mx01 MX 10 mail +mx02 MX 10 . +naptr01 NAPTR 0 0 "" "" "" . +naptr02 NAPTR 65535 65535 "blurgh" "blorf" "blegh" foo. +nsap-ptr01 NSAP-PTR foo. + NSAP-PTR . +nsap01 NSAP 0x47000580005a0000000001e133ffffff00016100 +nsap02 NSAP 0x47.000580005a0000000001e133ffffff000161.00 +nxt01 NXT a.secure ( NS SOA MX SIG KEY LOC NXT ) +nxt02 NXT . ( NSAP-PTR NXT ) +nxt03 NXT . ( A ) +nxt04 NXT . ( 127 ) +ptr01 PTR example. +px01 PX 65535 foo. bar. +px02 PX 65535 . . +rp01 RP mbox-dname txt-dname +rp02 RP . . +rt01 RT 0 intermediate-host +rt02 RT 65535 . +$TTL 300 ; 5 minutes +s NS ns.s +$ORIGIN s.example. +ns A 73.80.65.49 +$ORIGIN example. +$TTL 3600 ; 1 hour +sig01 SIG NXT 1 3 3600 ( + 20200101000000 20030101000000 2143 foo + MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi + WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl + d80jEeC8aTrO+KKmCaY= ) +srv01 SRV 0 0 0 . +srv02 SRV 65535 65535 65535 old-slow-box.example.com. +$TTL 301 ; 5 minutes 1 second +t A 73.80.65.49 +$TTL 3600 ; 1 hour +txt01 TXT "foo" +txt02 TXT "foo" "bar" +txt03 TXT "foo" +txt04 TXT "foo" "bar" +txt05 TXT "foo bar" +txt06 TXT "foo bar" +txt07 TXT "foo bar" +txt08 TXT "foo\010bar" +txt09 TXT "foo\010bar" +txt10 TXT "foo bar" +txt11 TXT "\"foo\"" +txt12 TXT "\"foo\"" +txt13 TXT foo +$TTL 300 ; 5 minutes +u TXT "txt-not-in-nxt" +$ORIGIN u.example. +a A 73.80.65.49 +b A 73.80.65.49 +$ORIGIN example. +$TTL 3600 ; 1 hour +wks01 WKS 10.0.0.1 6 ( 0 1 2 21 23 ) +wks02 WKS 10.0.0.1 17 ( 0 1 2 53 ) +wks03 WKS 10.0.0.2 6 ( 65535 ) +x2501 X25 "123456789" +dlv01 DLV 12345 3 1 123456789abcdef67890123456789abcdef67890 +ds01 DS 12345 3 1 123456789abcdef67890123456789abcdef67890 +apl01 APL 1:192.168.32.0/21 !1:192.168.38.0/28 +apl02 APL 1:224.0.0.0/4 2:FF00:0:0:0:0:0:0:0/8 +unknown2 TYPE999 \# 8 0a0000010a000001 +rrsig01 RRSIG NSEC 1 3 3600 20200101000000 20030101000000 2143 foo MxFcby9k/yvedMfQgKzhH5er0Mu/ vILz45IkskceFGgiWCn/GxHhai6V AuHAoNUz4YoU1tVfSCSqQYn6//11 U6Nld80jEeC8aTrO+KKmCaY= +nsec01 NSEC a.secure. A MX RRSIG NSEC TYPE1234 +nsec02 NSEC . NSAP-PTR NSEC +nsec03 NSEC . NSEC TYPE65535 +dnskey01 DNSKEY 512 255 1 ( + AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aR + yzWZriO6i2odGWWQVucZqKVsENW91IOW4vqudngPZsY3 + GvQ/xVA8/7pyFj6b7Esga60zyGW6LFe9r8n6paHrlG5o + jqf0BaqHT+8= ) +dnskey02 DNSKEY HOST|FLAG4 DNSSEC RSAMD5 ( + AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aR + yzWZriO6i2odGWWQVucZqKVsENW91IOW4vqudngPZsY3 + GvQ/xVA8/7pyFj6b7Esga60zyGW6LFe9r8n6paHrlG5o + jqf0BaqHT+8= ) +; +; test known type using unknown RR syntax +; +unknown3 A \# 4 7f000002 +sshfp1 SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab +spf SPF "v=spf1 mx -all" +ipseckey01 IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== +ipseckey02 IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== +ipseckey03 IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== +ipseckey04 IPSECKEY 10 2 2 2001:0DB8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== +ipseckey05 IPSECKEY 10 3 2 mygateway2 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== +nsec301 NSEC3 1 1 12 aabbccdd 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG +nsec302 NSEC3 1 1 12 - 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG +nsec3param01 NSEC3PARAM 1 1 12 aabbccdd +nsec3param02 NSEC3PARAM 1 1 12 - +hip01 HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs1.example.com. rvs2 diff --git a/lib/dnspython/tests/example1.good b/lib/dnspython/tests/example1.good new file mode 100644 index 0000000000..ca5ead6379 --- /dev/null +++ b/lib/dnspython/tests/example1.good @@ -0,0 +1,121 @@ +@ 300 IN SOA ns1 hostmaster 1 2000 2000 1814400 3600 +@ 300 IN NS ns1 +@ 300 IN NS ns2 +* 300 IN MX 10 mail +a 300 IN TXT "foo foo foo" +a 300 IN PTR foo.net. +a01 3600 IN A 0.0.0.0 +a02 3600 IN A 255.255.255.255 +aaaa01 3600 IN AAAA ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +aaaa02 3600 IN AAAA ::1 +afsdb01 3600 IN AFSDB 0 hostname +afsdb02 3600 IN AFSDB 65535 . +apl01 3600 IN APL 1:192.168.32.0/21 !1:192.168.38.0/28 +apl02 3600 IN APL 1:224.0.0.0/4 2:FF00:0:0:0:0:0:0:0/8 +b 300 IN CNAME foo.net. +c 300 IN A 73.80.65.49 +cert01 3600 IN CERT 65534 65535 PRIVATEOID MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY= +cname01 3600 IN CNAME cname-target. +cname02 3600 IN CNAME cname-target +cname03 3600 IN CNAME . +d 300 IN A 73.80.65.49 +dhcid01 3600 IN DHCID AAIBY2/AuCccgoJbsaxcQc9TUapptP69 lOjxfNuVAA2kjEA= +dhcid02 3600 IN DHCID AAEBOSD+XR3Os/0LozeXVqcNc7FwCfQd WL3b/NaiUDlW2No= +dhcid03 3600 IN DHCID AAABxLmlskllE0MVjd57zHcWmEH3pCQ6 VytcKD//7es/deY= +dlv01 3600 IN DLV 12345 3 1 123456789abcdef67890123456789abcdef67890 +dname01 3600 IN DNAME dname-target. +dname02 3600 IN DNAME dname-target +dname03 3600 IN DNAME . +dnskey01 3600 IN DNSKEY 512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRu niJDBzC7w0aRyzWZriO6i2odGWWQVucZ qKVsENW91IOW4vqudngPZsY3GvQ/xVA8 /7pyFj6b7Esga60zyGW6LFe9r8n6paHr lG5ojqf0BaqHT+8= +dnskey02 3600 IN DNSKEY 2560 3 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRu niJDBzC7w0aRyzWZriO6i2odGWWQVucZ qKVsENW91IOW4vqudngPZsY3GvQ/xVA8 /7pyFj6b7Esga60zyGW6LFe9r8n6paHr lG5ojqf0BaqHT+8= +ds01 3600 IN DS 12345 3 1 123456789abcdef67890123456789abcdef67890 +e 300 IN MX 10 mail +e 300 IN TXT "one" +e 300 IN TXT "three" +e 300 IN TXT "two" +e 300 IN A 73.80.65.49 +e 300 IN A 73.80.65.50 +e 300 IN A 73.80.65.52 +e 300 IN A 73.80.65.51 +f 300 IN A 73.80.65.52 +gpos01 3600 IN GPOS -22.6882 116.8652 250.0 +hinfo01 3600 IN HINFO "Generic PC clone" "NetBSD-1.4" +hinfo02 3600 IN HINFO "PC" "NetBSD" +hip01 3600 IN HIP 2 200100107b1a74df365639cc39f1d578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs1.example.com. rvs2 +ipseckey01 3600 IN IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ== +ipseckey02 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ== +ipseckey03 3600 IN IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ== +ipseckey04 3600 IN IPSECKEY 10 2 2 2001:0DB8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ== +ipseckey05 3600 IN IPSECKEY 10 3 2 mygateway2 AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ== +isdn01 3600 IN ISDN "isdn-address" +isdn02 3600 IN ISDN "isdn-address" "subaddress" +isdn03 3600 IN ISDN "isdn-address" +isdn04 3600 IN ISDN "isdn-address" "subaddress" +key01 3600 IN KEY 512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRu niJDBzC7w0aRyzWZriO6i2odGWWQVucZ qKVsENW91IOW4vqudngPZsY3GvQ/xVA8 /7pyFj6b7Esga60zyGW6LFe9r8n6paHr lG5ojqf0BaqHT+8= +key02 3600 IN KEY 2560 3 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRu niJDBzC7w0aRyzWZriO6i2odGWWQVucZ qKVsENW91IOW4vqudngPZsY3GvQ/xVA8 /7pyFj6b7Esga60zyGW6LFe9r8n6paHr lG5ojqf0BaqHT+8= +kx01 3600 IN KX 10 kdc +kx02 3600 IN KX 10 . +loc01 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +loc02 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +loc03 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 90000000.00m 2000.00m 20.00m +loc04 3600 IN LOC 60 9 1.500 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +loc05 3600 IN LOC 60 9 1.510 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +mx01 3600 IN MX 10 mail +mx02 3600 IN MX 10 . +naptr01 3600 IN NAPTR 0 0 "" "" "" . +naptr02 3600 IN NAPTR 65535 65535 "blurgh" "blorf" "blegh" foo. +ns1 300 IN A 10.53.0.1 +ns2 300 IN A 10.53.0.2 +nsap-ptr01 3600 IN NSAP-PTR foo. +nsap-ptr01 3600 IN NSAP-PTR . +nsap01 3600 IN NSAP 0x47000580005a0000000001e133ffffff00016100 +nsap02 3600 IN NSAP 0x47000580005a0000000001e133ffffff00016100 +nsec01 3600 IN NSEC a.secure. A MX RRSIG NSEC TYPE1234 +nsec02 3600 IN NSEC . NSAP-PTR NSEC +nsec03 3600 IN NSEC . NSEC TYPE65535 +nsec301 3600 IN NSEC3 1 1 12 aabbccdd 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS SOA MX RRSIG DNSKEY NSEC3PARAM +nsec302 3600 IN NSEC3 1 1 12 - 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS SOA MX RRSIG DNSKEY NSEC3PARAM +nsec3param01 3600 IN NSEC3PARAM 1 1 12 aabbccdd +nsec3param02 3600 IN NSEC3PARAM 1 1 12 - +nxt01 3600 IN NXT a.secure NS SOA MX SIG KEY LOC NXT +nxt02 3600 IN NXT . NSAP-PTR NXT +nxt03 3600 IN NXT . A +nxt04 3600 IN NXT . TYPE127 +ptr01 3600 IN PTR @ +px01 3600 IN PX 65535 foo. bar. +px02 3600 IN PX 65535 . . +rp01 3600 IN RP mbox-dname txt-dname +rp02 3600 IN RP . . +rrsig01 3600 IN RRSIG NSEC 1 3 3600 20200101000000 20030101000000 2143 foo MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY= +rt01 3600 IN RT 0 intermediate-host +rt02 3600 IN RT 65535 . +s 300 IN NS ns.s +ns.s 300 IN A 73.80.65.49 +sig01 3600 IN SIG NXT 1 3 3600 20200101000000 20030101000000 2143 foo MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY= +spf 3600 IN SPF "v=spf1 mx -all" +srv01 3600 IN SRV 0 0 0 . +srv02 3600 IN SRV 65535 65535 65535 old-slow-box.example.com. +sshfp1 3600 IN SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab +t 301 IN A 73.80.65.49 +txt01 3600 IN TXT "foo" +txt02 3600 IN TXT "foo" "bar" +txt03 3600 IN TXT "foo" +txt04 3600 IN TXT "foo" "bar" +txt05 3600 IN TXT "foo bar" +txt06 3600 IN TXT "foo bar" +txt07 3600 IN TXT "foo bar" +txt08 3600 IN TXT "foo\010bar" +txt09 3600 IN TXT "foo\010bar" +txt10 3600 IN TXT "foo bar" +txt11 3600 IN TXT "\"foo\"" +txt12 3600 IN TXT "\"foo\"" +txt13 3600 IN TXT "foo" +u 300 IN TXT "txt-not-in-nxt" +a.u 300 IN A 73.80.65.49 +b.u 300 IN A 73.80.65.49 +unknown2 3600 IN TYPE999 \# 8 0a0000010a000001 +unknown3 3600 IN A 127.0.0.2 +wks01 3600 IN WKS 10.0.0.1 6 0 1 2 21 23 +wks02 3600 IN WKS 10.0.0.1 17 0 1 2 53 +wks03 3600 IN WKS 10.0.0.2 6 65535 +x2501 3600 IN X25 "123456789" diff --git a/lib/dnspython/tests/example2.good b/lib/dnspython/tests/example2.good new file mode 100644 index 0000000000..c923c09b7c --- /dev/null +++ b/lib/dnspython/tests/example2.good @@ -0,0 +1,121 @@ +example. 300 IN SOA ns1.example. hostmaster.example. 1 2000 2000 1814400 3600 +example. 300 IN NS ns1.example. +example. 300 IN NS ns2.example. +*.example. 300 IN MX 10 mail.example. +a.example. 300 IN TXT "foo foo foo" +a.example. 300 IN PTR foo.net. +a01.example. 3600 IN A 0.0.0.0 +a02.example. 3600 IN A 255.255.255.255 +aaaa01.example. 3600 IN AAAA ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +aaaa02.example. 3600 IN AAAA ::1 +afsdb01.example. 3600 IN AFSDB 0 hostname.example. +afsdb02.example. 3600 IN AFSDB 65535 . +apl01.example. 3600 IN APL 1:192.168.32.0/21 !1:192.168.38.0/28 +apl02.example. 3600 IN APL 1:224.0.0.0/4 2:FF00:0:0:0:0:0:0:0/8 +b.example. 300 IN CNAME foo.net. +c.example. 300 IN A 73.80.65.49 +cert01.example. 3600 IN CERT 65534 65535 PRIVATEOID MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY= +cname01.example. 3600 IN CNAME cname-target. +cname02.example. 3600 IN CNAME cname-target.example. +cname03.example. 3600 IN CNAME . +d.example. 300 IN A 73.80.65.49 +dhcid01.example. 3600 IN DHCID AAIBY2/AuCccgoJbsaxcQc9TUapptP69 lOjxfNuVAA2kjEA= +dhcid02.example. 3600 IN DHCID AAEBOSD+XR3Os/0LozeXVqcNc7FwCfQd WL3b/NaiUDlW2No= +dhcid03.example. 3600 IN DHCID AAABxLmlskllE0MVjd57zHcWmEH3pCQ6 VytcKD//7es/deY= +dlv01.example. 3600 IN DLV 12345 3 1 123456789abcdef67890123456789abcdef67890 +dname01.example. 3600 IN DNAME dname-target. +dname02.example. 3600 IN DNAME dname-target.example. +dname03.example. 3600 IN DNAME . +dnskey01.example. 3600 IN DNSKEY 512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRu niJDBzC7w0aRyzWZriO6i2odGWWQVucZ qKVsENW91IOW4vqudngPZsY3GvQ/xVA8 /7pyFj6b7Esga60zyGW6LFe9r8n6paHr lG5ojqf0BaqHT+8= +dnskey02.example. 3600 IN DNSKEY 2560 3 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRu niJDBzC7w0aRyzWZriO6i2odGWWQVucZ qKVsENW91IOW4vqudngPZsY3GvQ/xVA8 /7pyFj6b7Esga60zyGW6LFe9r8n6paHr lG5ojqf0BaqHT+8= +ds01.example. 3600 IN DS 12345 3 1 123456789abcdef67890123456789abcdef67890 +e.example. 300 IN MX 10 mail.example. +e.example. 300 IN TXT "one" +e.example. 300 IN TXT "three" +e.example. 300 IN TXT "two" +e.example. 300 IN A 73.80.65.49 +e.example. 300 IN A 73.80.65.50 +e.example. 300 IN A 73.80.65.52 +e.example. 300 IN A 73.80.65.51 +f.example. 300 IN A 73.80.65.52 +gpos01.example. 3600 IN GPOS -22.6882 116.8652 250.0 +hinfo01.example. 3600 IN HINFO "Generic PC clone" "NetBSD-1.4" +hinfo02.example. 3600 IN HINFO "PC" "NetBSD" +hip01.example. 3600 IN HIP 2 200100107b1a74df365639cc39f1d578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs1.example.com. rvs2.example. +ipseckey01.example. 3600 IN IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ== +ipseckey02.example. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ== +ipseckey03.example. 3600 IN IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ== +ipseckey04.example. 3600 IN IPSECKEY 10 2 2 2001:0DB8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ== +ipseckey05.example. 3600 IN IPSECKEY 10 3 2 mygateway2.example. AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ== +isdn01.example. 3600 IN ISDN "isdn-address" +isdn02.example. 3600 IN ISDN "isdn-address" "subaddress" +isdn03.example. 3600 IN ISDN "isdn-address" +isdn04.example. 3600 IN ISDN "isdn-address" "subaddress" +key01.example. 3600 IN KEY 512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRu niJDBzC7w0aRyzWZriO6i2odGWWQVucZ qKVsENW91IOW4vqudngPZsY3GvQ/xVA8 /7pyFj6b7Esga60zyGW6LFe9r8n6paHr lG5ojqf0BaqHT+8= +key02.example. 3600 IN KEY 2560 3 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRu niJDBzC7w0aRyzWZriO6i2odGWWQVucZ qKVsENW91IOW4vqudngPZsY3GvQ/xVA8 /7pyFj6b7Esga60zyGW6LFe9r8n6paHr lG5ojqf0BaqHT+8= +kx01.example. 3600 IN KX 10 kdc.example. +kx02.example. 3600 IN KX 10 . +loc01.example. 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +loc02.example. 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +loc03.example. 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 90000000.00m 2000.00m 20.00m +loc04.example. 3600 IN LOC 60 9 1.500 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +loc05.example. 3600 IN LOC 60 9 1.510 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +mx01.example. 3600 IN MX 10 mail.example. +mx02.example. 3600 IN MX 10 . +naptr01.example. 3600 IN NAPTR 0 0 "" "" "" . +naptr02.example. 3600 IN NAPTR 65535 65535 "blurgh" "blorf" "blegh" foo. +ns1.example. 300 IN A 10.53.0.1 +ns2.example. 300 IN A 10.53.0.2 +nsap-ptr01.example. 3600 IN NSAP-PTR foo. +nsap-ptr01.example. 3600 IN NSAP-PTR . +nsap01.example. 3600 IN NSAP 0x47000580005a0000000001e133ffffff00016100 +nsap02.example. 3600 IN NSAP 0x47000580005a0000000001e133ffffff00016100 +nsec01.example. 3600 IN NSEC a.secure. A MX RRSIG NSEC TYPE1234 +nsec02.example. 3600 IN NSEC . NSAP-PTR NSEC +nsec03.example. 3600 IN NSEC . NSEC TYPE65535 +nsec301.example. 3600 IN NSEC3 1 1 12 aabbccdd 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS SOA MX RRSIG DNSKEY NSEC3PARAM +nsec302.example. 3600 IN NSEC3 1 1 12 - 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS SOA MX RRSIG DNSKEY NSEC3PARAM +nsec3param01.example. 3600 IN NSEC3PARAM 1 1 12 aabbccdd +nsec3param02.example. 3600 IN NSEC3PARAM 1 1 12 - +nxt01.example. 3600 IN NXT a.secure.example. NS SOA MX SIG KEY LOC NXT +nxt02.example. 3600 IN NXT . NSAP-PTR NXT +nxt03.example. 3600 IN NXT . A +nxt04.example. 3600 IN NXT . TYPE127 +ptr01.example. 3600 IN PTR example. +px01.example. 3600 IN PX 65535 foo. bar. +px02.example. 3600 IN PX 65535 . . +rp01.example. 3600 IN RP mbox-dname.example. txt-dname.example. +rp02.example. 3600 IN RP . . +rrsig01.example. 3600 IN RRSIG NSEC 1 3 3600 20200101000000 20030101000000 2143 foo.example. MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY= +rt01.example. 3600 IN RT 0 intermediate-host.example. +rt02.example. 3600 IN RT 65535 . +s.example. 300 IN NS ns.s.example. +ns.s.example. 300 IN A 73.80.65.49 +sig01.example. 3600 IN SIG NXT 1 3 3600 20200101000000 20030101000000 2143 foo.example. MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY= +spf.example. 3600 IN SPF "v=spf1 mx -all" +srv01.example. 3600 IN SRV 0 0 0 . +srv02.example. 3600 IN SRV 65535 65535 65535 old-slow-box.example.com. +sshfp1.example. 3600 IN SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab +t.example. 301 IN A 73.80.65.49 +txt01.example. 3600 IN TXT "foo" +txt02.example. 3600 IN TXT "foo" "bar" +txt03.example. 3600 IN TXT "foo" +txt04.example. 3600 IN TXT "foo" "bar" +txt05.example. 3600 IN TXT "foo bar" +txt06.example. 3600 IN TXT "foo bar" +txt07.example. 3600 IN TXT "foo bar" +txt08.example. 3600 IN TXT "foo\010bar" +txt09.example. 3600 IN TXT "foo\010bar" +txt10.example. 3600 IN TXT "foo bar" +txt11.example. 3600 IN TXT "\"foo\"" +txt12.example. 3600 IN TXT "\"foo\"" +txt13.example. 3600 IN TXT "foo" +u.example. 300 IN TXT "txt-not-in-nxt" +a.u.example. 300 IN A 73.80.65.49 +b.u.example. 300 IN A 73.80.65.49 +unknown2.example. 3600 IN TYPE999 \# 8 0a0000010a000001 +unknown3.example. 3600 IN A 127.0.0.2 +wks01.example. 3600 IN WKS 10.0.0.1 6 0 1 2 21 23 +wks02.example. 3600 IN WKS 10.0.0.1 17 0 1 2 53 +wks03.example. 3600 IN WKS 10.0.0.2 6 65535 +x2501.example. 3600 IN X25 "123456789" diff --git a/lib/dnspython/tests/flags.py b/lib/dnspython/tests/flags.py new file mode 100644 index 0000000000..7ee2d8e12e --- /dev/null +++ b/lib/dnspython/tests/flags.py @@ -0,0 +1,59 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import unittest + +import dns.flags +import dns.rcode +import dns.opcode + +class FlagsTestCase(unittest.TestCase): + + def test_rcode1(self): + self.failUnless(dns.rcode.from_text('FORMERR') == dns.rcode.FORMERR) + + def test_rcode2(self): + self.failUnless(dns.rcode.to_text(dns.rcode.FORMERR) == "FORMERR") + + def test_rcode3(self): + self.failUnless(dns.rcode.to_flags(dns.rcode.FORMERR) == (1, 0)) + + def test_rcode4(self): + self.failUnless(dns.rcode.to_flags(dns.rcode.BADVERS) == \ + (0, 0x01000000)) + + def test_rcode6(self): + self.failUnless(dns.rcode.from_flags(0, 0x01000000) == \ + dns.rcode.BADVERS) + + def test_rcode6(self): + self.failUnless(dns.rcode.from_flags(5, 0) == dns.rcode.REFUSED) + + def test_rcode7(self): + def bad(): + dns.rcode.to_flags(4096) + self.failUnlessRaises(ValueError, bad) + + def test_flags1(self): + self.failUnless(dns.flags.from_text("RA RD AA QR") == \ + dns.flags.QR|dns.flags.AA|dns.flags.RD|dns.flags.RA) + + def test_flags2(self): + flags = dns.flags.QR|dns.flags.AA|dns.flags.RD|dns.flags.RA + self.failUnless(dns.flags.to_text(flags) == "QR AA RD RA") + + +if __name__ == '__main__': + unittest.main() diff --git a/lib/dnspython/tests/message.py b/lib/dnspython/tests/message.py new file mode 100644 index 0000000000..7134661d3a --- /dev/null +++ b/lib/dnspython/tests/message.py @@ -0,0 +1,179 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import cStringIO +import os +import unittest + +import dns.exception +import dns.message + +query_text = """id 1234 +opcode QUERY +rcode NOERROR +flags RD +edns 0 +eflags DO +payload 4096 +;QUESTION +wwww.dnspython.org. IN A +;ANSWER +;AUTHORITY +;ADDITIONAL""" + +goodhex = '04d201000001000000000001047777777709646e73707974686f6e' \ + '036f726700000100010000291000000080000000' + +goodwire = goodhex.decode('hex_codec') + +answer_text = """id 1234 +opcode QUERY +rcode NOERROR +flags QR AA RD +;QUESTION +dnspython.org. IN SOA +;ANSWER +dnspython.org. 3600 IN SOA woof.dnspython.org. hostmaster.dnspython.org. 2003052700 3600 1800 604800 3600 +;AUTHORITY +dnspython.org. 3600 IN NS ns1.staff.nominum.org. +dnspython.org. 3600 IN NS ns2.staff.nominum.org. +dnspython.org. 3600 IN NS woof.play-bow.org. +;ADDITIONAL +woof.play-bow.org. 3600 IN A 204.152.186.150 +""" + +goodhex2 = '04d2 8500 0001 0001 0003 0001' \ + '09646e73707974686f6e036f726700 0006 0001' \ + 'c00c 0006 0001 00000e10 0028 ' \ + '04776f6f66c00c 0a686f73746d6173746572c00c' \ + '7764289c 00000e10 00000708 00093a80 00000e10' \ + 'c00c 0002 0001 00000e10 0014' \ + '036e7331057374616666076e6f6d696e756dc016' \ + 'c00c 0002 0001 00000e10 0006 036e7332c063' \ + 'c00c 0002 0001 00000e10 0010 04776f6f6608706c61792d626f77c016' \ + 'c091 0001 0001 00000e10 0004 cc98ba96' + + +goodwire2 = goodhex2.replace(' ', '').decode('hex_codec') + +query_text_2 = """id 1234 +opcode QUERY +rcode 4095 +flags RD +edns 0 +eflags DO +payload 4096 +;QUESTION +wwww.dnspython.org. IN A +;ANSWER +;AUTHORITY +;ADDITIONAL""" + +goodhex3 = '04d2010f0001000000000001047777777709646e73707974686f6e' \ + '036f726700000100010000291000ff0080000000' + +goodwire3 = goodhex3.decode('hex_codec') + +class MessageTestCase(unittest.TestCase): + + def test_comparison_eq1(self): + q1 = dns.message.from_text(query_text) + q2 = dns.message.from_text(query_text) + self.failUnless(q1 == q2) + + def test_comparison_ne1(self): + q1 = dns.message.from_text(query_text) + q2 = dns.message.from_text(query_text) + q2.id = 10 + self.failUnless(q1 != q2) + + def test_comparison_ne2(self): + q1 = dns.message.from_text(query_text) + q2 = dns.message.from_text(query_text) + q2.question = [] + self.failUnless(q1 != q2) + + def test_comparison_ne3(self): + q1 = dns.message.from_text(query_text) + self.failUnless(q1 != 1) + + def test_EDNS_to_wire1(self): + q = dns.message.from_text(query_text) + w = q.to_wire() + self.failUnless(w == goodwire) + + def test_EDNS_from_wire1(self): + m = dns.message.from_wire(goodwire) + self.failUnless(str(m) == query_text) + + def test_EDNS_to_wire2(self): + q = dns.message.from_text(query_text_2) + w = q.to_wire() + self.failUnless(w == goodwire3) + + def test_EDNS_from_wire2(self): + m = dns.message.from_wire(goodwire3) + self.failUnless(str(m) == query_text_2) + + def test_TooBig(self): + def bad(): + q = dns.message.from_text(query_text) + for i in xrange(0, 25): + rrset = dns.rrset.from_text('foo%d.' % i, 3600, + dns.rdataclass.IN, + dns.rdatatype.A, + '10.0.0.%d' % i) + q.additional.append(rrset) + w = q.to_wire(max_size=512) + self.failUnlessRaises(dns.exception.TooBig, bad) + + def test_answer1(self): + a = dns.message.from_text(answer_text) + wire = a.to_wire(want_shuffle=False) + self.failUnless(wire == goodwire2) + + def test_TrailingJunk(self): + def bad(): + badwire = goodwire + '\x00' + m = dns.message.from_wire(badwire) + self.failUnlessRaises(dns.message.TrailingJunk, bad) + + def test_ShortHeader(self): + def bad(): + badwire = '\x00' * 11 + m = dns.message.from_wire(badwire) + self.failUnlessRaises(dns.message.ShortHeader, bad) + + def test_RespondingToResponse(self): + def bad(): + q = dns.message.make_query('foo', 'A') + r1 = dns.message.make_response(q) + r2 = dns.message.make_response(r1) + self.failUnlessRaises(dns.exception.FormError, bad) + + def test_ExtendedRcodeSetting(self): + m = dns.message.make_query('foo', 'A') + m.set_rcode(4095) + self.failUnless(m.rcode() == 4095) + m.set_rcode(2) + self.failUnless(m.rcode() == 2) + + def test_EDNSVersionCoherence(self): + m = dns.message.make_query('foo', 'A') + m.use_edns(1) + self.failUnless((m.ednsflags >> 16) & 0xFF == 1) + +if __name__ == '__main__': + unittest.main() diff --git a/lib/dnspython/tests/name.py b/lib/dnspython/tests/name.py new file mode 100644 index 0000000000..a53ef9eac6 --- /dev/null +++ b/lib/dnspython/tests/name.py @@ -0,0 +1,697 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import unittest + +import cStringIO +import socket + +import dns.name +import dns.reversename +import dns.e164 + +class NameTestCase(unittest.TestCase): + def setUp(self): + self.origin = dns.name.from_text('example.') + + def testFromTextRel1(self): + n = dns.name.from_text('foo.bar') + self.failUnless(n.labels == ('foo', 'bar', '')) + + def testFromTextRel2(self): + n = dns.name.from_text('foo.bar', origin=self.origin) + self.failUnless(n.labels == ('foo', 'bar', 'example', '')) + + def testFromTextRel3(self): + n = dns.name.from_text('foo.bar', origin=None) + self.failUnless(n.labels == ('foo', 'bar')) + + def testFromTextRel4(self): + n = dns.name.from_text('@', origin=None) + self.failUnless(n == dns.name.empty) + + def testFromTextRel5(self): + n = dns.name.from_text('@', origin=self.origin) + self.failUnless(n == self.origin) + + def testFromTextAbs1(self): + n = dns.name.from_text('foo.bar.') + self.failUnless(n.labels == ('foo', 'bar', '')) + + def testTortureFromText(self): + good = [ + r'.', + r'a', + r'a.', + r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + r'\000.\008.\010.\032.\046.\092.\099.\255', + r'\\', + r'\..\.', + r'\\.\\', + r'!"#%&/()=+-', + r'\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255', + ] + bad = [ + r'..', + r'.a', + r'\\..', + '\\', # yes, we don't want the 'r' prefix! + r'\0', + r'\00', + r'\00Z', + r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + r'\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255', + ] + for t in good: + try: + n = dns.name.from_text(t) + except: + self.fail("good test '%s' raised an exception" % t) + for t in bad: + caught = False + try: + n = dns.name.from_text(t) + except: + caught = True + if not caught: + self.fail("bad test '%s' did not raise an exception" % t) + + def testImmutable1(self): + def bad(): + self.origin.labels = () + self.failUnlessRaises(TypeError, bad) + + def testImmutable2(self): + def bad(): + self.origin.labels[0] = 'foo' + self.failUnlessRaises(TypeError, bad) + + def testAbs1(self): + self.failUnless(dns.name.root.is_absolute()) + + def testAbs2(self): + self.failUnless(not dns.name.empty.is_absolute()) + + def testAbs3(self): + self.failUnless(self.origin.is_absolute()) + + def testAbs3(self): + n = dns.name.from_text('foo', origin=None) + self.failUnless(not n.is_absolute()) + + def testWild1(self): + n = dns.name.from_text('*.foo', origin=None) + self.failUnless(n.is_wild()) + + def testWild2(self): + n = dns.name.from_text('*a.foo', origin=None) + self.failUnless(not n.is_wild()) + + def testWild3(self): + n = dns.name.from_text('a.*.foo', origin=None) + self.failUnless(not n.is_wild()) + + def testWild4(self): + self.failUnless(not dns.name.root.is_wild()) + + def testWild5(self): + self.failUnless(not dns.name.empty.is_wild()) + + def testHash1(self): + n1 = dns.name.from_text('fOo.COM') + n2 = dns.name.from_text('foo.com') + self.failUnless(hash(n1) == hash(n2)) + + def testCompare1(self): + n1 = dns.name.from_text('a') + n2 = dns.name.from_text('b') + self.failUnless(n1 < n2) + self.failUnless(n2 > n1) + + def testCompare2(self): + n1 = dns.name.from_text('') + n2 = dns.name.from_text('b') + self.failUnless(n1 < n2) + self.failUnless(n2 > n1) + + def testCompare3(self): + self.failUnless(dns.name.empty < dns.name.root) + self.failUnless(dns.name.root > dns.name.empty) + + def testCompare4(self): + self.failUnless(dns.name.root != 1) + + def testCompare5(self): + self.failUnless(dns.name.root < 1 or dns.name.root > 1) + + def testSubdomain1(self): + self.failUnless(not dns.name.empty.is_subdomain(dns.name.root)) + + def testSubdomain2(self): + self.failUnless(not dns.name.root.is_subdomain(dns.name.empty)) + + def testSubdomain3(self): + n = dns.name.from_text('foo', origin=self.origin) + self.failUnless(n.is_subdomain(self.origin)) + + def testSubdomain4(self): + n = dns.name.from_text('foo', origin=self.origin) + self.failUnless(n.is_subdomain(dns.name.root)) + + def testSubdomain5(self): + n = dns.name.from_text('foo', origin=self.origin) + self.failUnless(n.is_subdomain(n)) + + def testSuperdomain1(self): + self.failUnless(not dns.name.empty.is_superdomain(dns.name.root)) + + def testSuperdomain2(self): + self.failUnless(not dns.name.root.is_superdomain(dns.name.empty)) + + def testSuperdomain3(self): + n = dns.name.from_text('foo', origin=self.origin) + self.failUnless(self.origin.is_superdomain(n)) + + def testSuperdomain4(self): + n = dns.name.from_text('foo', origin=self.origin) + self.failUnless(dns.name.root.is_superdomain(n)) + + def testSuperdomain5(self): + n = dns.name.from_text('foo', origin=self.origin) + self.failUnless(n.is_superdomain(n)) + + def testCanonicalize1(self): + n = dns.name.from_text('FOO.bar', origin=self.origin) + c = n.canonicalize() + self.failUnless(c.labels == ('foo', 'bar', 'example', '')) + + def testToText1(self): + n = dns.name.from_text('FOO.bar', origin=self.origin) + t = n.to_text() + self.failUnless(t == 'FOO.bar.example.') + + def testToText2(self): + n = dns.name.from_text('FOO.bar', origin=self.origin) + t = n.to_text(True) + self.failUnless(t == 'FOO.bar.example') + + def testToText3(self): + n = dns.name.from_text('FOO.bar', origin=None) + t = n.to_text() + self.failUnless(t == 'FOO.bar') + + def testToText4(self): + t = dns.name.empty.to_text() + self.failUnless(t == '@') + + def testToText5(self): + t = dns.name.root.to_text() + self.failUnless(t == '.') + + def testToText6(self): + n = dns.name.from_text('FOO bar', origin=None) + t = n.to_text() + self.failUnless(t == r'FOO\032bar') + + def testToText7(self): + n = dns.name.from_text(r'FOO\.bar', origin=None) + t = n.to_text() + self.failUnless(t == r'FOO\.bar') + + def testToText8(self): + n = dns.name.from_text(r'\070OO\.bar', origin=None) + t = n.to_text() + self.failUnless(t == r'FOO\.bar') + + def testSlice1(self): + n = dns.name.from_text(r'a.b.c.', origin=None) + s = n[:] + self.failUnless(s == ('a', 'b', 'c', '')) + + def testSlice2(self): + n = dns.name.from_text(r'a.b.c.', origin=None) + s = n[:2] + self.failUnless(s == ('a', 'b')) + + def testSlice3(self): + n = dns.name.from_text(r'a.b.c.', origin=None) + s = n[2:] + self.failUnless(s == ('c', '')) + + def testEmptyLabel1(self): + def bad(): + n = dns.name.Name(['a', '', 'b']) + self.failUnlessRaises(dns.name.EmptyLabel, bad) + + def testEmptyLabel2(self): + def bad(): + n = dns.name.Name(['', 'b']) + self.failUnlessRaises(dns.name.EmptyLabel, bad) + + def testEmptyLabel3(self): + n = dns.name.Name(['b', '']) + self.failUnless(n) + + def testLongLabel(self): + n = dns.name.Name(['a' * 63]) + self.failUnless(n) + + def testLabelTooLong(self): + def bad(): + n = dns.name.Name(['a' * 64, 'b']) + self.failUnlessRaises(dns.name.LabelTooLong, bad) + + def testLongName(self): + n = dns.name.Name(['a' * 63, 'a' * 63, 'a' * 63, 'a' * 62]) + self.failUnless(n) + + def testNameTooLong(self): + def bad(): + n = dns.name.Name(['a' * 63, 'a' * 63, 'a' * 63, 'a' * 63]) + self.failUnlessRaises(dns.name.NameTooLong, bad) + + def testConcat1(self): + n1 = dns.name.Name(['a', 'b']) + n2 = dns.name.Name(['c', 'd']) + e = dns.name.Name(['a', 'b', 'c', 'd']) + r = n1 + n2 + self.failUnless(r == e) + + def testConcat2(self): + n1 = dns.name.Name(['a', 'b']) + n2 = dns.name.Name([]) + e = dns.name.Name(['a', 'b']) + r = n1 + n2 + self.failUnless(r == e) + + def testConcat2(self): + n1 = dns.name.Name([]) + n2 = dns.name.Name(['a', 'b']) + e = dns.name.Name(['a', 'b']) + r = n1 + n2 + self.failUnless(r == e) + + def testConcat3(self): + n1 = dns.name.Name(['a', 'b', '']) + n2 = dns.name.Name([]) + e = dns.name.Name(['a', 'b', '']) + r = n1 + n2 + self.failUnless(r == e) + + def testConcat4(self): + n1 = dns.name.Name(['a', 'b']) + n2 = dns.name.Name(['c', '']) + e = dns.name.Name(['a', 'b', 'c', '']) + r = n1 + n2 + self.failUnless(r == e) + + def testConcat5(self): + def bad(): + n1 = dns.name.Name(['a', 'b', '']) + n2 = dns.name.Name(['c']) + r = n1 + n2 + self.failUnlessRaises(dns.name.AbsoluteConcatenation, bad) + + def testBadEscape(self): + def bad(): + n = dns.name.from_text(r'a.b\0q1.c.') + print n + self.failUnlessRaises(dns.name.BadEscape, bad) + + def testDigestable1(self): + n = dns.name.from_text('FOO.bar') + d = n.to_digestable() + self.failUnless(d == '\x03foo\x03bar\x00') + + def testDigestable2(self): + n1 = dns.name.from_text('FOO.bar') + n2 = dns.name.from_text('foo.BAR.') + d1 = n1.to_digestable() + d2 = n2.to_digestable() + self.failUnless(d1 == d2) + + def testDigestable3(self): + d = dns.name.root.to_digestable() + self.failUnless(d == '\x00') + + def testDigestable4(self): + n = dns.name.from_text('FOO.bar', None) + d = n.to_digestable(dns.name.root) + self.failUnless(d == '\x03foo\x03bar\x00') + + def testBadDigestable(self): + def bad(): + n = dns.name.from_text('FOO.bar', None) + d = n.to_digestable() + self.failUnlessRaises(dns.name.NeedAbsoluteNameOrOrigin, bad) + + def testToWire1(self): + n = dns.name.from_text('FOO.bar') + f = cStringIO.StringIO() + compress = {} + n.to_wire(f, compress) + self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00') + + def testToWire2(self): + n = dns.name.from_text('FOO.bar') + f = cStringIO.StringIO() + compress = {} + n.to_wire(f, compress) + n.to_wire(f, compress) + self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\xc0\x00') + + def testToWire3(self): + n1 = dns.name.from_text('FOO.bar') + n2 = dns.name.from_text('foo.bar') + f = cStringIO.StringIO() + compress = {} + n1.to_wire(f, compress) + n2.to_wire(f, compress) + self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\xc0\x00') + + def testToWire4(self): + n1 = dns.name.from_text('FOO.bar') + n2 = dns.name.from_text('a.foo.bar') + f = cStringIO.StringIO() + compress = {} + n1.to_wire(f, compress) + n2.to_wire(f, compress) + self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\x01\x61\xc0\x00') + + def testToWire5(self): + n1 = dns.name.from_text('FOO.bar') + n2 = dns.name.from_text('a.foo.bar') + f = cStringIO.StringIO() + compress = {} + n1.to_wire(f, compress) + n2.to_wire(f, None) + self.failUnless(f.getvalue() == \ + '\x03FOO\x03bar\x00\x01\x61\x03foo\x03bar\x00') + + def testToWire6(self): + n = dns.name.from_text('FOO.bar') + v = n.to_wire() + self.failUnless(v == '\x03FOO\x03bar\x00') + + def testBadToWire(self): + def bad(): + n = dns.name.from_text('FOO.bar', None) + f = cStringIO.StringIO() + compress = {} + n.to_wire(f, compress) + self.failUnlessRaises(dns.name.NeedAbsoluteNameOrOrigin, bad) + + def testSplit1(self): + n = dns.name.from_text('foo.bar.') + (prefix, suffix) = n.split(2) + ep = dns.name.from_text('foo', None) + es = dns.name.from_text('bar.', None) + self.failUnless(prefix == ep and suffix == es) + + def testSplit2(self): + n = dns.name.from_text('foo.bar.') + (prefix, suffix) = n.split(1) + ep = dns.name.from_text('foo.bar', None) + es = dns.name.from_text('.', None) + self.failUnless(prefix == ep and suffix == es) + + def testSplit3(self): + n = dns.name.from_text('foo.bar.') + (prefix, suffix) = n.split(0) + ep = dns.name.from_text('foo.bar.', None) + es = dns.name.from_text('', None) + self.failUnless(prefix == ep and suffix == es) + + def testSplit4(self): + n = dns.name.from_text('foo.bar.') + (prefix, suffix) = n.split(3) + ep = dns.name.from_text('', None) + es = dns.name.from_text('foo.bar.', None) + self.failUnless(prefix == ep and suffix == es) + + def testBadSplit1(self): + def bad(): + n = dns.name.from_text('foo.bar.') + (prefix, suffix) = n.split(-1) + self.failUnlessRaises(ValueError, bad) + + def testBadSplit2(self): + def bad(): + n = dns.name.from_text('foo.bar.') + (prefix, suffix) = n.split(4) + self.failUnlessRaises(ValueError, bad) + + def testRelativize1(self): + n = dns.name.from_text('a.foo.bar.', None) + o = dns.name.from_text('bar.', None) + e = dns.name.from_text('a.foo', None) + self.failUnless(n.relativize(o) == e) + + def testRelativize2(self): + n = dns.name.from_text('a.foo.bar.', None) + o = n + e = dns.name.empty + self.failUnless(n.relativize(o) == e) + + def testRelativize3(self): + n = dns.name.from_text('a.foo.bar.', None) + o = dns.name.from_text('blaz.', None) + e = n + self.failUnless(n.relativize(o) == e) + + def testRelativize4(self): + n = dns.name.from_text('a.foo', None) + o = dns.name.root + e = n + self.failUnless(n.relativize(o) == e) + + def testDerelativize1(self): + n = dns.name.from_text('a.foo', None) + o = dns.name.from_text('bar.', None) + e = dns.name.from_text('a.foo.bar.', None) + self.failUnless(n.derelativize(o) == e) + + def testDerelativize2(self): + n = dns.name.empty + o = dns.name.from_text('a.foo.bar.', None) + e = o + self.failUnless(n.derelativize(o) == e) + + def testDerelativize3(self): + n = dns.name.from_text('a.foo.bar.', None) + o = dns.name.from_text('blaz.', None) + e = n + self.failUnless(n.derelativize(o) == e) + + def testChooseRelativity1(self): + n = dns.name.from_text('a.foo.bar.', None) + o = dns.name.from_text('bar.', None) + e = dns.name.from_text('a.foo', None) + self.failUnless(n.choose_relativity(o, True) == e) + + def testChooseRelativity2(self): + n = dns.name.from_text('a.foo.bar.', None) + o = dns.name.from_text('bar.', None) + e = n + self.failUnless(n.choose_relativity(o, False) == e) + + def testChooseRelativity3(self): + n = dns.name.from_text('a.foo', None) + o = dns.name.from_text('bar.', None) + e = dns.name.from_text('a.foo.bar.', None) + self.failUnless(n.choose_relativity(o, False) == e) + + def testChooseRelativity4(self): + n = dns.name.from_text('a.foo', None) + o = None + e = n + self.failUnless(n.choose_relativity(o, True) == e) + + def testChooseRelativity5(self): + n = dns.name.from_text('a.foo', None) + o = None + e = n + self.failUnless(n.choose_relativity(o, False) == e) + + def testChooseRelativity6(self): + n = dns.name.from_text('a.foo.', None) + o = None + e = n + self.failUnless(n.choose_relativity(o, True) == e) + + def testChooseRelativity7(self): + n = dns.name.from_text('a.foo.', None) + o = None + e = n + self.failUnless(n.choose_relativity(o, False) == e) + + def testFromWire1(self): + w = '\x03foo\x00\xc0\x00' + (n1, cused1) = dns.name.from_wire(w, 0) + (n2, cused2) = dns.name.from_wire(w, cused1) + en1 = dns.name.from_text('foo.') + en2 = en1 + ecused1 = 5 + ecused2 = 2 + self.failUnless(n1 == en1 and cused1 == ecused1 and \ + n2 == en2 and cused2 == ecused2) + + def testFromWire1(self): + w = '\x03foo\x00\x01a\xc0\x00\x01b\xc0\x05' + current = 0 + (n1, cused1) = dns.name.from_wire(w, current) + current += cused1 + (n2, cused2) = dns.name.from_wire(w, current) + current += cused2 + (n3, cused3) = dns.name.from_wire(w, current) + en1 = dns.name.from_text('foo.') + en2 = dns.name.from_text('a.foo.') + en3 = dns.name.from_text('b.a.foo.') + ecused1 = 5 + ecused2 = 4 + ecused3 = 4 + self.failUnless(n1 == en1 and cused1 == ecused1 and \ + n2 == en2 and cused2 == ecused2 and \ + n3 == en3 and cused3 == ecused3) + + def testBadFromWire1(self): + def bad(): + w = '\x03foo\xc0\x04' + (n, cused) = dns.name.from_wire(w, 0) + self.failUnlessRaises(dns.name.BadPointer, bad) + + def testBadFromWire2(self): + def bad(): + w = '\x03foo\xc0\x05' + (n, cused) = dns.name.from_wire(w, 0) + self.failUnlessRaises(dns.name.BadPointer, bad) + + def testBadFromWire3(self): + def bad(): + w = '\xbffoo' + (n, cused) = dns.name.from_wire(w, 0) + self.failUnlessRaises(dns.name.BadLabelType, bad) + + def testBadFromWire4(self): + def bad(): + w = '\x41foo' + (n, cused) = dns.name.from_wire(w, 0) + self.failUnlessRaises(dns.name.BadLabelType, bad) + + def testParent1(self): + n = dns.name.from_text('foo.bar.') + self.failUnless(n.parent() == dns.name.from_text('bar.')) + self.failUnless(n.parent().parent() == dns.name.root) + + def testParent2(self): + n = dns.name.from_text('foo.bar', None) + self.failUnless(n.parent() == dns.name.from_text('bar', None)) + self.failUnless(n.parent().parent() == dns.name.empty) + + def testParent3(self): + def bad(): + n = dns.name.root + n.parent() + self.failUnlessRaises(dns.name.NoParent, bad) + + def testParent4(self): + def bad(): + n = dns.name.empty + n.parent() + self.failUnlessRaises(dns.name.NoParent, bad) + + def testFromUnicode1(self): + n = dns.name.from_text(u'foo.bar') + self.failUnless(n.labels == ('foo', 'bar', '')) + + def testFromUnicode2(self): + n = dns.name.from_text(u'foo\u1234bar.bar') + self.failUnless(n.labels == ('xn--foobar-r5z', 'bar', '')) + + def testFromUnicodeAlternateDot1(self): + n = dns.name.from_text(u'foo\u3002bar') + self.failUnless(n.labels == ('foo', 'bar', '')) + + def testFromUnicodeAlternateDot2(self): + n = dns.name.from_text(u'foo\uff0ebar') + self.failUnless(n.labels == ('foo', 'bar', '')) + + def testFromUnicodeAlternateDot3(self): + n = dns.name.from_text(u'foo\uff61bar') + self.failUnless(n.labels == ('foo', 'bar', '')) + + def testToUnicode1(self): + n = dns.name.from_text(u'foo.bar') + s = n.to_unicode() + self.failUnless(s == u'foo.bar.') + + def testToUnicode2(self): + n = dns.name.from_text(u'foo\u1234bar.bar') + s = n.to_unicode() + self.failUnless(s == u'foo\u1234bar.bar.') + + def testToUnicode3(self): + n = dns.name.from_text('foo.bar') + s = n.to_unicode() + self.failUnless(s == u'foo.bar.') + + def testReverseIPv4(self): + e = dns.name.from_text('1.0.0.127.in-addr.arpa.') + n = dns.reversename.from_address('127.0.0.1') + self.failUnless(e == n) + + def testReverseIPv6(self): + e = dns.name.from_text('1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.') + n = dns.reversename.from_address('::1') + self.failUnless(e == n) + + def testBadReverseIPv4(self): + def bad(): + n = dns.reversename.from_address('127.0.foo.1') + self.failUnlessRaises(socket.error, bad) + + def testBadReverseIPv6(self): + def bad(): + n = dns.reversename.from_address('::1::1') + self.failUnlessRaises(socket.error, bad) + + def testForwardIPv4(self): + n = dns.name.from_text('1.0.0.127.in-addr.arpa.') + e = '127.0.0.1' + text = dns.reversename.to_address(n) + self.failUnless(text == e) + + def testForwardIPv6(self): + n = dns.name.from_text('1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.') + e = '::1' + text = dns.reversename.to_address(n) + self.failUnless(text == e) + + def testE164ToEnum(self): + text = '+1 650 555 1212' + e = dns.name.from_text('2.1.2.1.5.5.5.0.5.6.1.e164.arpa.') + n = dns.e164.from_e164(text) + self.failUnless(n == e) + + def testEnumToE164(self): + n = dns.name.from_text('2.1.2.1.5.5.5.0.5.6.1.e164.arpa.') + e = '+16505551212' + text = dns.e164.to_e164(n) + self.failUnless(text == e) + +if __name__ == '__main__': + unittest.main() diff --git a/lib/dnspython/tests/namedict.py b/lib/dnspython/tests/namedict.py new file mode 100644 index 0000000000..0261142186 --- /dev/null +++ b/lib/dnspython/tests/namedict.py @@ -0,0 +1,102 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import unittest + +import dns.name +import dns.namedict + +class NameTestCase(unittest.TestCase): + + def setUp(self): + self.ndict = dns.namedict.NameDict() + n1 = dns.name.from_text('foo.bar.') + n2 = dns.name.from_text('bar.') + self.ndict[n1] = 1 + self.ndict[n2] = 2 + self.rndict = dns.namedict.NameDict() + n1 = dns.name.from_text('foo.bar', None) + n2 = dns.name.from_text('bar', None) + self.rndict[n1] = 1 + self.rndict[n2] = 2 + + def testDepth(self): + self.failUnless(self.ndict.max_depth == 3) + + def testLookup1(self): + k = dns.name.from_text('foo.bar.') + self.failUnless(self.ndict[k] == 1) + + def testLookup2(self): + k = dns.name.from_text('foo.bar.') + self.failUnless(self.ndict.get_deepest_match(k)[1] == 1) + + def testLookup3(self): + k = dns.name.from_text('a.b.c.foo.bar.') + self.failUnless(self.ndict.get_deepest_match(k)[1] == 1) + + def testLookup4(self): + k = dns.name.from_text('a.b.c.bar.') + self.failUnless(self.ndict.get_deepest_match(k)[1] == 2) + + def testLookup5(self): + def bad(): + n = dns.name.from_text('a.b.c.') + (k, v) = self.ndict.get_deepest_match(n) + self.failUnlessRaises(KeyError, bad) + + def testLookup6(self): + def bad(): + (k, v) = self.ndict.get_deepest_match(dns.name.empty) + self.failUnlessRaises(KeyError, bad) + + def testLookup7(self): + self.ndict[dns.name.empty] = 100 + n = dns.name.from_text('a.b.c.') + (k, v) = self.ndict.get_deepest_match(n) + self.failUnless(v == 100) + + def testLookup8(self): + def bad(): + self.ndict['foo'] = 100 + self.failUnlessRaises(ValueError, bad) + + def testRelDepth(self): + self.failUnless(self.rndict.max_depth == 2) + + def testRelLookup1(self): + k = dns.name.from_text('foo.bar', None) + self.failUnless(self.rndict[k] == 1) + + def testRelLookup2(self): + k = dns.name.from_text('foo.bar', None) + self.failUnless(self.rndict.get_deepest_match(k)[1] == 1) + + def testRelLookup3(self): + k = dns.name.from_text('a.b.c.foo.bar', None) + self.failUnless(self.rndict.get_deepest_match(k)[1] == 1) + + def testRelLookup4(self): + k = dns.name.from_text('a.b.c.bar', None) + self.failUnless(self.rndict.get_deepest_match(k)[1] == 2) + + def testRelLookup7(self): + self.rndict[dns.name.empty] = 100 + n = dns.name.from_text('a.b.c', None) + (k, v) = self.rndict.get_deepest_match(n) + self.failUnless(v == 100) + +if __name__ == '__main__': + unittest.main() diff --git a/lib/dnspython/tests/ntoaaton.py b/lib/dnspython/tests/ntoaaton.py new file mode 100644 index 0000000000..77befd26e3 --- /dev/null +++ b/lib/dnspython/tests/ntoaaton.py @@ -0,0 +1,156 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import unittest + +import dns.exception +import dns.ipv6 + +class NtoAAtoNTestCase(unittest.TestCase): + + def test_aton1(self): + a = dns.ipv6.inet_aton('::') + self.failUnless(a == '\x00' * 16) + + def test_aton2(self): + a = dns.ipv6.inet_aton('::1') + self.failUnless(a == '\x00' * 15 + '\x01') + + def test_aton3(self): + a = dns.ipv6.inet_aton('::10.0.0.1') + self.failUnless(a == '\x00' * 12 + '\x0a\x00\x00\x01') + + def test_aton4(self): + a = dns.ipv6.inet_aton('abcd::dcba') + self.failUnless(a == '\xab\xcd' + '\x00' * 12 + '\xdc\xba') + + def test_aton5(self): + a = dns.ipv6.inet_aton('1:2:3:4:5:6:7:8') + self.failUnless(a == \ + '00010002000300040005000600070008'.decode('hex_codec')) + + def test_bad_aton1(self): + def bad(): + a = dns.ipv6.inet_aton('abcd:dcba') + self.failUnlessRaises(dns.exception.SyntaxError, bad) + + def test_bad_aton2(self): + def bad(): + a = dns.ipv6.inet_aton('abcd::dcba::1') + self.failUnlessRaises(dns.exception.SyntaxError, bad) + + def test_bad_aton3(self): + def bad(): + a = dns.ipv6.inet_aton('1:2:3:4:5:6:7:8:9') + self.failUnlessRaises(dns.exception.SyntaxError, bad) + + def test_aton1(self): + a = dns.ipv6.inet_aton('::') + self.failUnless(a == '\x00' * 16) + + def test_aton2(self): + a = dns.ipv6.inet_aton('::1') + self.failUnless(a == '\x00' * 15 + '\x01') + + def test_aton3(self): + a = dns.ipv6.inet_aton('::10.0.0.1') + self.failUnless(a == '\x00' * 12 + '\x0a\x00\x00\x01') + + def test_aton4(self): + a = dns.ipv6.inet_aton('abcd::dcba') + self.failUnless(a == '\xab\xcd' + '\x00' * 12 + '\xdc\xba') + + def test_ntoa1(self): + b = '00010002000300040005000600070008'.decode('hex_codec') + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == '1:2:3:4:5:6:7:8') + + def test_ntoa2(self): + b = '\x00' * 16 + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == '::') + + def test_ntoa3(self): + b = '\x00' * 15 + '\x01' + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == '::1') + + def test_ntoa4(self): + b = '\x80' + '\x00' * 15 + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == '8000::') + + def test_ntoa5(self): + b = '\x01\xcd' + '\x00' * 12 + '\x03\xef' + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == '1cd::3ef') + + def test_ntoa6(self): + b = 'ffff00000000ffff000000000000ffff'.decode('hex_codec') + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == 'ffff:0:0:ffff::ffff') + + def test_ntoa7(self): + b = '00000000ffff000000000000ffffffff'.decode('hex_codec') + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == '0:0:ffff::ffff:ffff') + + def test_ntoa8(self): + b = 'ffff0000ffff00000000ffff00000000'.decode('hex_codec') + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == 'ffff:0:ffff::ffff:0:0') + + def test_ntoa9(self): + b = '0000000000000000000000000a000001'.decode('hex_codec') + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == '::10.0.0.1') + + def test_ntoa10(self): + b = '0000000000000000000000010a000001'.decode('hex_codec') + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == '::1:a00:1') + + def test_ntoa11(self): + b = '00000000000000000000ffff0a000001'.decode('hex_codec') + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == '::ffff:10.0.0.1') + + def test_ntoa12(self): + b = '000000000000000000000000ffffffff'.decode('hex_codec') + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == '::255.255.255.255') + + def test_ntoa13(self): + b = '00000000000000000000ffffffffffff'.decode('hex_codec') + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == '::ffff:255.255.255.255') + + def test_ntoa14(self): + b = '0000000000000000000000000001ffff'.decode('hex_codec') + t = dns.ipv6.inet_ntoa(b) + self.failUnless(t == '::0.1.255.255') + + def test_bad_ntoa1(self): + def bad(): + a = dns.ipv6.inet_ntoa('') + self.failUnlessRaises(ValueError, bad) + + def test_bad_ntoa2(self): + def bad(): + a = dns.ipv6.inet_ntoa('\x00' * 17) + self.failUnlessRaises(ValueError, bad) + +if __name__ == '__main__': + unittest.main() diff --git a/lib/dnspython/tests/rdtypeandclass.py b/lib/dnspython/tests/rdtypeandclass.py new file mode 100644 index 0000000000..edd7f7eae3 --- /dev/null +++ b/lib/dnspython/tests/rdtypeandclass.py @@ -0,0 +1,123 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import unittest + +import dns.rdataclass +import dns.rdatatype + +class RdTypeAndClassTestCase(unittest.TestCase): + + # Classes + + def test_class_meta1(self): + self.failUnless(dns.rdataclass.is_metaclass(dns.rdataclass.ANY)) + + def test_class_meta2(self): + self.failUnless(not dns.rdataclass.is_metaclass(dns.rdataclass.IN)) + + def test_class_bytext1(self): + self.failUnless(dns.rdataclass.from_text('IN') == dns.rdataclass.IN) + + def test_class_bytext2(self): + self.failUnless(dns.rdataclass.from_text('CLASS1') == + dns.rdataclass.IN) + + def test_class_bytext_bounds1(self): + self.failUnless(dns.rdataclass.from_text('CLASS0') == 0) + self.failUnless(dns.rdataclass.from_text('CLASS65535') == 65535) + + def test_class_bytext_bounds2(self): + def bad(): + junk = dns.rdataclass.from_text('CLASS65536') + self.failUnlessRaises(ValueError, bad) + + def test_class_bytext_unknown(self): + def bad(): + junk = dns.rdataclass.from_text('XXX') + self.failUnlessRaises(dns.rdataclass.UnknownRdataclass, bad) + + def test_class_totext1(self): + self.failUnless(dns.rdataclass.to_text(dns.rdataclass.IN) == 'IN') + + def test_class_totext1(self): + self.failUnless(dns.rdataclass.to_text(999) == 'CLASS999') + + def test_class_totext_bounds1(self): + def bad(): + junk = dns.rdataclass.to_text(-1) + self.failUnlessRaises(ValueError, bad) + + def test_class_totext_bounds2(self): + def bad(): + junk = dns.rdataclass.to_text(65536) + self.failUnlessRaises(ValueError, bad) + + # Types + + def test_type_meta1(self): + self.failUnless(dns.rdatatype.is_metatype(dns.rdatatype.ANY)) + + def test_type_meta2(self): + self.failUnless(dns.rdatatype.is_metatype(dns.rdatatype.OPT)) + + def test_type_meta3(self): + self.failUnless(not dns.rdatatype.is_metatype(dns.rdatatype.A)) + + def test_type_singleton1(self): + self.failUnless(dns.rdatatype.is_singleton(dns.rdatatype.SOA)) + + def test_type_singleton2(self): + self.failUnless(not dns.rdatatype.is_singleton(dns.rdatatype.A)) + + def test_type_bytext1(self): + self.failUnless(dns.rdatatype.from_text('A') == dns.rdatatype.A) + + def test_type_bytext2(self): + self.failUnless(dns.rdatatype.from_text('TYPE1') == + dns.rdatatype.A) + + def test_type_bytext_bounds1(self): + self.failUnless(dns.rdatatype.from_text('TYPE0') == 0) + self.failUnless(dns.rdatatype.from_text('TYPE65535') == 65535) + + def test_type_bytext_bounds2(self): + def bad(): + junk = dns.rdatatype.from_text('TYPE65536') + self.failUnlessRaises(ValueError, bad) + + def test_type_bytext_unknown(self): + def bad(): + junk = dns.rdatatype.from_text('XXX') + self.failUnlessRaises(dns.rdatatype.UnknownRdatatype, bad) + + def test_type_totext1(self): + self.failUnless(dns.rdatatype.to_text(dns.rdatatype.A) == 'A') + + def test_type_totext1(self): + self.failUnless(dns.rdatatype.to_text(999) == 'TYPE999') + + def test_type_totext_bounds1(self): + def bad(): + junk = dns.rdatatype.to_text(-1) + self.failUnlessRaises(ValueError, bad) + + def test_type_totext_bounds2(self): + def bad(): + junk = dns.rdatatype.to_text(65536) + self.failUnlessRaises(ValueError, bad) + +if __name__ == '__main__': + unittest.main() diff --git a/lib/dnspython/tests/resolver.py b/lib/dnspython/tests/resolver.py new file mode 100644 index 0000000000..4cacbdc79d --- /dev/null +++ b/lib/dnspython/tests/resolver.py @@ -0,0 +1,105 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import cStringIO +import sys +import time +import unittest + +import dns.name +import dns.message +import dns.name +import dns.rdataclass +import dns.rdatatype +import dns.resolver + +resolv_conf = """ + /t/t +# comment 1 +; comment 2 +domain foo +nameserver 10.0.0.1 +nameserver 10.0.0.2 +""" + +message_text = """id 1234 +opcode QUERY +rcode NOERROR +flags QR AA RD +;QUESTION +example. IN A +;ANSWER +example. 1 IN A 10.0.0.1 +;AUTHORITY +;ADDITIONAL +""" + +class ResolverTestCase(unittest.TestCase): + + if sys.platform != 'win32': + def testRead(self): + f = cStringIO.StringIO(resolv_conf) + r = dns.resolver.Resolver(f) + self.failUnless(r.nameservers == ['10.0.0.1', '10.0.0.2'] and + r.domain == dns.name.from_text('foo')) + + def testCacheExpiration(self): + message = dns.message.from_text(message_text) + name = dns.name.from_text('example.') + answer = dns.resolver.Answer(name, dns.rdatatype.A, dns.rdataclass.IN, + message) + cache = dns.resolver.Cache() + cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer) + time.sleep(2) + self.failUnless(cache.get((name, dns.rdatatype.A, dns.rdataclass.IN)) + is None) + + def testCacheCleaning(self): + message = dns.message.from_text(message_text) + name = dns.name.from_text('example.') + answer = dns.resolver.Answer(name, dns.rdatatype.A, dns.rdataclass.IN, + message) + cache = dns.resolver.Cache(cleaning_interval=1.0) + cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer) + time.sleep(2) + self.failUnless(cache.get((name, dns.rdatatype.A, dns.rdataclass.IN)) + is None) + + def testZoneForName1(self): + name = dns.name.from_text('www.dnspython.org.') + ezname = dns.name.from_text('dnspython.org.') + zname = dns.resolver.zone_for_name(name) + self.failUnless(zname == ezname) + + def testZoneForName2(self): + name = dns.name.from_text('a.b.www.dnspython.org.') + ezname = dns.name.from_text('dnspython.org.') + zname = dns.resolver.zone_for_name(name) + self.failUnless(zname == ezname) + + def testZoneForName3(self): + name = dns.name.from_text('dnspython.org.') + ezname = dns.name.from_text('dnspython.org.') + zname = dns.resolver.zone_for_name(name) + self.failUnless(zname == ezname) + + def testZoneForName4(self): + def bad(): + name = dns.name.from_text('dnspython.org', None) + zname = dns.resolver.zone_for_name(name) + self.failUnlessRaises(dns.resolver.NotAbsolute, bad) + +if __name__ == '__main__': + unittest.main() diff --git a/lib/dnspython/tests/rrset.py b/lib/dnspython/tests/rrset.py new file mode 100644 index 0000000000..740162b4c5 --- /dev/null +++ b/lib/dnspython/tests/rrset.py @@ -0,0 +1,54 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import unittest + +import dns.rrset + +class RRsetTestCase(unittest.TestCase): + + def testEqual1(self): + r1 = dns.rrset.from_text('foo', 300, 'in', 'a', '10.0.0.1', '10.0.0.2') + r2 = dns.rrset.from_text('FOO', 300, 'in', 'a', '10.0.0.2', '10.0.0.1') + self.failUnless(r1 == r2) + + def testEqual2(self): + r1 = dns.rrset.from_text('foo', 300, 'in', 'a', '10.0.0.1', '10.0.0.2') + r2 = dns.rrset.from_text('FOO', 600, 'in', 'a', '10.0.0.2', '10.0.0.1') + self.failUnless(r1 == r2) + + def testNotEqual1(self): + r1 = dns.rrset.from_text('fooa', 30, 'in', 'a', '10.0.0.1', '10.0.0.2') + r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1') + self.failUnless(r1 != r2) + + def testNotEqual2(self): + r1 = dns.rrset.from_text('foo', 30, 'in', 'a', '10.0.0.1', '10.0.0.3') + r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1') + self.failUnless(r1 != r2) + + def testNotEqual3(self): + r1 = dns.rrset.from_text('foo', 30, 'in', 'a', '10.0.0.1', '10.0.0.2', + '10.0.0.3') + r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1') + self.failUnless(r1 != r2) + + def testNotEqual4(self): + r1 = dns.rrset.from_text('foo', 30, 'in', 'a', '10.0.0.1') + r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1') + self.failUnless(r1 != r2) + +if __name__ == '__main__': + unittest.main() diff --git a/lib/dnspython/tests/set.py b/lib/dnspython/tests/set.py new file mode 100644 index 0000000000..6319eb821c --- /dev/null +++ b/lib/dnspython/tests/set.py @@ -0,0 +1,208 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import unittest + +import dns.set + +# for convenience +S = dns.set.Set + +class SimpleSetTestCase(unittest.TestCase): + + def testLen1(self): + s1 = S() + self.failUnless(len(s1) == 0) + + def testLen2(self): + s1 = S([1, 2, 3]) + self.failUnless(len(s1) == 3) + + def testLen3(self): + s1 = S([1, 2, 3, 3, 3]) + self.failUnless(len(s1) == 3) + + def testUnion1(self): + s1 = S([1, 2, 3]) + s2 = S([1, 2, 3]) + e = S([1, 2, 3]) + self.failUnless(s1 | s2 == e) + + def testUnion2(self): + s1 = S([1, 2, 3]) + s2 = S([]) + e = S([1, 2, 3]) + self.failUnless(s1 | s2 == e) + + def testUnion3(self): + s1 = S([1, 2, 3]) + s2 = S([3, 4]) + e = S([1, 2, 3, 4]) + self.failUnless(s1 | s2 == e) + + def testIntersection1(self): + s1 = S([1, 2, 3]) + s2 = S([1, 2, 3]) + e = S([1, 2, 3]) + self.failUnless(s1 & s2 == e) + + def testIntersection2(self): + s1 = S([0, 1, 2, 3]) + s2 = S([1, 2, 3, 4]) + e = S([1, 2, 3]) + self.failUnless(s1 & s2 == e) + + def testIntersection3(self): + s1 = S([1, 2, 3]) + s2 = S([]) + e = S([]) + self.failUnless(s1 & s2 == e) + + def testIntersection4(self): + s1 = S([1, 2, 3]) + s2 = S([5, 4]) + e = S([]) + self.failUnless(s1 & s2 == e) + + def testDifference1(self): + s1 = S([1, 2, 3]) + s2 = S([5, 4]) + e = S([1, 2, 3]) + self.failUnless(s1 - s2 == e) + + def testDifference2(self): + s1 = S([1, 2, 3]) + s2 = S([]) + e = S([1, 2, 3]) + self.failUnless(s1 - s2 == e) + + def testDifference3(self): + s1 = S([1, 2, 3]) + s2 = S([3, 2]) + e = S([1]) + self.failUnless(s1 - s2 == e) + + def testDifference4(self): + s1 = S([1, 2, 3]) + s2 = S([3, 2, 1]) + e = S([]) + self.failUnless(s1 - s2 == e) + + def testSubset1(self): + s1 = S([1, 2, 3]) + s2 = S([3, 2, 1]) + self.failUnless(s1.issubset(s2)) + + def testSubset2(self): + s1 = S([1, 2, 3]) + self.failUnless(s1.issubset(s1)) + + def testSubset3(self): + s1 = S([]) + s2 = S([1, 2, 3]) + self.failUnless(s1.issubset(s2)) + + def testSubset4(self): + s1 = S([1]) + s2 = S([1, 2, 3]) + self.failUnless(s1.issubset(s2)) + + def testSubset5(self): + s1 = S([]) + s2 = S([]) + self.failUnless(s1.issubset(s2)) + + def testSubset6(self): + s1 = S([1, 4]) + s2 = S([1, 2, 3]) + self.failUnless(not s1.issubset(s2)) + + def testSuperset1(self): + s1 = S([1, 2, 3]) + s2 = S([3, 2, 1]) + self.failUnless(s1.issuperset(s2)) + + def testSuperset2(self): + s1 = S([1, 2, 3]) + self.failUnless(s1.issuperset(s1)) + + def testSuperset3(self): + s1 = S([1, 2, 3]) + s2 = S([]) + self.failUnless(s1.issuperset(s2)) + + def testSuperset4(self): + s1 = S([1, 2, 3]) + s2 = S([1]) + self.failUnless(s1.issuperset(s2)) + + def testSuperset5(self): + s1 = S([]) + s2 = S([]) + self.failUnless(s1.issuperset(s2)) + + def testSuperset6(self): + s1 = S([1, 2, 3]) + s2 = S([1, 4]) + self.failUnless(not s1.issuperset(s2)) + + def testUpdate1(self): + s1 = S([1, 2, 3]) + u = (4, 5, 6) + e = S([1, 2, 3, 4, 5, 6]) + s1.update(u) + self.failUnless(s1 == e) + + def testUpdate2(self): + s1 = S([1, 2, 3]) + u = [] + e = S([1, 2, 3]) + s1.update(u) + self.failUnless(s1 == e) + + def testGetitem(self): + s1 = S([1, 2, 3]) + i0 = s1[0] + i1 = s1[1] + i2 = s1[2] + s2 = S([i0, i1, i2]) + self.failUnless(s1 == s2) + + def testGetslice(self): + s1 = S([1, 2, 3]) + slice = s1[0:2] + self.failUnless(len(slice) == 2) + item = s1[2] + slice.append(item) + s2 = S(slice) + self.failUnless(s1 == s2) + + def testDelitem(self): + s1 = S([1, 2, 3]) + del s1[0] + i1 = s1[0] + i2 = s1[1] + self.failUnless(i1 != i2) + self.failUnless(i1 == 1 or i1 == 2 or i1 == 3) + self.failUnless(i2 == 1 or i2 == 2 or i2 == 3) + + def testDelslice(self): + s1 = S([1, 2, 3]) + del s1[0:2] + i1 = s1[0] + self.failUnless(i1 == 1 or i1 == 2 or i1 == 3) + +if __name__ == '__main__': + unittest.main() diff --git a/lib/dnspython/tests/tokenizer.py b/lib/dnspython/tests/tokenizer.py new file mode 100644 index 0000000000..4f4a1bdc90 --- /dev/null +++ b/lib/dnspython/tests/tokenizer.py @@ -0,0 +1,190 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import unittest + +import dns.exception +import dns.tokenizer + +Token = dns.tokenizer.Token + +class TokenizerTestCase(unittest.TestCase): + + def testQuotedString1(self): + tok = dns.tokenizer.Tokenizer(r'"foo"') + token = tok.get() + self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, 'foo')) + + def testQuotedString2(self): + tok = dns.tokenizer.Tokenizer(r'""') + token = tok.get() + self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, '')) + + def testQuotedString3(self): + tok = dns.tokenizer.Tokenizer(r'"\"foo\""') + token = tok.get() + self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, '"foo"')) + + def testQuotedString4(self): + tok = dns.tokenizer.Tokenizer(r'"foo\010bar"') + token = tok.get() + self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, 'foo\x0abar')) + + def testQuotedString5(self): + def bad(): + tok = dns.tokenizer.Tokenizer(r'"foo') + token = tok.get() + self.failUnlessRaises(dns.exception.UnexpectedEnd, bad) + + def testQuotedString6(self): + def bad(): + tok = dns.tokenizer.Tokenizer(r'"foo\01') + token = tok.get() + self.failUnlessRaises(dns.exception.SyntaxError, bad) + + def testQuotedString7(self): + def bad(): + tok = dns.tokenizer.Tokenizer('"foo\nbar"') + token = tok.get() + self.failUnlessRaises(dns.exception.SyntaxError, bad) + + def testEmpty1(self): + tok = dns.tokenizer.Tokenizer('') + token = tok.get() + self.failUnless(token.is_eof()) + + def testEmpty2(self): + tok = dns.tokenizer.Tokenizer('') + token1 = tok.get() + token2 = tok.get() + self.failUnless(token1.is_eof() and token2.is_eof()) + + def testEOL(self): + tok = dns.tokenizer.Tokenizer('\n') + token1 = tok.get() + token2 = tok.get() + self.failUnless(token1.is_eol() and token2.is_eof()) + + def testWS1(self): + tok = dns.tokenizer.Tokenizer(' \n') + token1 = tok.get() + self.failUnless(token1.is_eol()) + + def testWS2(self): + tok = dns.tokenizer.Tokenizer(' \n') + token1 = tok.get(want_leading=True) + self.failUnless(token1.is_whitespace()) + + def testComment1(self): + tok = dns.tokenizer.Tokenizer(' ;foo\n') + token1 = tok.get() + self.failUnless(token1.is_eol()) + + def testComment2(self): + tok = dns.tokenizer.Tokenizer(' ;foo\n') + token1 = tok.get(want_comment = True) + token2 = tok.get() + self.failUnless(token1 == Token(dns.tokenizer.COMMENT, 'foo') and + token2.is_eol()) + + def testComment3(self): + tok = dns.tokenizer.Tokenizer(' ;foo bar\n') + token1 = tok.get(want_comment = True) + token2 = tok.get() + self.failUnless(token1 == Token(dns.tokenizer.COMMENT, 'foo bar') and + token2.is_eol()) + + def testMultiline1(self): + tok = dns.tokenizer.Tokenizer('( foo\n\n bar\n)') + tokens = list(iter(tok)) + self.failUnless(tokens == [Token(dns.tokenizer.IDENTIFIER, 'foo'), + Token(dns.tokenizer.IDENTIFIER, 'bar')]) + + def testMultiline2(self): + tok = dns.tokenizer.Tokenizer('( foo\n\n bar\n)\n') + tokens = list(iter(tok)) + self.failUnless(tokens == [Token(dns.tokenizer.IDENTIFIER, 'foo'), + Token(dns.tokenizer.IDENTIFIER, 'bar'), + Token(dns.tokenizer.EOL, '\n')]) + def testMultiline3(self): + def bad(): + tok = dns.tokenizer.Tokenizer('foo)') + tokens = list(iter(tok)) + self.failUnlessRaises(dns.exception.SyntaxError, bad) + + def testMultiline4(self): + def bad(): + tok = dns.tokenizer.Tokenizer('((foo)') + tokens = list(iter(tok)) + self.failUnlessRaises(dns.exception.SyntaxError, bad) + + def testUnget1(self): + tok = dns.tokenizer.Tokenizer('foo') + t1 = tok.get() + tok.unget(t1) + t2 = tok.get() + self.failUnless(t1 == t2 and t1.ttype == dns.tokenizer.IDENTIFIER and \ + t1.value == 'foo') + + def testUnget2(self): + def bad(): + tok = dns.tokenizer.Tokenizer('foo') + t1 = tok.get() + tok.unget(t1) + tok.unget(t1) + self.failUnlessRaises(dns.tokenizer.UngetBufferFull, bad) + + def testGetEOL1(self): + tok = dns.tokenizer.Tokenizer('\n') + t = tok.get_eol() + self.failUnless(t == '\n') + + def testGetEOL2(self): + tok = dns.tokenizer.Tokenizer('') + t = tok.get_eol() + self.failUnless(t == '') + + def testEscapedDelimiter1(self): + tok = dns.tokenizer.Tokenizer(r'ch\ ld') + t = tok.get() + self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\ ld') + + def testEscapedDelimiter2(self): + tok = dns.tokenizer.Tokenizer(r'ch\032ld') + t = tok.get() + self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\032ld') + + def testEscapedDelimiter3(self): + tok = dns.tokenizer.Tokenizer(r'ch\ild') + t = tok.get() + self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\ild') + + def testEscapedDelimiter1u(self): + tok = dns.tokenizer.Tokenizer(r'ch\ ld') + t = tok.get().unescape() + self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch ld') + + def testEscapedDelimiter2u(self): + tok = dns.tokenizer.Tokenizer(r'ch\032ld') + t = tok.get().unescape() + self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == 'ch ld') + + def testEscapedDelimiter3u(self): + tok = dns.tokenizer.Tokenizer(r'ch\ild') + t = tok.get().unescape() + self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'child') + +if __name__ == '__main__': + unittest.main() diff --git a/lib/dnspython/tests/update.py b/lib/dnspython/tests/update.py new file mode 100644 index 0000000000..5f7b31f23f --- /dev/null +++ b/lib/dnspython/tests/update.py @@ -0,0 +1,114 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import unittest + +import dns.update +import dns.rdata +import dns.rdataset + +goodhex = '0001 2800 0001 0005 0007 0000' \ + '076578616d706c6500 0006 0001' \ + '03666f6fc00c 00ff 00ff 00000000 0000' \ + 'c019 0001 00ff 00000000 0000' \ + '03626172c00c 0001 0001 00000000 0004 0a000005' \ + '05626c617a32c00c 00ff 00fe 00000000 0000' \ + 'c049 0001 00fe 00000000 0000' \ + 'c019 0001 00ff 00000000 0000' \ + 'c019 0001 0001 0000012c 0004 0a000001' \ + 'c019 0001 0001 0000012c 0004 0a000002' \ + 'c035 0001 0001 0000012c 0004 0a000003' \ + 'c035 0001 00fe 00000000 0004 0a000004' \ + '04626c617ac00c 0001 00ff 00000000 0000' \ + 'c049 00ff 00ff 00000000 0000' + +goodwire = goodhex.replace(' ', '').decode('hex_codec') + +update_text="""id 1 +opcode UPDATE +rcode NOERROR +;ZONE +example. IN SOA +;PREREQ +foo ANY ANY +foo ANY A +bar 0 IN A 10.0.0.5 +blaz2 NONE ANY +blaz2 NONE A +;UPDATE +foo ANY A +foo 300 IN A 10.0.0.1 +foo 300 IN A 10.0.0.2 +bar 300 IN A 10.0.0.3 +bar 0 NONE A 10.0.0.4 +blaz ANY A +blaz2 ANY ANY +""" + +class UpdateTestCase(unittest.TestCase): + + def test_to_wire1(self): + update = dns.update.Update('example') + update.id = 1 + update.present('foo') + update.present('foo', 'a') + update.present('bar', 'a', '10.0.0.5') + update.absent('blaz2') + update.absent('blaz2', 'a') + update.replace('foo', 300, 'a', '10.0.0.1', '10.0.0.2') + update.add('bar', 300, 'a', '10.0.0.3') + update.delete('bar', 'a', '10.0.0.4') + update.delete('blaz','a') + update.delete('blaz2') + self.failUnless(update.to_wire() == goodwire) + + def test_to_wire2(self): + update = dns.update.Update('example') + update.id = 1 + update.present('foo') + update.present('foo', 'a') + update.present('bar', 'a', '10.0.0.5') + update.absent('blaz2') + update.absent('blaz2', 'a') + update.replace('foo', 300, 'a', '10.0.0.1', '10.0.0.2') + update.add('bar', 300, dns.rdata.from_text(1, 1, '10.0.0.3')) + update.delete('bar', 'a', '10.0.0.4') + update.delete('blaz','a') + update.delete('blaz2') + self.failUnless(update.to_wire() == goodwire) + + def test_to_wire3(self): + update = dns.update.Update('example') + update.id = 1 + update.present('foo') + update.present('foo', 'a') + update.present('bar', 'a', '10.0.0.5') + update.absent('blaz2') + update.absent('blaz2', 'a') + update.replace('foo', 300, 'a', '10.0.0.1', '10.0.0.2') + update.add('bar', dns.rdataset.from_text(1, 1, 300, '10.0.0.3')) + update.delete('bar', 'a', '10.0.0.4') + update.delete('blaz','a') + update.delete('blaz2') + self.failUnless(update.to_wire() == goodwire) + + def test_from_text1(self): + update = dns.message.from_text(update_text) + w = update.to_wire(origin=dns.name.from_text('example'), + want_shuffle=False) + self.failUnless(w == goodwire) + +if __name__ == '__main__': + unittest.main() diff --git a/lib/dnspython/tests/zone.py b/lib/dnspython/tests/zone.py new file mode 100644 index 0000000000..a8d629c532 --- /dev/null +++ b/lib/dnspython/tests/zone.py @@ -0,0 +1,389 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import cStringIO +import filecmp +import os +import unittest + +import dns.exception +import dns.rdata +import dns.rdataclass +import dns.rdatatype +import dns.rrset +import dns.zone + +example_text = """$TTL 3600 +$ORIGIN example. +@ soa foo bar 1 2 3 4 5 +@ ns ns1 +@ ns ns2 +ns1 a 10.0.0.1 +ns2 a 10.0.0.2 +$TTL 300 +$ORIGIN foo.example. +bar mx 0 blaz +""" + +example_text_output = """@ 3600 IN SOA foo bar 1 2 3 4 5 +@ 3600 IN NS ns1 +@ 3600 IN NS ns2 +bar.foo 300 IN MX 0 blaz.foo +ns1 3600 IN A 10.0.0.1 +ns2 3600 IN A 10.0.0.2 +""" + +something_quite_similar = """@ 3600 IN SOA foo bar 1 2 3 4 5 +@ 3600 IN NS ns1 +@ 3600 IN NS ns2 +bar.foo 300 IN MX 0 blaz.foo +ns1 3600 IN A 10.0.0.1 +ns2 3600 IN A 10.0.0.3 +""" + +something_different = """@ 3600 IN SOA fooa bar 1 2 3 4 5 +@ 3600 IN NS ns11 +@ 3600 IN NS ns21 +bar.fooa 300 IN MX 0 blaz.fooa +ns11 3600 IN A 10.0.0.11 +ns21 3600 IN A 10.0.0.21 +""" + +ttl_example_text = """$TTL 1h +$ORIGIN example. +@ soa foo bar 1 2 3 4 5 +@ ns ns1 +@ ns ns2 +ns1 1d1s a 10.0.0.1 +ns2 1w1D1h1m1S a 10.0.0.2 +""" + +no_soa_text = """$TTL 1h +$ORIGIN example. +@ ns ns1 +@ ns ns2 +ns1 1d1s a 10.0.0.1 +ns2 1w1D1h1m1S a 10.0.0.2 +""" + +no_ns_text = """$TTL 1h +$ORIGIN example. +@ soa foo bar 1 2 3 4 5 +""" + +include_text = """$INCLUDE "example" +""" + +bad_directive_text = """$FOO bar +$ORIGIN example. +@ soa foo bar 1 2 3 4 5 +@ ns ns1 +@ ns ns2 +ns1 1d1s a 10.0.0.1 +ns2 1w1D1h1m1S a 10.0.0.2 +""" + +_keep_output = False + +class ZoneTestCase(unittest.TestCase): + + def testFromFile1(self): + z = dns.zone.from_file('example', 'example') + ok = False + try: + z.to_file('example1.out', nl='\x0a') + ok = filecmp.cmp('example1.out', 'example1.good') + finally: + if not _keep_output: + os.unlink('example1.out') + self.failUnless(ok) + + def testFromFile2(self): + z = dns.zone.from_file('example', 'example', relativize=False) + ok = False + try: + z.to_file('example2.out', relativize=False, nl='\x0a') + ok = filecmp.cmp('example2.out', 'example2.good') + finally: + if not _keep_output: + os.unlink('example2.out') + self.failUnless(ok) + + def testFromText(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + f = cStringIO.StringIO() + names = z.nodes.keys() + names.sort() + for n in names: + print >> f, z[n].to_text(n) + self.failUnless(f.getvalue() == example_text_output) + + def testTorture1(self): + # + # Read a zone containing all our supported RR types, and + # for each RR in the zone, convert the rdata into wire format + # and then back out, and see if we get equal rdatas. + # + f = cStringIO.StringIO() + o = dns.name.from_text('example.') + z = dns.zone.from_file('example', o) + for (name, node) in z.iteritems(): + for rds in node: + for rd in rds: + f.seek(0) + f.truncate() + rd.to_wire(f, origin=o) + wire = f.getvalue() + rd2 = dns.rdata.from_wire(rds.rdclass, rds.rdtype, + wire, 0, len(wire), + origin = o) + self.failUnless(rd == rd2) + + def testEqual(self): + z1 = dns.zone.from_text(example_text, 'example.', relativize=True) + z2 = dns.zone.from_text(example_text_output, 'example.', + relativize=True) + self.failUnless(z1 == z2) + + def testNotEqual1(self): + z1 = dns.zone.from_text(example_text, 'example.', relativize=True) + z2 = dns.zone.from_text(something_quite_similar, 'example.', + relativize=True) + self.failUnless(z1 != z2) + + def testNotEqual2(self): + z1 = dns.zone.from_text(example_text, 'example.', relativize=True) + z2 = dns.zone.from_text(something_different, 'example.', + relativize=True) + self.failUnless(z1 != z2) + + def testNotEqual3(self): + z1 = dns.zone.from_text(example_text, 'example.', relativize=True) + z2 = dns.zone.from_text(something_different, 'example2.', + relativize=True) + self.failUnless(z1 != z2) + + def testFindRdataset1(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + rds = z.find_rdataset('@', 'soa') + exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5') + self.failUnless(rds == exrds) + + def testFindRdataset2(self): + def bad(): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + rds = z.find_rdataset('@', 'loc') + self.failUnlessRaises(KeyError, bad) + + def testFindRRset1(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + rrs = z.find_rrset('@', 'soa') + exrrs = dns.rrset.from_text('@', 300, 'IN', 'SOA', 'foo bar 1 2 3 4 5') + self.failUnless(rrs == exrrs) + + def testFindRRset2(self): + def bad(): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + rrs = z.find_rrset('@', 'loc') + self.failUnlessRaises(KeyError, bad) + + def testGetRdataset1(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + rds = z.get_rdataset('@', 'soa') + exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5') + self.failUnless(rds == exrds) + + def testGetRdataset2(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + rds = z.get_rdataset('@', 'loc') + self.failUnless(rds == None) + + def testGetRRset1(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + rrs = z.get_rrset('@', 'soa') + exrrs = dns.rrset.from_text('@', 300, 'IN', 'SOA', 'foo bar 1 2 3 4 5') + self.failUnless(rrs == exrrs) + + def testGetRRset2(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + rrs = z.get_rrset('@', 'loc') + self.failUnless(rrs == None) + + def testReplaceRdataset1(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + rdataset = dns.rdataset.from_text('in', 'ns', 300, 'ns3', 'ns4') + z.replace_rdataset('@', rdataset) + rds = z.get_rdataset('@', 'ns') + self.failUnless(rds is rdataset) + + def testReplaceRdataset2(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + rdataset = dns.rdataset.from_text('in', 'txt', 300, '"foo"') + z.replace_rdataset('@', rdataset) + rds = z.get_rdataset('@', 'txt') + self.failUnless(rds is rdataset) + + def testDeleteRdataset1(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + z.delete_rdataset('@', 'ns') + rds = z.get_rdataset('@', 'ns') + self.failUnless(rds is None) + + def testDeleteRdataset2(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + z.delete_rdataset('ns1', 'a') + node = z.get_node('ns1') + self.failUnless(node is None) + + def testNodeFindRdataset1(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + node = z['@'] + rds = node.find_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA) + exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5') + self.failUnless(rds == exrds) + + def testNodeFindRdataset2(self): + def bad(): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + node = z['@'] + rds = node.find_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC) + self.failUnlessRaises(KeyError, bad) + + def testNodeGetRdataset1(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + node = z['@'] + rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA) + exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5') + self.failUnless(rds == exrds) + + def testNodeGetRdataset2(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + node = z['@'] + rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC) + self.failUnless(rds == None) + + def testNodeDeleteRdataset1(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + node = z['@'] + rds = node.delete_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA) + rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA) + self.failUnless(rds == None) + + def testNodeDeleteRdataset2(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + node = z['@'] + rds = node.delete_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC) + rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC) + self.failUnless(rds == None) + + def testIterateRdatasets(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + ns = [n for n, r in z.iterate_rdatasets('A')] + ns.sort() + self.failUnless(ns == [dns.name.from_text('ns1', None), + dns.name.from_text('ns2', None)]) + + def testIterateAllRdatasets(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + ns = [n for n, r in z.iterate_rdatasets()] + ns.sort() + self.failUnless(ns == [dns.name.from_text('@', None), + dns.name.from_text('@', None), + dns.name.from_text('bar.foo', None), + dns.name.from_text('ns1', None), + dns.name.from_text('ns2', None)]) + + def testIterateRdatas(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + l = list(z.iterate_rdatas('A')) + l.sort() + exl = [(dns.name.from_text('ns1', None), + 3600, + dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, + '10.0.0.1')), + (dns.name.from_text('ns2', None), + 3600, + dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, + '10.0.0.2'))] + self.failUnless(l == exl) + + def testIterateAllRdatas(self): + z = dns.zone.from_text(example_text, 'example.', relativize=True) + l = list(z.iterate_rdatas()) + l.sort() + exl = [(dns.name.from_text('@', None), + 3600, + dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, + 'ns1')), + (dns.name.from_text('@', None), + 3600, + dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, + 'ns2')), + (dns.name.from_text('@', None), + 3600, + dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, + 'foo bar 1 2 3 4 5')), + (dns.name.from_text('bar.foo', None), + 300, + dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, + '0 blaz.foo')), + (dns.name.from_text('ns1', None), + 3600, + dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, + '10.0.0.1')), + (dns.name.from_text('ns2', None), + 3600, + dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, + '10.0.0.2'))] + self.failUnless(l == exl) + + def testTTLs(self): + z = dns.zone.from_text(ttl_example_text, 'example.', relativize=True) + n = z['@'] + rds = n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA) + self.failUnless(rds.ttl == 3600) + n = z['ns1'] + rds = n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A) + self.failUnless(rds.ttl == 86401) + n = z['ns2'] + rds = n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A) + self.failUnless(rds.ttl == 694861) + + def testNoSOA(self): + def bad(): + z = dns.zone.from_text(no_soa_text, 'example.', + relativize=True) + self.failUnlessRaises(dns.zone.NoSOA, bad) + + def testNoNS(self): + def bad(): + z = dns.zone.from_text(no_ns_text, 'example.', + relativize=True) + self.failUnlessRaises(dns.zone.NoNS, bad) + + def testInclude(self): + z1 = dns.zone.from_text(include_text, 'example.', relativize=True, + allow_include=True) + z2 = dns.zone.from_file('example', 'example.', relativize=True) + self.failUnless(z1 == z2) + + def testBadDirective(self): + def bad(): + z = dns.zone.from_text(bad_directive_text, 'example.', + relativize=True) + self.failUnlessRaises(dns.exception.SyntaxError, bad) + +if __name__ == '__main__': + unittest.main() |