Codebase list dnspython / 3519406
Imported Upstream version 1.12.0 SVN-Git Migration 8 years ago
57 changed file(s) with 4053 addition(s) and 3343 deletion(s). Raw diff Collapse all Expand all
0 2014-09-01 Bob Halley <halley@dnspython.org>
1
2 * (Version 1.12.0 released)
3
4 2014-08-31 Bob Halley <halley@dnspython.org>
5
6 * The test system can now run the tests without requiring dnspython
7 to be installed.
8
9 2014-07-24 Bob Halley <halley@dnspython.org>
10
11 * The 64-bit version of Python on Windows has sys.maxint set to
12 2^31-1, yet passes 2^63-1 as the "unspecified bound" value in
13 slices. This is a bug in Python as the documentation says the
14 unspecified bound value should be sys.maxint. We now cope with
15 this. Thanks to Matthäus Wander for reporting the problem.
16
17 2014-06-21 Bob Halley <halley@dnspython.org>
18
19 * When reading from a masterfile, if the first content line
20 started with leading whitespace, we raised an ugly exception
21 instead of doing the right thing, namely using the zone origin as
22 the name. [#73] Thanks to Tassatux for reporting the issue.
23
24 * Added dns.zone.to_text() convenience method. Thanks to Brandon
25 Whaley <redkrieg@gmail.com> for the patch.
26
27 * The /etc/resolv.conf setting "options rotate" is now understood
28 by the resolver. If present, the resolver will shuffle the
29 nameserver list each time dns.resolver.query() is called. Thanks
30 to underrun for the patch. Note that you don't want to add
31 "options rotate" to your /etc/resolv.conf if your system's
32 resolver library does not understand it. In this case, just set
33 resolver.rotate = True by hand.
34
35 2014-06-19 Bob Halley <halley@dnspython.org>
36
37 * Escaping of Unicode has been corrected. Previously we escaped
38 and then converted to Unicode, but the right thing to do is
39 convert to Unicode, then escape. Also, characters > 0x7f should
40 NOT be escaped in Unicode mode. Thanks to Martin Basti for the
41 patch.
42
43 * dns.rdtypes.ANY.DNSKEY now has helpers functions to convert
44 between the numeric form of the flags and a set of human-friendly
45 strings. Thanks to Petr Spacek for the patch.
46
47 * RRSIGs did not respect relativization settings in to_text().
48 Thanks to Brian Smith for reporting the bug and submitting a
49 (slightly different) patch.
50
51 2014-06-18 Bob Halley <halley@dnspython.org>
52
53 * dns/rdtypes/IN/APL.py: The APL from_wire() method did not accept an
54 rdata length of 0 as valid. Thanks to salzmdan for reporting the
55 problem.
56
57 2014-05-31 Bob Halley <halley@dnspython.org>
58
59 * dns/ipv6.py: Add is_mapped()
60
61 * dns/reversename.py: Lookup IPv6 mapped IPv4 addresses in the v4
62 reverse namespace. Thanks to Devin Bayer. Yes, I finally fixed
63 this one :)
64
65 2014-04-11 Bob Halley <halley@dnspython.org>
66
67 * dns/zone.py: Do not put back an unescaped token. This was
68 causing escape processing for domain names to break. Thanks to
69 connormclaud for reporting the problem.
70
71 2014-04-04 Bob Halley <halley@dnspython.org>
72
73 * dns/message.py: Making a response didn't work correctly if the
74 query was signed with TSIG and we knew the key. Thanks to Jeffrey
75 Stiles for reporting the problem.
76
77 2013-12-11 Bob Halley <halley@dnspython.org>
78
79 * dns/query.py: Fix problems with the IXFR state machine which caused
80 long diffs to fail. Thanks to James Raftery for the fix and the
81 repeated prodding to get it applied :)
82
083 2013-09-02 Bob Halley <halley@dnspython.org>
184
285 * (Version 1.11.1 released)
00 Metadata-Version: 1.1
11 Name: dnspython
2 Version: 1.11.1
2 Version: 1.12.0
33 Summary: DNS toolkit
44 Home-page: http://www.dnspython.org
55 Author: Bob Halley
66 Author-email: halley@dnspython.org
77 License: BSD-like
8 Download-URL: http://www.dnspython.org/kits/1.11.1/dnspython-1.11.1.tar.gz
8 Download-URL: http://www.dnspython.org/kits/1.12.0/dnspython-1.12.0.tar.gz
99 Description: dnspython is a DNS toolkit for Python. It supports almost all
1010 record types. It can be used for queries, zone transfers, and dynamic
1111 updates. It supports TSIG authenticated messages and EDNS0.
2121
2222 ABOUT THIS RELEASE
2323
24 This is dnspython 1.11.1
24 This is dnspython 1.12.0
25
26 New since 1.11.1:
27
28 Added dns.zone.to_text().
29
30 Added support for "options rotate" in /etc/resolv.conf.
31
32 dns.rdtypes.ANY.DNSKEY now has helpers functions to convert
33 between the numeric form of the flags and a set of
34 human-friendly strings
35
36 The reverse name of an IPv6 mapped IPv4 address is now in the
37 IPv4 reverse namespace.
38
39 The test system can now run the tests without requiring
40 dnspython to be installed.
41
42 Preliminary Elliptic Curve DNSSEC Validation (requires ecdsa module)
43
44 Bugs fixed since 1.11.1:
45
46 dnspython raised an exception when reading a masterfile starting
47 with leading whitespace
48
49 dnspython was affected by a python slicing API bug present on
50 64-bit windows.
51
52 Unicode escaping was applied at the wrong time.
53
54 RRSIG to_text() did not respect the relativize setting.
55
56 APL RRs with zero rdlength were rejected.
57
58 The tokenizer could put back an unescaped token.
59
60 Making a response to a message signed with TSIG was broken.
61
62 The IXFR state machine didn't handle long IXFR diffs.
2563
2664 New since 1.11.0:
2765
2866 Nothing
2967
30 Bugs fixed since 1.11.1:
68 Bugs fixed since 1.11.0:
3169
3270 dns.resolver.Resolver erroneously referred to 'retry_servfail'
3371 instead of 'self.retry_servfail'.
4444 RSASHA1NSEC3SHA1 = 7
4545 RSASHA256 = 8
4646 RSASHA512 = 10
47 ECDSAP256SHA256 = 13
48 ECDSAP384SHA384 = 14
4749 INDIRECT = 252
4850 PRIVATEDNS = 253
4951 PRIVATEOID = 254
5961 'RSASHA256' : RSASHA256,
6062 'RSASHA512' : RSASHA512,
6163 'INDIRECT' : INDIRECT,
64 'ECDSAP256SHA256' : ECDSAP256SHA256,
65 'ECDSAP384SHA384' : ECDSAP384SHA384,
6266 'PRIVATEDNS' : PRIVATEDNS,
6367 'PRIVATEOID' : PRIVATEOID,
6468 }
152156 def _is_dsa(algorithm):
153157 return algorithm in (DSA, DSANSEC3SHA1)
154158
159 def _is_ecdsa(algorithm):
160 return _have_ecdsa and (algorithm in (ECDSAP256SHA256, ECDSAP384SHA384))
161
155162 def _is_md5(algorithm):
156163 return algorithm == RSAMD5
157164
160167 DSANSEC3SHA1, RSASHA1NSEC3SHA1)
161168
162169 def _is_sha256(algorithm):
163 return algorithm == RSASHA256
170 return algorithm in (RSASHA256, ECDSAP256SHA256)
171
172 def _is_sha384(algorithm):
173 return algorithm == ECDSAP384SHA384
164174
165175 def _is_sha512(algorithm):
166176 return algorithm == RSASHA512
172182 return dns.hash.get('SHA1')()
173183 if _is_sha256(algorithm):
174184 return dns.hash.get('SHA256')()
185 if _is_sha384(algorithm):
186 return dns.hash.get('SHA384')()
175187 if _is_sha512(algorithm):
176188 return dns.hash.get('SHA512')()
177189 raise ValidationFailure, 'unknown hash for algorithm %u' % algorithm
273285 (dsa_r, dsa_s) = struct.unpack('!20s20s', rrsig.signature[1:])
274286 sig = (Crypto.Util.number.bytes_to_long(dsa_r),
275287 Crypto.Util.number.bytes_to_long(dsa_s))
288 elif _is_ecdsa(rrsig.algorithm):
289 if rrsig.algorithm == ECDSAP256SHA256:
290 curve = ecdsa.curves.NIST256p
291 key_len = 32
292 digest_len = 32
293 elif rrsig.algorithm == ECDSAP384SHA384:
294 curve = ecdsa.curves.NIST384p
295 key_len = 48
296 digest_len = 48
297 else:
298 # shouldn't happen
299 raise ValidationFailure, 'unknown ECDSA curve'
300 keyptr = candidate_key.key
301 x = Crypto.Util.number.bytes_to_long(keyptr[0:key_len])
302 y = Crypto.Util.number.bytes_to_long(keyptr[key_len:key_len * 2])
303 assert ecdsa.ecdsa.point_is_valid(curve.generator, x, y)
304 point = ecdsa.ellipticcurve.Point(curve.curve, x, y, curve.order)
305 verifying_key = ecdsa.keys.VerifyingKey.from_public_point(point,
306 curve)
307 pubkey = ECKeyWrapper(verifying_key, key_len)
308 r = rrsig.signature[:key_len]
309 s = rrsig.signature[key_len:]
310 sig = ecdsa.ecdsa.Signature(Crypto.Util.number.bytes_to_long(r),
311 Crypto.Util.number.bytes_to_long(s))
276312 else:
277313 raise ValidationFailure, 'unknown algorithm %u' % rrsig.algorithm
278314
301337 digest = _make_algorithm_id(rrsig.algorithm) + digest
302338 padlen = keylen // 8 - len(digest) - 3
303339 digest = chr(0) + chr(1) + chr(0xFF) * padlen + chr(0) + digest
304 elif _is_dsa(rrsig.algorithm):
340 elif _is_dsa(rrsig.algorithm) or _is_ecdsa(rrsig.algorithm):
305341 pass
306342 else:
307343 # Raise here for code clarity; this won't actually ever happen
368404 import Crypto.Util.number
369405 validate = _validate
370406 validate_rrsig = _validate_rrsig
407 _have_pycrypto = True
371408 except ImportError:
372409 validate = _need_pycrypto
373410 validate_rrsig = _need_pycrypto
411 _have_pycrypto = False
412
413 try:
414 import ecdsa
415 import ecdsa.ecdsa
416 import ecdsa.ellipticcurve
417 import ecdsa.keys
418 _have_ecdsa = True
419
420 class ECKeyWrapper(object):
421 def __init__(self, key, key_len):
422 self.key = key
423 self.key_len = key_len
424 def verify(self, digest, sig):
425 diglong = Crypto.Util.number.bytes_to_long(digest)
426 return self.key.pubkey.verifies(diglong, sig)
427
428 except ImportError:
429 _have_ecdsa = False
160160 return text.decode('hex_codec')
161161 except TypeError:
162162 raise dns.exception.SyntaxError
163
164 _mapped_prefix = '\x00' * 10 + '\xff\xff'
165
166 def is_mapped(address):
167 return address.startswith(_mapped_prefix)
664664 secret = self.message.keyring.get(absolute_name)
665665 if secret is None:
666666 raise UnknownTSIGKey("key '%s' unknown" % name)
667 self.message.keyname = absolute_name
668 (self.message.keyalgorithm, self.message.mac) = \
669 dns.tsig.get_algorithm_and_mac(self.wire, self.current,
670 rdlen)
667671 self.message.tsig_ctx = \
668672 dns.tsig.validate(self.wire,
669673 absolute_name,
10701074 m.want_dnssec(want_dnssec)
10711075 return m
10721076
1073 def make_response(query, recursion_available=False, our_payload=8192):
1077 def make_response(query, recursion_available=False, our_payload=8192,
1078 fudge=300):
10741079 """Make a message which is a response for the specified query.
10751080 The message returned is really a response skeleton; it has all
10761081 of the infrastructure required of a response, but none of the
10871092 @param our_payload: payload size to advertise in EDNS responses; default
10881093 is 8192.
10891094 @type our_payload: int
1095 @param fudge: TSIG time fudge; default is 300 seconds.
1096 @type fudge: int
10901097 @rtype: dns.message.Message object"""
10911098
10921099 if query.flags & dns.flags.QR:
10991106 response.question = list(query.question)
11001107 if query.edns >= 0:
11011108 response.use_edns(0, 0, our_payload, query.payload)
1102 if not query.keyname is None:
1103 response.keyname = query.keyname
1104 response.keyring = query.keyring
1109 if query.had_tsig:
1110 response.use_tsig(query.keyring, query.keyname, fudge, None, 0, '',
1111 query.keyalgorithm)
11051112 response.request_mac = query.mac
11061113 return response
2323 import cStringIO
2424 import struct
2525 import sys
26 import copy
2627
2728 if sys.hexversion >= 0x02030000:
2829 import encodings.idna
8687 '$' : True
8788 }
8889
89 def _escapify(label):
90 def _escapify(label, unicode_mode=False):
9091 """Escape the characters in label which need it.
92 @param unicode_mode: escapify only special and whitespace (<= 0x20)
93 characters
9194 @returns: the escaped string
9295 @rtype: string"""
9396 text = ''
97100 elif ord(c) > 0x20 and ord(c) < 0x7F:
98101 text += c
99102 else:
100 text += '\\%03d' % ord(c)
103 if unicode_mode and ord(c) >= 0x7F:
104 text += c
105 else:
106 text += '\\%03d' % ord(c)
101107 return text
102108
103109 def _validate_labels(labels):
147153
148154 def __setattr__(self, name, value):
149155 raise TypeError("object doesn't support attribute assignment")
156
157 def __copy__(self):
158 return Name(self.labels)
159
160 def __deepcopy__(self, memo):
161 return Name(copy.deepcopy(self.labels, memo))
150162
151163 def is_absolute(self):
152164 """Is the most significant label of this name the root label?
344356 l = self.labels[:-1]
345357 else:
346358 l = self.labels
347 s = u'.'.join([encodings.idna.ToUnicode(_escapify(x)) for x in l])
359 s = u'.'.join([_escapify(encodings.idna.ToUnicode(x), True) for x in l])
348360 return s
349361
350362 def to_digestable(self, origin=None):
410410 tcpmsg = struct.pack("!H", l) + wire
411411 _net_write(s, tcpmsg, expiration)
412412 done = False
413 delete_mode = True
414 expecting_SOA = False
413415 soa_rrset = None
414416 soa_count = 0
415417 if relativize:
438440 tsig_ctx = r.tsig_ctx
439441 first = False
440442 answer_index = 0
441 delete_mode = False
442 expecting_SOA = False
443443 if soa_rrset is None:
444444 if not r.answer or r.answer[0].name != oname:
445 raise dns.exception.FormError
445 raise dns.exception.FormError("No answer or RRset not for qname")
446446 rrset = r.answer[0]
447447 if rrset.rdtype != dns.rdatatype.SOA:
448448 raise dns.exception.FormError("first RRset is not an SOA")
449449 answer_index = 1
450450 soa_rrset = rrset.copy()
451451 if rdtype == dns.rdatatype.IXFR:
452 if soa_rrset[0].serial == serial:
452 if soa_rrset[0].serial <= serial:
453453 #
454454 # We're already up-to-date.
455455 #
470470 expecting_SOA = False
471471 elif rdtype == dns.rdatatype.IXFR:
472472 delete_mode = not delete_mode
473 if rrset == soa_rrset and not delete_mode:
473 #
474 # If this SOA RRset is equal to the first we saw then we're
475 # finished. If this is an IXFR we also check that we're seeing
476 # the record in the expected part of the response.
477 #
478 if rrset == soa_rrset and \
479 (rdtype == dns.rdatatype.AXFR or \
480 (rdtype == dns.rdatatype.IXFR and delete_mode)):
474481 done = True
475482 elif expecting_SOA:
476483 #
1919 import dns.dnssec
2020 import dns.rdata
2121
22
2223 # flag constants
2324 SEP = 0x0001
2425 REVOKE = 0x0080
2526 ZONE = 0x0100
27
28 _flag_by_text = {
29 'SEP': SEP,
30 'REVOKE': REVOKE,
31 'ZONE': ZONE
32 }
33
34 # We construct the inverse mapping programmatically to ensure that we
35 # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
36 # would cause the mapping not to be true inverse.
37 _flag_by_value = dict([(y, x) for x, y in _flag_by_text.iteritems()])
38
39
40 def flags_to_text_set(flags):
41 """Convert a DNSKEY flags value to set texts
42 @rtype: set([string])"""
43
44 flags_set = set()
45 mask = 0x1
46 while mask <= 0x8000:
47 if flags & mask:
48 text = _flag_by_value.get(mask)
49 if not text:
50 text = hex(mask)
51 flags_set.add(text)
52 mask <<= 1
53 return flags_set
54
55
56 def flags_from_text_set(texts_set):
57 """Convert set of DNSKEY flag mnemonic texts to DNSKEY flag value
58 @rtype: int"""
59
60 flags = 0
61 for text in texts_set:
62 try:
63 flags += _flag_by_text[text]
64 except KeyError:
65 raise NotImplementedError(
66 "DNSKEY flag '%s' is not supported" % text)
67 return flags
68
2669
2770 class DNSKEY(dns.rdata.Rdata):
2871 """DNSKEY record
91134 if v == 0:
92135 v = cmp(self.key, other.key)
93136 return v
137
138 def flags_to_text_set(self):
139 """Convert a DNSKEY flags value to set texts
140 @rtype: set([string])"""
141 return flags_to_text_set(self.flags)
2121 _pows = (1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L,
2222 100000000L, 1000000000L, 10000000000L)
2323
24 # default values are in centimeters
25 _default_size = 100.0
26 _default_hprec = 1000000.0
27 _default_vprec = 1000.0
28
2429 def _exponent_of(what, desc):
30 if what == 0:
31 return 0
2532 exp = None
2633 for i in xrange(len(_pows)):
2734 if what // _pows[i] == 0L:
97104 'horizontal_precision', 'vertical_precision']
98105
99106 def __init__(self, rdclass, rdtype, latitude, longitude, altitude,
100 size=1.0, hprec=10000.0, vprec=10.0):
107 size=_default_size, hprec=_default_hprec, vprec=_default_vprec):
101108 """Initialize a LOC record instance.
102109
103110 The parameters I{latitude} and I{longitude} may be either a 4-tuple
104111 of integers specifying (degrees, minutes, seconds, milliseconds),
105112 or they may be floating point values specifying the number of
106 degrees. The other parameters are floats."""
113 degrees. The other parameters are floats. Size, horizontal precision,
114 and vertical precision are specified in centimeters."""
107115
108116 super(LOC, self).__init__(rdclass, rdtype)
109117 if isinstance(latitude, int) or isinstance(latitude, long):
140148 self.longitude[3], long_hemisphere, self.altitude / 100.0
141149 )
142150
143 if self.size != 1.0 or self.horizontal_precision != 10000.0 or \
144 self.vertical_precision != 10.0:
151 # do not print default values
152 if self.size != _default_size or \
153 self.horizontal_precision != _default_hprec or \
154 self.vertical_precision != _default_vprec:
145155 text += " %0.2fm %0.2fm %0.2fm" % (
146156 self.size / 100.0, self.horizontal_precision / 100.0,
147157 self.vertical_precision / 100.0
151161 def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
152162 latitude = [0, 0, 0, 0]
153163 longitude = [0, 0, 0, 0]
154 size = 1.0
155 hprec = 10000.0
156 vprec = 10.0
164 size = _default_size
165 hprec = _default_hprec
166 vprec = _default_vprec
157167
158168 latitude[0] = tok.get_int()
159169 t = tok.get_string()
239249 value = token.value
240250 if value[-1] == 'm':
241251 value = value[0 : -1]
242 vprec = float(value) * 100.0 # m -> cm
243 tok.get_eol()
252 vprec = float(value) * 100.0 # m -> cm
253 tok.get_eol()
244254
245255 return cls(rdclass, rdtype, latitude, longitude, altitude,
246256 size, hprec, vprec)
5555 salt = ''
5656 else:
5757 salt = salt.decode('hex-codec')
58 tok.get_eol()
5859 return cls(rdclass, rdtype, algorithm, flags, iterations, salt)
5960
6061 from_text = classmethod(from_text)
9292 posixtime_to_sigtime(self.expiration),
9393 posixtime_to_sigtime(self.inception),
9494 self.key_tag,
95 self.signer,
95 self.signer.choose_relativity(origin, relativize),
9696 dns.rdata._base64ify(self.signature)
9797 )
9898
117117 def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
118118 items = []
119119 while 1:
120 if rdlen == 0:
121 break
120122 if rdlen < 4:
121123 raise dns.exception.FormError
122124 header = struct.unpack('!HBB', wire[current : current + 4])
150152 rdlen -= afdlen
151153 item = APLItem(header[0], negation, address, header[1])
152154 items.append(item)
153 if rdlen == 0:
154 break
155155 return cls(rdclass, rdtype, items)
156156
157157 from_wire = classmethod(from_wire)
2020 import socket
2121 import sys
2222 import time
23 import random
2324
2425 try:
2526 import threading as _threading
507508 self.cache = None
508509 self.flags = None
509510 self.retry_servfail = False
511 self.rotate = False
510512
511513 def read_resolv_conf(self, f):
512514 """Process f as a file in the /etc/resolv.conf format. If f is
537539 elif tokens[0] == 'search':
538540 for suffix in tokens[1:]:
539541 self.search.append(dns.name.from_text(suffix))
542 elif tokens[0] == 'options':
543 if 'rotate' in tokens[1:]:
544 self.rotate = True
540545 finally:
541546 if want_close:
542547 f.close()
810815 # make a copy of the servers list so we can alter it later.
811816 #
812817 nameservers = self.nameservers[:]
818 if self.rotate:
819 random.shuffle(nameservers)
813820 backoff = 0.10
814821 while response is None:
815822 if len(nameservers) == 0:
3636 @rtype: dns.name.Name object
3737 """
3838 try:
39 parts = list(dns.ipv6.inet_aton(text).encode('hex_codec'))
40 origin = ipv6_reverse_domain
39 v6 = dns.ipv6.inet_aton(text)
40 if dns.ipv6.is_mapped(v6):
41 parts = ['%d' % ord(byte) for byte in v6[12:]]
42 origin = ipv4_reverse_domain
43 else:
44 parts = list(v6.encode('hex_codec'))
45 origin = ipv6_reverse_domain
4146 except:
4247 parts = ['%d' % ord(byte) for byte in dns.ipv4.inet_aton(text)]
4348 origin = ipv4_reverse_domain
220220 except KeyError:
221221 raise NotImplementedError("TSIG algorithm " + str(algorithm) +
222222 " is not supported")
223
224 def get_algorithm_and_mac(wire, tsig_rdata, tsig_rdlen):
225 """Return the tsig algorithm for the specified tsig_rdata
226 @raises FormError: The TSIG is badly formed.
227 """
228 current = tsig_rdata
229 (aname, used) = dns.name.from_wire(wire, current)
230 current = current + used
231 (upper_time, lower_time, fudge, mac_size) = \
232 struct.unpack("!HIHH", wire[current:current + 10])
233 current += 10
234 mac = wire[current:current + mac_size]
235 current += mac_size
236 if current > tsig_rdata + tsig_rdlen:
237 raise dns.exception.FormError
238 return (aname, mac)
1515 """dnspython release version information."""
1616
1717 MAJOR = 1
18 MINOR = 11
19 MICRO = 1
18 MINOR = 12
19 MICRO = 0
2020 RELEASELEVEL = 0x0f
2121 SERIAL = 0
2222
1818
1919 import dns.exception
2020
21 # Figure out what constant python passes for an unspecified slice bound.
22 # It's supposed to be sys.maxint, yet on 64-bit windows sys.maxint is 2^31 - 1
23 # but Python uses 2^63 - 1 as the constant. Rather than making pointless
24 # extra comparisons, duplicating code, or weakening WireData, we just figure
25 # out what constant Python will use.
26
27 class _SliceUnspecifiedBound(str):
28 def __getslice__(self, i, j):
29 return j
30
31 _unspecified_bound = _SliceUnspecifiedBound('')[1:]
32
2133 class WireData(str):
2234 # WireData is a string with stricter slicing
2335 def __getitem__(self, key):
2739 raise dns.exception.FormError
2840 def __getslice__(self, i, j):
2941 try:
30 if j == sys.maxint:
42 if j == _unspecified_bound:
3143 # handle the case where the right bound is unspecified
3244 j = len(self)
3345 if i < 0 or j < 0:
3030 import dns.ttl
3131 import dns.grange
3232
33 try:
34 from cStringIO import StringIO
35 except ImportError:
36 from io import StringIO
3337
3438 class BadZone(dns.exception.DNSException):
3539 """The zone is malformed."""
504508 finally:
505509 if want_close:
506510 f.close()
511
512 def to_text(self, sorted=True, relativize=True, nl=None):
513 """Return a zone's text as though it were written to a file.
514
515 @param sorted: if True, the file will be written with the
516 names sorted in DNSSEC order from least to greatest. Otherwise
517 the names will be written in whatever order they happen to have
518 in the zone's dictionary.
519 @param relativize: if True, domain names in the output will be
520 relativized to the zone's origin (if possible).
521 @type relativize: bool
522 @param nl: The end of line string. If not specified, the
523 output will use the platform's native end-of-line marker (i.e.
524 LF on POSIX, CRLF on Windows, CR on Macintosh).
525 @type nl: string or None
526 """
527 temp_buffer = StringIO()
528 self.to_file(temp_buffer, sorted, relativize, nl)
529 return_value = temp_buffer.getvalue()
530 temp_buffer.close()
531 return return_value
507532
508533 def check_origin(self):
509534 """Do some simple checking of the zone's origin.
557582 self.current_origin = origin
558583 self.relativize = relativize
559584 self.ttl = 0
560 self.last_name = None
585 self.last_name = self.current_origin
561586 self.zone = zone_factory(origin, rdclass, relativize=relativize)
562587 self.saved_state = []
563588 self.current_file = None
812837
813838 try:
814839 while 1:
815 token = self.tok.get(True, True).unescape()
840 token = self.tok.get(True, True)
816841 if token.is_eof():
817842 if not self.current_file is None:
818843 self.current_file.close()
1717 import sys
1818 from distutils.core import setup
1919
20 version = '1.11.1'
20 version = '1.12.0'
2121
2222 kwargs = {
2323 'name' : 'dnspython',
1919 check: test
2020
2121 test:
22 @for i in *.py; do \
23 echo "Running $$i:"; \
24 ${PYTHON} $$i || exit 1; \
25 done
22 ${PYTHON} ./utest.py
+0
-49
tests/bugs.py less more
0 # Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.rdata
18 import dns.rdataclass
19 import dns.rdatatype
20 import dns.ttl
21
22 class BugsTestCase(unittest.TestCase):
23
24 def test_float_LOC(self):
25 rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.LOC,
26 "30 30 0.000 N 100 30 0.000 W 10.00m 20m 2000m 20m")
27 self.failUnless(rdata.float_latitude == 30.5)
28 self.failUnless(rdata.float_longitude == -100.5)
29
30 def test_SOA_BIND8_TTL(self):
31 rdata1 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
32 "a b 100 1s 1m 1h 1d")
33 rdata2 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
34 "a b 100 1 60 3600 86400")
35 self.failUnless(rdata1 == rdata2)
36
37 def test_TTL_bounds_check(self):
38 def bad():
39 ttl = dns.ttl.from_text("2147483648")
40 self.failUnlessRaises(dns.ttl.BadTTL, bad)
41
42 def test_empty_NSEC3_window(self):
43 rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NSEC3,
44 "1 0 100 ABCD SCBCQHKU35969L2A68P3AD59LHF30715")
45 self.failUnless(rdata.windows == [])
46
47 if __name__ == '__main__':
48 unittest.main()
+0
-156
tests/dnssec.py less more
0 # Copyright (C) 2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.dnssec
18 import dns.name
19 import dns.rdata
20 import dns.rdataclass
21 import dns.rdatatype
22 import dns.rrset
23
24 abs_dnspython_org = dns.name.from_text('dnspython.org')
25
26 abs_keys = { abs_dnspython_org :
27 dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'DNSKEY',
28 '257 3 5 AwEAAenVTr9L1OMlL1/N2ta0Qj9LLLnnmFWIr1dJoAsWM9BQfsbV7kFZ XbAkER/FY9Ji2o7cELxBwAsVBuWn6IUUAJXLH74YbC1anY0lifjgt29z SwDzuB7zmC7yVYZzUunBulVW4zT0tg1aePbpVL2EtTL8VzREqbJbE25R KuQYHZtFwG8S4iBxJUmT2Bbd0921LLxSQgVoFXlQx/gFV2+UERXcJ5ce iX6A6wc02M/pdg/YbJd2rBa0MYL3/Fz/Xltre0tqsImZGxzi6YtYDs45 NC8gH+44egz82e2DATCVM1ICPmRDjXYTLldQiWA2ZXIWnK0iitl5ue24 7EsWJefrIhE=',
29 '256 3 5 AwEAAdSSghOGjU33IQZgwZM2Hh771VGXX05olJK49FxpSyuEAjDBXY58 LGU9R2Zgeecnk/b9EAhFu/vCV9oECtiTCvwuVAkt9YEweqYDluQInmgP NGMJCKdSLlnX93DkjDw8rMYv5dqXCuSGPlKChfTJOLQxIAxGloS7lL+c 0CTZydAF')
30 }
31
32 abs_keys_duplicate_keytag = { abs_dnspython_org :
33 dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'DNSKEY',
34 '257 3 5 AwEAAenVTr9L1OMlL1/N2ta0Qj9LLLnnmFWIr1dJoAsWM9BQfsbV7kFZ XbAkER/FY9Ji2o7cELxBwAsVBuWn6IUUAJXLH74YbC1anY0lifjgt29z SwDzuB7zmC7yVYZzUunBulVW4zT0tg1aePbpVL2EtTL8VzREqbJbE25R KuQYHZtFwG8S4iBxJUmT2Bbd0921LLxSQgVoFXlQx/gFV2+UERXcJ5ce iX6A6wc02M/pdg/YbJd2rBa0MYL3/Fz/Xltre0tqsImZGxzi6YtYDs45 NC8gH+44egz82e2DATCVM1ICPmRDjXYTLldQiWA2ZXIWnK0iitl5ue24 7EsWJefrIhE=',
35 '256 3 5 AwEAAdSSg++++THIS/IS/NOT/THE/CORRECT/KEY++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AaOSydAF',
36 '256 3 5 AwEAAdSSghOGjU33IQZgwZM2Hh771VGXX05olJK49FxpSyuEAjDBXY58 LGU9R2Zgeecnk/b9EAhFu/vCV9oECtiTCvwuVAkt9YEweqYDluQInmgP NGMJCKdSLlnX93DkjDw8rMYv5dqXCuSGPlKChfTJOLQxIAxGloS7lL+c 0CTZydAF')
37 }
38
39 rel_keys = { dns.name.empty :
40 dns.rrset.from_text('@', 3600, 'IN', 'DNSKEY',
41 '257 3 5 AwEAAenVTr9L1OMlL1/N2ta0Qj9LLLnnmFWIr1dJoAsWM9BQfsbV7kFZ XbAkER/FY9Ji2o7cELxBwAsVBuWn6IUUAJXLH74YbC1anY0lifjgt29z SwDzuB7zmC7yVYZzUunBulVW4zT0tg1aePbpVL2EtTL8VzREqbJbE25R KuQYHZtFwG8S4iBxJUmT2Bbd0921LLxSQgVoFXlQx/gFV2+UERXcJ5ce iX6A6wc02M/pdg/YbJd2rBa0MYL3/Fz/Xltre0tqsImZGxzi6YtYDs45 NC8gH+44egz82e2DATCVM1ICPmRDjXYTLldQiWA2ZXIWnK0iitl5ue24 7EsWJefrIhE=',
42 '256 3 5 AwEAAdSSghOGjU33IQZgwZM2Hh771VGXX05olJK49FxpSyuEAjDBXY58 LGU9R2Zgeecnk/b9EAhFu/vCV9oECtiTCvwuVAkt9YEweqYDluQInmgP NGMJCKdSLlnX93DkjDw8rMYv5dqXCuSGPlKChfTJOLQxIAxGloS7lL+c 0CTZydAF')
43 }
44
45 when = 1290250287
46
47 abs_soa = dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'SOA',
48 'howl.dnspython.org. hostmaster.dnspython.org. 2010020047 3600 1800 604800 3600')
49
50 abs_other_soa = dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'SOA',
51 'foo.dnspython.org. hostmaster.dnspython.org. 2010020047 3600 1800 604800 3600')
52
53 abs_soa_rrsig = dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'RRSIG',
54 'SOA 5 2 3600 20101127004331 20101119213831 61695 dnspython.org. sDUlltRlFTQw5ITFxOXW3TgmrHeMeNpdqcZ4EXxM9FHhIlte6V9YCnDw t6dvM9jAXdIEi03l9H/RAd9xNNW6gvGMHsBGzpvvqFQxIBR2PoiZA1mX /SWHZFdbt4xjYTtXqpyYvrMK0Dt7bUYPadyhPFCJ1B+I8Zi7B5WJEOd0 8vs=')
55
56 rel_soa = dns.rrset.from_text('@', 3600, 'IN', 'SOA',
57 'howl hostmaster 2010020047 3600 1800 604800 3600')
58
59 rel_other_soa = dns.rrset.from_text('@', 3600, 'IN', 'SOA',
60 'foo hostmaster 2010020047 3600 1800 604800 3600')
61
62 rel_soa_rrsig = dns.rrset.from_text('@', 3600, 'IN', 'RRSIG',
63 'SOA 5 2 3600 20101127004331 20101119213831 61695 @ sDUlltRlFTQw5ITFxOXW3TgmrHeMeNpdqcZ4EXxM9FHhIlte6V9YCnDw t6dvM9jAXdIEi03l9H/RAd9xNNW6gvGMHsBGzpvvqFQxIBR2PoiZA1mX /SWHZFdbt4xjYTtXqpyYvrMK0Dt7bUYPadyhPFCJ1B+I8Zi7B5WJEOd0 8vs=')
64
65 sep_key = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DNSKEY,
66 '257 3 5 AwEAAenVTr9L1OMlL1/N2ta0Qj9LLLnnmFWIr1dJoAsWM9BQfsbV7kFZ XbAkER/FY9Ji2o7cELxBwAsVBuWn6IUUAJXLH74YbC1anY0lifjgt29z SwDzuB7zmC7yVYZzUunBulVW4zT0tg1aePbpVL2EtTL8VzREqbJbE25R KuQYHZtFwG8S4iBxJUmT2Bbd0921LLxSQgVoFXlQx/gFV2+UERXcJ5ce iX6A6wc02M/pdg/YbJd2rBa0MYL3/Fz/Xltre0tqsImZGxzi6YtYDs45 NC8gH+44egz82e2DATCVM1ICPmRDjXYTLldQiWA2ZXIWnK0iitl5ue24 7EsWJefrIhE=')
67
68 good_ds = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DS,
69 '57349 5 2 53A79A3E7488AB44FFC56B2D1109F0699D1796DD977E72108B841F96 E47D7013')
70
71 when2 = 1290425644
72
73 abs_example = dns.name.from_text('example')
74
75 abs_dsa_keys = { abs_example :
76 dns.rrset.from_text('example.', 86400, 'IN', 'DNSKEY',
77 '257 3 3 CI3nCqyJsiCJHTjrNsJOT4RaszetzcJPYuoH3F9ZTVt3KJXncCVR3bwn 1w0iavKljb9hDlAYSfHbFCp4ic/rvg4p1L8vh5s8ToMjqDNl40A0hUGQ Ybx5hsECyK+qHoajilUX1phYSAD8d9WAGO3fDWzUPBuzR7o85NiZCDxz yXuNVfni0uhj9n1KYhEO5yAbbruDGN89wIZcxMKuQsdUY2GYD93ssnBv a55W6XRABYWayKZ90WkRVODLVYLSn53Pj/wwxGH+XdhIAZJXimrZL4yl My7rtBsLMqq8Ihs4Tows7LqYwY7cp6y/50tw6pj8tFqMYcPUjKZV36l1 M/2t5BVg3i7IK61Aidt6aoC3TDJtzAxg3ZxfjZWJfhHjMJqzQIfbW5b9 q1mjFsW5EUv39RaNnX+3JWPRLyDqD4pIwDyqfutMsdk/Py3paHn82FGp CaOg+nicqZ9TiMZURN/XXy5JoXUNQ3RNvbHCUiPUe18KUkY6mTfnyHld 1l9YCWmzXQVClkx/hOYxjJ4j8Ife58+Obu5X',
78 '256 3 3 CJE1yb9YRQiw5d2xZrMUMR+cGCTt1bp1KDCefmYKmS+Z1+q9f42ETVhx JRiQwXclYwmxborzIkSZegTNYIV6mrYwbNB27Q44c3UGcspb3PiOw5TC jNPRYEcdwGvDZ2wWy+vkSV/S9tHXY8O6ODiE6abZJDDg/RnITyi+eoDL R3KZ5n/V1f1T1b90rrV6EewhBGQJpQGDogaXb2oHww9Tm6NfXyo7SoMM pbwbzOckXv+GxRPJIQNSF4D4A9E8XCksuzVVdE/0lr37+uoiAiPia38U 5W2QWe/FJAEPLjIp2eTzf0TrADc1pKP1wrA2ASpdzpm/aX3IB5RPp8Ew S9U72eBFZJAUwg635HxJVxH1maG6atzorR566E+e0OZSaxXS9o1o6QqN 3oPlYLGPORDiExilKfez3C/x/yioOupW9K5eKF0gmtaqrHX0oq9s67f/ RIM2xVaKHgG9Vf2cgJIZkhv7sntujr+E4htnRmy9P9BxyFxsItYxPI6Z bzygHAZpGhlI/7ltEGlIwKxyTK3ZKBm67q7B')
79 }
80
81 abs_dsa_soa = dns.rrset.from_text('example.', 86400, 'IN', 'SOA',
82 'ns1.example. hostmaster.example. 2 10800 3600 604800 86400')
83
84 abs_other_dsa_soa = dns.rrset.from_text('example.', 86400, 'IN', 'SOA',
85 'ns1.example. hostmaster.example. 2 10800 3600 604800 86401')
86
87 abs_dsa_soa_rrsig = dns.rrset.from_text('example.', 86400, 'IN', 'RRSIG',
88 'SOA 3 1 86400 20101129143231 20101122112731 42088 example. CGul9SuBofsktunV8cJs4eRs6u+3NCS3yaPKvBbD+pB2C76OUXDZq9U=')
89
90 example_sep_key = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DNSKEY,
91 '257 3 3 CI3nCqyJsiCJHTjrNsJOT4RaszetzcJPYuoH3F9ZTVt3KJXncCVR3bwn 1w0iavKljb9hDlAYSfHbFCp4ic/rvg4p1L8vh5s8ToMjqDNl40A0hUGQ Ybx5hsECyK+qHoajilUX1phYSAD8d9WAGO3fDWzUPBuzR7o85NiZCDxz yXuNVfni0uhj9n1KYhEO5yAbbruDGN89wIZcxMKuQsdUY2GYD93ssnBv a55W6XRABYWayKZ90WkRVODLVYLSn53Pj/wwxGH+XdhIAZJXimrZL4yl My7rtBsLMqq8Ihs4Tows7LqYwY7cp6y/50tw6pj8tFqMYcPUjKZV36l1 M/2t5BVg3i7IK61Aidt6aoC3TDJtzAxg3ZxfjZWJfhHjMJqzQIfbW5b9 q1mjFsW5EUv39RaNnX+3JWPRLyDqD4pIwDyqfutMsdk/Py3paHn82FGp CaOg+nicqZ9TiMZURN/XXy5JoXUNQ3RNvbHCUiPUe18KUkY6mTfnyHld 1l9YCWmzXQVClkx/hOYxjJ4j8Ife58+Obu5X')
92
93 example_ds_sha1 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DS,
94 '18673 3 1 71b71d4f3e11bbd71b4eff12cde69f7f9215bbe7')
95
96 example_ds_sha256 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DS,
97 '18673 3 2 eb8344cbbf07c9d3d3d6c81d10c76653e28d8611a65e639ef8f716e4e4e5d913')
98
99 class DNSSECValidatorTestCase(unittest.TestCase):
100
101 def testAbsoluteRSAGood(self):
102 dns.dnssec.validate(abs_soa, abs_soa_rrsig, abs_keys, None, when)
103
104 def testDuplicateKeytag(self):
105 dns.dnssec.validate(abs_soa, abs_soa_rrsig, abs_keys_duplicate_keytag, None, when)
106
107 def testAbsoluteRSABad(self):
108 def bad():
109 dns.dnssec.validate(abs_other_soa, abs_soa_rrsig, abs_keys, None,
110 when)
111 self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
112
113 def testRelativeRSAGood(self):
114 dns.dnssec.validate(rel_soa, rel_soa_rrsig, rel_keys,
115 abs_dnspython_org, when)
116
117 def testRelativeRSABad(self):
118 def bad():
119 dns.dnssec.validate(rel_other_soa, rel_soa_rrsig, rel_keys,
120 abs_dnspython_org, when)
121 self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
122
123 def testMakeSHA256DS(self):
124 ds = dns.dnssec.make_ds(abs_dnspython_org, sep_key, 'SHA256')
125 self.failUnless(ds == good_ds)
126
127 def testAbsoluteDSAGood(self):
128 dns.dnssec.validate(abs_dsa_soa, abs_dsa_soa_rrsig, abs_dsa_keys, None,
129 when2)
130
131 def testAbsoluteDSABad(self):
132 def bad():
133 dns.dnssec.validate(abs_other_dsa_soa, abs_dsa_soa_rrsig,
134 abs_dsa_keys, None, when2)
135 self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
136
137 def testMakeExampleSHA1DS(self):
138 ds = dns.dnssec.make_ds(abs_example, example_sep_key, 'SHA1')
139 self.failUnless(ds == example_ds_sha1)
140
141 def testMakeExampleSHA256DS(self):
142 ds = dns.dnssec.make_ds(abs_example, example_sep_key, 'SHA256')
143 self.failUnless(ds == example_ds_sha256)
144
145 if __name__ == '__main__':
146 import_ok = False
147 try:
148 import Crypto.Util.number
149 import_ok = True
150 except:
151 pass
152 if import_ok:
153 unittest.main()
154 else:
155 print 'skipping DNSSEC tests because pycrypto is not installed'
0 @ 300 IN SOA ns1 hostmaster 1 2000 2000 1814400 3600
1 @ 300 IN NS ns1
2 @ 300 IN NS ns2
3 * 300 IN MX 10 mail
4 a 300 IN TXT "foo foo foo"
5 a 300 IN PTR foo.net.
6 a01 3600 IN A 0.0.0.0
7 a02 3600 IN A 255.255.255.255
8 aaaa01 3600 IN AAAA ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
9 aaaa02 3600 IN AAAA ::1
10 afsdb01 3600 IN AFSDB 0 hostname
11 afsdb02 3600 IN AFSDB 65535 .
12 apl01 3600 IN APL 1:192.168.32.0/21 !1:192.168.38.0/28
13 apl02 3600 IN APL 1:224.0.0.0/4 2:FF00:0:0:0:0:0:0:0/8
14 b 300 IN CNAME foo.net.
15 c 300 IN A 73.80.65.49
16 cert01 3600 IN CERT 65534 65535 PRIVATEOID MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY=
17 cname01 3600 IN CNAME cname-target.
18 cname02 3600 IN CNAME cname-target
19 cname03 3600 IN CNAME .
20 d 300 IN A 73.80.65.49
21 dhcid01 3600 IN DHCID AAIBY2/AuCccgoJbsaxcQc9TUapptP69 lOjxfNuVAA2kjEA=
22 dhcid02 3600 IN DHCID AAEBOSD+XR3Os/0LozeXVqcNc7FwCfQd WL3b/NaiUDlW2No=
23 dhcid03 3600 IN DHCID AAABxLmlskllE0MVjd57zHcWmEH3pCQ6 VytcKD//7es/deY=
24 dlv01 3600 IN DLV 12345 3 1 123456789abcdef67890123456789abcdef67890
25 dname01 3600 IN DNAME dname-target.
26 dname02 3600 IN DNAME dname-target
27 dname03 3600 IN DNAME .
28 dnskey01 3600 IN DNSKEY 512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRu niJDBzC7w0aRyzWZriO6i2odGWWQVucZ qKVsENW91IOW4vqudngPZsY3GvQ/xVA8 /7pyFj6b7Esga60zyGW6LFe9r8n6paHr lG5ojqf0BaqHT+8=
29 dnskey02 3600 IN DNSKEY 257 3 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRu niJDBzC7w0aRyzWZriO6i2odGWWQVucZ qKVsENW91IOW4vqudngPZsY3GvQ/xVA8 /7pyFj6b7Esga60zyGW6LFe9r8n6paHr lG5ojqf0BaqHT+8=
30 ds01 3600 IN DS 12345 3 1 123456789abcdef67890123456789abcdef67890
31 e 300 IN MX 10 mail
32 e 300 IN TXT "one"
33 e 300 IN TXT "three"
34 e 300 IN TXT "two"
35 e 300 IN A 73.80.65.49
36 e 300 IN A 73.80.65.50
37 e 300 IN A 73.80.65.52
38 e 300 IN A 73.80.65.51
39 f 300 IN A 73.80.65.52
40 gpos01 3600 IN GPOS -22.6882 116.8652 250.0
41 hinfo01 3600 IN HINFO "Generic PC clone" "NetBSD-1.4"
42 hinfo02 3600 IN HINFO "PC" "NetBSD"
43 hip01 3600 IN HIP 2 200100107b1a74df365639cc39f1d578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs1.example.com. rvs2
44 ipseckey01 3600 IN IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
45 ipseckey02 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
46 ipseckey03 3600 IN IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
47 ipseckey04 3600 IN IPSECKEY 10 2 2 2001:0DB8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
48 ipseckey05 3600 IN IPSECKEY 10 3 2 mygateway2 AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
49 isdn01 3600 IN ISDN "isdn-address"
50 isdn02 3600 IN ISDN "isdn-address" "subaddress"
51 isdn03 3600 IN ISDN "isdn-address"
52 isdn04 3600 IN ISDN "isdn-address" "subaddress"
53 kx01 3600 IN KX 10 kdc
54 kx02 3600 IN KX 10 .
55 loc01 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m
56 loc02 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m
57 loc03 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 90000000.00m 2000.00m 20.00m
58 loc04 3600 IN LOC 60 9 1.500 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m
59 loc05 3600 IN LOC 60 9 1.510 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m
60 mx01 3600 IN MX 10 mail
61 mx02 3600 IN MX 10 .
62 naptr01 3600 IN NAPTR 0 0 "" "" "" .
63 naptr02 3600 IN NAPTR 65535 65535 "blurgh" "blorf" "blegh" foo.
64 ns1 300 IN A 10.53.0.1
65 ns2 300 IN A 10.53.0.2
66 nsap-ptr01 3600 IN NSAP-PTR foo.
67 nsap-ptr01 3600 IN NSAP-PTR .
68 nsap01 3600 IN NSAP 0x47000580005a0000000001e133ffffff00016100
69 nsap02 3600 IN NSAP 0x47000580005a0000000001e133ffffff00016100
70 nsec01 3600 IN NSEC a.secure. A MX RRSIG NSEC TYPE1234
71 nsec02 3600 IN NSEC . NSAP-PTR NSEC
72 nsec03 3600 IN NSEC . NSEC TYPE65535
73 nsec301 3600 IN NSEC3 1 1 12 aabbccdd 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS SOA MX RRSIG DNSKEY NSEC3PARAM
74 nsec302 3600 IN NSEC3 1 1 12 - 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS SOA MX RRSIG DNSKEY NSEC3PARAM
75 nsec3param01 3600 IN NSEC3PARAM 1 1 12 aabbccdd
76 nsec3param02 3600 IN NSEC3PARAM 1 1 12 -
77 ptr01 3600 IN PTR @
78 px01 3600 IN PX 65535 foo. bar.
79 px02 3600 IN PX 65535 . .
80 rp01 3600 IN RP mbox-dname txt-dname
81 rp02 3600 IN RP . .
82 rrsig01 3600 IN RRSIG NSEC 1 3 3600 20200101000000 20030101000000 2143 foo MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY=
83 rt01 3600 IN RT 0 intermediate-host
84 rt02 3600 IN RT 65535 .
85 s 300 IN NS ns.s
86 ns.s 300 IN A 73.80.65.49
87 spf 3600 IN SPF "v=spf1 mx -all"
88 srv01 3600 IN SRV 0 0 0 .
89 srv02 3600 IN SRV 65535 65535 65535 old-slow-box.example.com.
90 sshfp1 3600 IN SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab
91 t 301 IN A 73.80.65.49
92 tlsa1 3600 IN TLSA 3 1 1 a9cdf989b504fe5dca90c0d2167b6550570734f7c763e09fdf88904e06157065
93 tlsa2 3600 IN TLSA 1 0 1 efddf0d915c7bdc5782c0881e1b2a95ad099fbdd06d7b1f77982d9364338d955
94 tlsa3 3600 IN TLSA 1 0 2 81ee7f6c0ecc6b09b7785a9418f54432de630dd54dc6ee9e3c49de547708d236d4c413c3e97e44f969e635958aa410495844127c04883503e5b024cf7a8f6a94
95 txt01 3600 IN TXT "foo"
96 txt02 3600 IN TXT "foo" "bar"
97 txt03 3600 IN TXT "foo"
98 txt04 3600 IN TXT "foo" "bar"
99 txt05 3600 IN TXT "foo bar"
100 txt06 3600 IN TXT "foo bar"
101 txt07 3600 IN TXT "foo bar"
102 txt08 3600 IN TXT "foo\010bar"
103 txt09 3600 IN TXT "foo\010bar"
104 txt10 3600 IN TXT "foo bar"
105 txt11 3600 IN TXT "\"foo\""
106 txt12 3600 IN TXT "\"foo\""
107 txt13 3600 IN TXT "foo"
108 u 300 IN TXT "txt-not-in-nxt"
109 a.u 300 IN A 73.80.65.49
110 b.u 300 IN A 73.80.65.49
111 unknown2 3600 IN TYPE999 \# 8 0a0000010a000001
112 unknown3 3600 IN A 127.0.0.2
113 wks01 3600 IN WKS 10.0.0.1 6 0 1 2 21 23
114 wks02 3600 IN WKS 10.0.0.1 17 0 1 2 53
115 wks03 3600 IN WKS 10.0.0.2 6 65535
116 x2501 3600 IN X25 "123456789"
+0
-59
tests/flags.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.flags
18 import dns.rcode
19 import dns.opcode
20
21 class FlagsTestCase(unittest.TestCase):
22
23 def test_rcode1(self):
24 self.failUnless(dns.rcode.from_text('FORMERR') == dns.rcode.FORMERR)
25
26 def test_rcode2(self):
27 self.failUnless(dns.rcode.to_text(dns.rcode.FORMERR) == "FORMERR")
28
29 def test_rcode3(self):
30 self.failUnless(dns.rcode.to_flags(dns.rcode.FORMERR) == (1, 0))
31
32 def test_rcode4(self):
33 self.failUnless(dns.rcode.to_flags(dns.rcode.BADVERS) == \
34 (0, 0x01000000))
35
36 def test_rcode6(self):
37 self.failUnless(dns.rcode.from_flags(0, 0x01000000) == \
38 dns.rcode.BADVERS)
39
40 def test_rcode6(self):
41 self.failUnless(dns.rcode.from_flags(5, 0) == dns.rcode.REFUSED)
42
43 def test_rcode7(self):
44 def bad():
45 dns.rcode.to_flags(4096)
46 self.failUnlessRaises(ValueError, bad)
47
48 def test_flags1(self):
49 self.failUnless(dns.flags.from_text("RA RD AA QR") == \
50 dns.flags.QR|dns.flags.AA|dns.flags.RD|dns.flags.RA)
51
52 def test_flags2(self):
53 flags = dns.flags.QR|dns.flags.AA|dns.flags.RD|dns.flags.RA
54 self.failUnless(dns.flags.to_text(flags) == "QR AA RD RA")
55
56
57 if __name__ == '__main__':
58 unittest.main()
+0
-499
tests/generate.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import sys
16 sys.path.insert(0, '../') # Force the local project to be *the* dns
17
18 import cStringIO
19 import filecmp
20 import os
21 import unittest
22
23 import dns.exception
24 import dns.rdata
25 import dns.rdataclass
26 import dns.rdatatype
27 import dns.rrset
28 import dns.zone
29
30 import pprint
31
32 pp = pprint.PrettyPrinter(indent=2)
33
34 import pdb
35 example_text = """$TTL 1h
36 $ORIGIN 0.0.192.IN-ADDR.ARPA.
37 $GENERATE 1-2 0 CNAME SERVER$.EXAMPLE.
38 """
39
40 example_text1 = """$TTL 1h
41 $ORIGIN 0.0.192.IN-ADDR.ARPA.
42 $GENERATE 1-10 fooo$ CNAME $.0
43 """
44
45 example_text2 = """$TTL 1h
46 @ 3600 IN SOA foo bar 1 2 3 4 5
47 @ 3600 IN NS ns1
48 @ 3600 IN NS ns2
49 bar.foo 300 IN MX 0 blaz.foo
50 ns1 3600 IN A 10.0.0.1
51 ns2 3600 IN A 10.0.0.2
52 $GENERATE 3-5 foo$ A 10.0.0.$
53 """
54
55 example_text3 = """$TTL 1h
56 @ 3600 IN SOA foo bar 1 2 3 4 5
57 @ 3600 IN NS ns1
58 @ 3600 IN NS ns2
59 bar.foo 300 IN MX 0 blaz.foo
60 ns1 3600 IN A 10.0.0.1
61 ns2 3600 IN A 10.0.0.2
62 $GENERATE 4-8/2 foo$ A 10.0.0.$
63 """
64
65 example_text4 = """$TTL 1h
66 @ 3600 IN SOA foo bar 1 2 3 4 5
67 @ 3600 IN NS ns1
68 @ 3600 IN NS ns2
69 bar.foo 300 IN MX 0 blaz.foo
70 ns1 3600 IN A 10.0.0.1
71 ns2 3600 IN A 10.0.0.2
72 $GENERATE 11-13 wp-db${-10,2,d}.services.mozilla.com 0 CNAME SERVER.FOOBAR.
73 """
74
75 example_text5 = """$TTL 1h
76 @ 3600 IN SOA foo bar 1 2 3 4 5
77 @ 3600 IN NS ns1
78 @ 3600 IN NS ns2
79 bar.foo 300 IN MX 0 blaz.foo
80 ns1 3600 IN A 10.0.0.1
81 ns2 3600 IN A 10.0.0.2
82 $GENERATE 11-13 wp-db${10,2,d}.services.mozilla.com 0 CNAME SERVER.FOOBAR.
83 """
84
85 example_text6 = """$TTL 1h
86 @ 3600 IN SOA foo bar 1 2 3 4 5
87 @ 3600 IN NS ns1
88 @ 3600 IN NS ns2
89 bar.foo 300 IN MX 0 blaz.foo
90 ns1 3600 IN A 10.0.0.1
91 ns2 3600 IN A 10.0.0.2
92 $GENERATE 11-13 wp-db${+10,2,d}.services.mozilla.com 0 CNAME SERVER.FOOBAR.
93 """
94
95 example_text7 = """$TTL 1h
96 @ 3600 IN SOA foo bar 1 2 3 4 5
97 @ 3600 IN NS ns1
98 @ 3600 IN NS ns2
99 bar.foo 300 IN MX 0 blaz.foo
100 ns1 3600 IN A 10.0.0.1
101 ns2 3600 IN A 10.0.0.2
102 $GENERATE 11-13 sync${-10}.db IN A 10.10.16.0
103 """
104
105 example_text8 = """$TTL 1h
106 @ 3600 IN SOA foo bar 1 2 3 4 5
107 @ 3600 IN NS ns1
108 @ 3600 IN NS ns2
109 bar.foo 300 IN MX 0 blaz.foo
110 ns1 3600 IN A 10.0.0.1
111 ns2 3600 IN A 10.0.0.2
112 $GENERATE 11-12 wp-db${-10,2,d} IN A 10.10.16.0
113 """
114
115 example_text9 = """$TTL 1h
116 @ 3600 IN SOA foo bar 1 2 3 4 5
117 @ 3600 IN NS ns1
118 @ 3600 IN NS ns2
119 bar.foo 300 IN MX 0 blaz.foo
120 ns1 3600 IN A 10.0.0.1
121 ns2 3600 IN A 10.0.0.2
122 $GENERATE 11-12 wp-db${-10,2,d} IN A 10.10.16.0
123 $GENERATE 11-13 sync${-10}.db IN A 10.10.16.0
124 """
125 example_text10 = """$TTL 1h
126 @ 3600 IN SOA foo bar 1 2 3 4 5
127 @ 3600 IN NS ns1
128 @ 3600 IN NS ns2
129 bar.foo 300 IN MX 0 blaz.foo
130 ns1 3600 IN A 10.0.0.1
131 ns2 3600 IN A 10.0.0.2
132 $GENERATE 27-28 $.2 PTR zlb${-26}.oob
133 """
134
135
136 class GenerateTestCase(unittest.TestCase):
137
138 def testFromText(self):
139 def bad():
140 z = dns.zone.from_text(example_text, 'example.', relativize=True)
141 self.failUnlessRaises(dns.zone.NoSOA, bad)
142
143 def testFromText1(self):
144 def bad():
145 z = dns.zone.from_text(example_text1, 'example.', relativize=True)
146 self.failUnlessRaises(dns.zone.NoSOA, bad)
147
148 def testIterateAllRdatas2(self):
149 z = dns.zone.from_text(example_text2, 'example.', relativize=True)
150 l = list(z.iterate_rdatas())
151 l.sort()
152 exl = [(dns.name.from_text('@', None),
153 3600,
154 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
155 'ns1')),
156 (dns.name.from_text('@', None),
157 3600,
158 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
159 'ns2')),
160 (dns.name.from_text('@', None),
161 3600,
162 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
163 'foo bar 1 2 3 4 5')),
164 (dns.name.from_text('bar.foo', None),
165 300,
166 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
167 '0 blaz.foo')),
168 (dns.name.from_text('ns1', None),
169 3600,
170 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
171 '10.0.0.1')),
172 (dns.name.from_text('ns2', None),
173 3600,
174 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
175 '10.0.0.2')),
176 (dns.name.from_text('foo3', None),
177 3600,
178 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
179 '10.0.0.3')),
180 (dns.name.from_text('foo4', None),
181 3600,
182 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
183 '10.0.0.4')),
184 (dns.name.from_text('foo5', None),
185 3600,
186 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
187 '10.0.0.5'))]
188
189 exl.sort()
190 self.failUnless(l == exl)
191
192 def testIterateAllRdatas3(self):
193 z = dns.zone.from_text(example_text3, 'example.', relativize=True)
194 l = list(z.iterate_rdatas())
195 l.sort()
196 exl = [(dns.name.from_text('@', None),
197 3600,
198 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
199 'ns1')),
200 (dns.name.from_text('@', None),
201 3600,
202 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
203 'ns2')),
204 (dns.name.from_text('@', None),
205 3600,
206 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
207 'foo bar 1 2 3 4 5')),
208 (dns.name.from_text('bar.foo', None),
209 300,
210 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
211 '0 blaz.foo')),
212 (dns.name.from_text('ns1', None),
213 3600,
214 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
215 '10.0.0.1')),
216 (dns.name.from_text('ns2', None),
217 3600,
218 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
219 '10.0.0.2')),
220 (dns.name.from_text('foo4', None), 3600,
221 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
222 '10.0.0.4')),
223 (dns.name.from_text('foo6', None), 3600,
224 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
225 '10.0.0.6')),
226 (dns.name.from_text('foo8', None), 3600,
227 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
228 '10.0.0.8'))]
229 exl.sort()
230 self.failUnless(l == exl)
231 def testGenerate1(self):
232 z = dns.zone.from_text(example_text4, 'example.', relativize=True)
233 l = list(z.iterate_rdatas())
234 l.sort()
235 exl = [(dns.name.from_text('@', None),
236 3600L,
237 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
238 'ns1')),
239 (dns.name.from_text('@', None),
240 3600L,
241 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
242 'ns2')),
243 (dns.name.from_text('@', None),
244 3600L,
245 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
246 'foo bar 1 2 3 4 5')),
247 (dns.name.from_text('bar.foo', None),
248 300L,
249 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
250 '0 blaz.foo')),
251 (dns.name.from_text('ns1', None),
252 3600L,
253 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
254 '10.0.0.1')),
255 (dns.name.from_text('ns2', None),
256 3600L,
257 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
258 '10.0.0.2')),
259
260 (dns.name.from_text('wp-db01.services.mozilla.com', None),
261 0L,
262 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
263 'SERVER.FOOBAR.')),
264
265 (dns.name.from_text('wp-db02.services.mozilla.com', None),
266 0L,
267 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
268 'SERVER.FOOBAR.')),
269
270 (dns.name.from_text('wp-db03.services.mozilla.com', None),
271 0L,
272 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
273 'SERVER.FOOBAR.'))]
274 exl.sort()
275 self.failUnless(l == exl)
276
277 def testGenerate2(self):
278 z = dns.zone.from_text(example_text5, 'example.', relativize=True)
279 l = list(z.iterate_rdatas())
280 l.sort()
281 exl = [(dns.name.from_text('@', None),
282 3600L,
283 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
284 'ns1')),
285 (dns.name.from_text('@', None),
286 3600L,
287 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
288 'ns2')),
289 (dns.name.from_text('@', None),
290 3600L,
291 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
292 'foo bar 1 2 3 4 5')),
293 (dns.name.from_text('bar.foo', None),
294 300L,
295 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
296 '0 blaz.foo')),
297 (dns.name.from_text('ns1', None),
298 3600L,
299 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
300 '10.0.0.1')),
301 (dns.name.from_text('ns2', None),
302 3600L,
303 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
304 '10.0.0.2')),
305
306 (dns.name.from_text('wp-db21.services.mozilla.com', None), 0L,
307 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
308 'SERVER.FOOBAR.')),
309
310 (dns.name.from_text('wp-db22.services.mozilla.com', None), 0L,
311 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
312 'SERVER.FOOBAR.')),
313
314 (dns.name.from_text('wp-db23.services.mozilla.com', None), 0L,
315 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
316 'SERVER.FOOBAR.'))]
317 exl.sort()
318 self.failUnless(l == exl)
319
320 def testGenerate3(self):
321 z = dns.zone.from_text(example_text6, 'example.', relativize=True)
322 l = list(z.iterate_rdatas())
323 l.sort()
324
325 exl = [(dns.name.from_text('@', None),
326 3600L,
327 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
328 'ns1')),
329 (dns.name.from_text('@', None),
330 3600L,
331 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
332 'ns2')),
333 (dns.name.from_text('@', None),
334 3600L,
335 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
336 'foo bar 1 2 3 4 5')),
337 (dns.name.from_text('bar.foo', None),
338 300L,
339 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
340 '0 blaz.foo')),
341 (dns.name.from_text('ns1', None),
342 3600L,
343 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
344 '10.0.0.1')),
345 (dns.name.from_text('ns2', None),
346 3600L,
347 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
348 '10.0.0.2')),
349 (dns.name.from_text('wp-db21.services.mozilla.com', None), 0L,
350 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
351 'SERVER.FOOBAR.')),
352
353 (dns.name.from_text('wp-db22.services.mozilla.com', None), 0L,
354 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
355 'SERVER.FOOBAR.')),
356
357 (dns.name.from_text('wp-db23.services.mozilla.com', None), 0L,
358 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
359 'SERVER.FOOBAR.'))]
360 exl.sort()
361 self.failUnless(l == exl)
362
363 def testGenerate4(self):
364 z = dns.zone.from_text(example_text7, 'example.', relativize=True)
365 l = list(z.iterate_rdatas())
366 l.sort()
367 exl = [(dns.name.from_text('@', None),
368 3600L,
369 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
370 'ns1')),
371 (dns.name.from_text('@', None),
372 3600L,
373 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
374 'ns2')),
375 (dns.name.from_text('@', None),
376 3600L,
377 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
378 'foo bar 1 2 3 4 5')),
379 (dns.name.from_text('bar.foo', None),
380 300L,
381 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
382 '0 blaz.foo')),
383 (dns.name.from_text('ns1', None),
384 3600L,
385 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
386 '10.0.0.1')),
387 (dns.name.from_text('ns2', None),
388 3600L,
389 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
390 '10.0.0.2')),
391
392 (dns.name.from_text('sync1.db', None), 3600L,
393 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
394 '10.10.16.0')),
395
396 (dns.name.from_text('sync2.db', None), 3600L,
397 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
398 '10.10.16.0')),
399
400 (dns.name.from_text('sync3.db', None), 3600L,
401 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
402 '10.10.16.0'))]
403 exl.sort()
404 self.failUnless(l == exl)
405
406 def testGenerate6(self):
407 z = dns.zone.from_text(example_text9, 'example.', relativize=True)
408 l = list(z.iterate_rdatas())
409 l.sort()
410 exl = [(dns.name.from_text('@', None),
411 3600L,
412 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
413 'ns1')),
414 (dns.name.from_text('@', None),
415 3600L,
416 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
417 'ns2')),
418 (dns.name.from_text('@', None),
419 3600L,
420 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
421 'foo bar 1 2 3 4 5')),
422 (dns.name.from_text('bar.foo', None),
423 300L,
424 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
425 '0 blaz.foo')),
426 (dns.name.from_text('ns1', None),
427 3600L,
428 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
429 '10.0.0.1')),
430 (dns.name.from_text('ns2', None),
431 3600L,
432 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
433 '10.0.0.2')),
434
435 (dns.name.from_text('wp-db01', None), 3600L,
436 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
437 '10.10.16.0')),
438 (dns.name.from_text('wp-db02', None), 3600L,
439 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
440 '10.10.16.0')),
441
442 (dns.name.from_text('sync1.db', None), 3600L,
443 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
444 '10.10.16.0')),
445
446 (dns.name.from_text('sync2.db', None), 3600L,
447 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
448 '10.10.16.0')),
449
450 (dns.name.from_text('sync3.db', None), 3600L,
451 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
452 '10.10.16.0'))]
453 exl.sort()
454 self.failUnless(l == exl)
455
456 def testGenerate7(self):
457 z = dns.zone.from_text(example_text10, 'example.', relativize=True)
458 l = list(z.iterate_rdatas())
459 l.sort()
460 exl = [(dns.name.from_text('@', None),
461 3600L,
462 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
463 'ns1')),
464 (dns.name.from_text('@', None),
465 3600L,
466 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
467 'ns2')),
468 (dns.name.from_text('@', None),
469 3600L,
470 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
471 'foo bar 1 2 3 4 5')),
472 (dns.name.from_text('bar.foo', None),
473 300L,
474 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
475 '0 blaz.foo')),
476 (dns.name.from_text('ns1', None),
477 3600L,
478 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
479 '10.0.0.1')),
480 (dns.name.from_text('ns2', None),
481 3600L,
482 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
483 '10.0.0.2')),
484
485 (dns.name.from_text('27.2', None), 3600L,
486 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.PTR,
487 'zlb1.oob')),
488
489 (dns.name.from_text('28.2', None), 3600L,
490 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.PTR,
491 'zlb2.oob'))]
492
493 exl.sort()
494 self.failUnless(l == exl)
495
496
497 if __name__ == '__main__':
498 unittest.main()
+0
-95
tests/grange.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import sys
16 sys.path.insert(0, '../')
17
18 import cStringIO
19 import filecmp
20 import os
21 import unittest
22
23 import dns
24 import dns.exception
25 import dns.grange
26
27 import pdb
28
29
30
31 class GRangeTestCase(unittest.TestCase):
32
33 def testFromText1(self):
34 start, stop, step = dns.grange.from_text('1-1')
35 self.assertEqual(start, 1)
36 self.assertEqual(stop, 1)
37 self.assertEqual(step, 1)
38
39 def testFromText2(self):
40 start, stop, step = dns.grange.from_text('1-4')
41 self.assertEqual(start, 1)
42 self.assertEqual(stop, 4)
43 self.assertEqual(step, 1)
44
45 def testFromText3(self):
46 start, stop, step = dns.grange.from_text('4-255')
47 self.assertEqual(start, 4)
48 self.assertEqual(stop, 255)
49 self.assertEqual(step, 1)
50
51 def testFromText4(self):
52 start, stop, step = dns.grange.from_text('1-1/1')
53 self.assertEqual(start, 1)
54 self.assertEqual(stop, 1)
55 self.assertEqual(step, 1)
56
57 def testFromText5(self):
58 start, stop, step = dns.grange.from_text('1-4/2')
59 self.assertEqual(start, 1)
60 self.assertEqual(stop, 4)
61 self.assertEqual(step, 2)
62
63 def testFromText6(self):
64 start, stop, step = dns.grange.from_text('4-255/77')
65 self.assertEqual(start, 4)
66 self.assertEqual(stop, 255)
67 self.assertEqual(step, 77)
68
69 def testFailFromText1(self):
70 def bad():
71 start = 2
72 stop = 1
73 step = 1
74 dns.grange.from_text('%d-%d/%d' % (start, stop, step))
75 self.assertRaises(AssertionError, bad)
76
77 def testFailFromText2(self):
78 def bad():
79 start = '-1'
80 stop = 3
81 step = 1
82 dns.grange.from_text('%s-%d/%d' % (start, stop, step))
83 self.assertRaises(dns.exception.SyntaxError, bad)
84
85 def testFailFromText2(self):
86 def bad():
87 start = 1
88 stop = 4
89 step = '-2'
90 dns.grange.from_text('%d-%d/%s' % (start, stop, step))
91 self.assertRaises(dns.exception.SyntaxError, bad)
92
93 if __name__ == '__main__':
94 unittest.main()
+0
-179
tests/message.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import cStringIO
16 import os
17 import unittest
18
19 import dns.exception
20 import dns.message
21
22 query_text = """id 1234
23 opcode QUERY
24 rcode NOERROR
25 flags RD
26 edns 0
27 eflags DO
28 payload 4096
29 ;QUESTION
30 wwww.dnspython.org. IN A
31 ;ANSWER
32 ;AUTHORITY
33 ;ADDITIONAL"""
34
35 goodhex = '04d201000001000000000001047777777709646e73707974686f6e' \
36 '036f726700000100010000291000000080000000'
37
38 goodwire = goodhex.decode('hex_codec')
39
40 answer_text = """id 1234
41 opcode QUERY
42 rcode NOERROR
43 flags QR AA RD
44 ;QUESTION
45 dnspython.org. IN SOA
46 ;ANSWER
47 dnspython.org. 3600 IN SOA woof.dnspython.org. hostmaster.dnspython.org. 2003052700 3600 1800 604800 3600
48 ;AUTHORITY
49 dnspython.org. 3600 IN NS ns1.staff.nominum.org.
50 dnspython.org. 3600 IN NS ns2.staff.nominum.org.
51 dnspython.org. 3600 IN NS woof.play-bow.org.
52 ;ADDITIONAL
53 woof.play-bow.org. 3600 IN A 204.152.186.150
54 """
55
56 goodhex2 = '04d2 8500 0001 0001 0003 0001' \
57 '09646e73707974686f6e036f726700 0006 0001' \
58 'c00c 0006 0001 00000e10 0028 ' \
59 '04776f6f66c00c 0a686f73746d6173746572c00c' \
60 '7764289c 00000e10 00000708 00093a80 00000e10' \
61 'c00c 0002 0001 00000e10 0014' \
62 '036e7331057374616666076e6f6d696e756dc016' \
63 'c00c 0002 0001 00000e10 0006 036e7332c063' \
64 'c00c 0002 0001 00000e10 0010 04776f6f6608706c61792d626f77c016' \
65 'c091 0001 0001 00000e10 0004 cc98ba96'
66
67
68 goodwire2 = goodhex2.replace(' ', '').decode('hex_codec')
69
70 query_text_2 = """id 1234
71 opcode QUERY
72 rcode 4095
73 flags RD
74 edns 0
75 eflags DO
76 payload 4096
77 ;QUESTION
78 wwww.dnspython.org. IN A
79 ;ANSWER
80 ;AUTHORITY
81 ;ADDITIONAL"""
82
83 goodhex3 = '04d2010f0001000000000001047777777709646e73707974686f6e' \
84 '036f726700000100010000291000ff0080000000'
85
86 goodwire3 = goodhex3.decode('hex_codec')
87
88 class MessageTestCase(unittest.TestCase):
89
90 def test_comparison_eq1(self):
91 q1 = dns.message.from_text(query_text)
92 q2 = dns.message.from_text(query_text)
93 self.failUnless(q1 == q2)
94
95 def test_comparison_ne1(self):
96 q1 = dns.message.from_text(query_text)
97 q2 = dns.message.from_text(query_text)
98 q2.id = 10
99 self.failUnless(q1 != q2)
100
101 def test_comparison_ne2(self):
102 q1 = dns.message.from_text(query_text)
103 q2 = dns.message.from_text(query_text)
104 q2.question = []
105 self.failUnless(q1 != q2)
106
107 def test_comparison_ne3(self):
108 q1 = dns.message.from_text(query_text)
109 self.failUnless(q1 != 1)
110
111 def test_EDNS_to_wire1(self):
112 q = dns.message.from_text(query_text)
113 w = q.to_wire()
114 self.failUnless(w == goodwire)
115
116 def test_EDNS_from_wire1(self):
117 m = dns.message.from_wire(goodwire)
118 self.failUnless(str(m) == query_text)
119
120 def test_EDNS_to_wire2(self):
121 q = dns.message.from_text(query_text_2)
122 w = q.to_wire()
123 self.failUnless(w == goodwire3)
124
125 def test_EDNS_from_wire2(self):
126 m = dns.message.from_wire(goodwire3)
127 self.failUnless(str(m) == query_text_2)
128
129 def test_TooBig(self):
130 def bad():
131 q = dns.message.from_text(query_text)
132 for i in xrange(0, 25):
133 rrset = dns.rrset.from_text('foo%d.' % i, 3600,
134 dns.rdataclass.IN,
135 dns.rdatatype.A,
136 '10.0.0.%d' % i)
137 q.additional.append(rrset)
138 w = q.to_wire(max_size=512)
139 self.failUnlessRaises(dns.exception.TooBig, bad)
140
141 def test_answer1(self):
142 a = dns.message.from_text(answer_text)
143 wire = a.to_wire(want_shuffle=False)
144 self.failUnless(wire == goodwire2)
145
146 def test_TrailingJunk(self):
147 def bad():
148 badwire = goodwire + '\x00'
149 m = dns.message.from_wire(badwire)
150 self.failUnlessRaises(dns.message.TrailingJunk, bad)
151
152 def test_ShortHeader(self):
153 def bad():
154 badwire = '\x00' * 11
155 m = dns.message.from_wire(badwire)
156 self.failUnlessRaises(dns.message.ShortHeader, bad)
157
158 def test_RespondingToResponse(self):
159 def bad():
160 q = dns.message.make_query('foo', 'A')
161 r1 = dns.message.make_response(q)
162 r2 = dns.message.make_response(r1)
163 self.failUnlessRaises(dns.exception.FormError, bad)
164
165 def test_ExtendedRcodeSetting(self):
166 m = dns.message.make_query('foo', 'A')
167 m.set_rcode(4095)
168 self.failUnless(m.rcode() == 4095)
169 m.set_rcode(2)
170 self.failUnless(m.rcode() == 2)
171
172 def test_EDNSVersionCoherence(self):
173 m = dns.message.make_query('foo', 'A')
174 m.use_edns(1)
175 self.failUnless((m.ednsflags >> 16) & 0xFF == 1)
176
177 if __name__ == '__main__':
178 unittest.main()
+0
-697
tests/name.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import cStringIO
18 import socket
19
20 import dns.name
21 import dns.reversename
22 import dns.e164
23
24 class NameTestCase(unittest.TestCase):
25 def setUp(self):
26 self.origin = dns.name.from_text('example.')
27
28 def testFromTextRel1(self):
29 n = dns.name.from_text('foo.bar')
30 self.failUnless(n.labels == ('foo', 'bar', ''))
31
32 def testFromTextRel2(self):
33 n = dns.name.from_text('foo.bar', origin=self.origin)
34 self.failUnless(n.labels == ('foo', 'bar', 'example', ''))
35
36 def testFromTextRel3(self):
37 n = dns.name.from_text('foo.bar', origin=None)
38 self.failUnless(n.labels == ('foo', 'bar'))
39
40 def testFromTextRel4(self):
41 n = dns.name.from_text('@', origin=None)
42 self.failUnless(n == dns.name.empty)
43
44 def testFromTextRel5(self):
45 n = dns.name.from_text('@', origin=self.origin)
46 self.failUnless(n == self.origin)
47
48 def testFromTextAbs1(self):
49 n = dns.name.from_text('foo.bar.')
50 self.failUnless(n.labels == ('foo', 'bar', ''))
51
52 def testTortureFromText(self):
53 good = [
54 r'.',
55 r'a',
56 r'a.',
57 r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
58 r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
59 r'\000.\008.\010.\032.\046.\092.\099.\255',
60 r'\\',
61 r'\..\.',
62 r'\\.\\',
63 r'!"#%&/()=+-',
64 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',
65 ]
66 bad = [
67 r'..',
68 r'.a',
69 r'\\..',
70 '\\', # yes, we don't want the 'r' prefix!
71 r'\0',
72 r'\00',
73 r'\00Z',
74 r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
75 r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
76 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',
77 ]
78 for t in good:
79 try:
80 n = dns.name.from_text(t)
81 except:
82 self.fail("good test '%s' raised an exception" % t)
83 for t in bad:
84 caught = False
85 try:
86 n = dns.name.from_text(t)
87 except:
88 caught = True
89 if not caught:
90 self.fail("bad test '%s' did not raise an exception" % t)
91
92 def testImmutable1(self):
93 def bad():
94 self.origin.labels = ()
95 self.failUnlessRaises(TypeError, bad)
96
97 def testImmutable2(self):
98 def bad():
99 self.origin.labels[0] = 'foo'
100 self.failUnlessRaises(TypeError, bad)
101
102 def testAbs1(self):
103 self.failUnless(dns.name.root.is_absolute())
104
105 def testAbs2(self):
106 self.failUnless(not dns.name.empty.is_absolute())
107
108 def testAbs3(self):
109 self.failUnless(self.origin.is_absolute())
110
111 def testAbs3(self):
112 n = dns.name.from_text('foo', origin=None)
113 self.failUnless(not n.is_absolute())
114
115 def testWild1(self):
116 n = dns.name.from_text('*.foo', origin=None)
117 self.failUnless(n.is_wild())
118
119 def testWild2(self):
120 n = dns.name.from_text('*a.foo', origin=None)
121 self.failUnless(not n.is_wild())
122
123 def testWild3(self):
124 n = dns.name.from_text('a.*.foo', origin=None)
125 self.failUnless(not n.is_wild())
126
127 def testWild4(self):
128 self.failUnless(not dns.name.root.is_wild())
129
130 def testWild5(self):
131 self.failUnless(not dns.name.empty.is_wild())
132
133 def testHash1(self):
134 n1 = dns.name.from_text('fOo.COM')
135 n2 = dns.name.from_text('foo.com')
136 self.failUnless(hash(n1) == hash(n2))
137
138 def testCompare1(self):
139 n1 = dns.name.from_text('a')
140 n2 = dns.name.from_text('b')
141 self.failUnless(n1 < n2)
142 self.failUnless(n2 > n1)
143
144 def testCompare2(self):
145 n1 = dns.name.from_text('')
146 n2 = dns.name.from_text('b')
147 self.failUnless(n1 < n2)
148 self.failUnless(n2 > n1)
149
150 def testCompare3(self):
151 self.failUnless(dns.name.empty < dns.name.root)
152 self.failUnless(dns.name.root > dns.name.empty)
153
154 def testCompare4(self):
155 self.failUnless(dns.name.root != 1)
156
157 def testCompare5(self):
158 self.failUnless(dns.name.root < 1 or dns.name.root > 1)
159
160 def testSubdomain1(self):
161 self.failUnless(not dns.name.empty.is_subdomain(dns.name.root))
162
163 def testSubdomain2(self):
164 self.failUnless(not dns.name.root.is_subdomain(dns.name.empty))
165
166 def testSubdomain3(self):
167 n = dns.name.from_text('foo', origin=self.origin)
168 self.failUnless(n.is_subdomain(self.origin))
169
170 def testSubdomain4(self):
171 n = dns.name.from_text('foo', origin=self.origin)
172 self.failUnless(n.is_subdomain(dns.name.root))
173
174 def testSubdomain5(self):
175 n = dns.name.from_text('foo', origin=self.origin)
176 self.failUnless(n.is_subdomain(n))
177
178 def testSuperdomain1(self):
179 self.failUnless(not dns.name.empty.is_superdomain(dns.name.root))
180
181 def testSuperdomain2(self):
182 self.failUnless(not dns.name.root.is_superdomain(dns.name.empty))
183
184 def testSuperdomain3(self):
185 n = dns.name.from_text('foo', origin=self.origin)
186 self.failUnless(self.origin.is_superdomain(n))
187
188 def testSuperdomain4(self):
189 n = dns.name.from_text('foo', origin=self.origin)
190 self.failUnless(dns.name.root.is_superdomain(n))
191
192 def testSuperdomain5(self):
193 n = dns.name.from_text('foo', origin=self.origin)
194 self.failUnless(n.is_superdomain(n))
195
196 def testCanonicalize1(self):
197 n = dns.name.from_text('FOO.bar', origin=self.origin)
198 c = n.canonicalize()
199 self.failUnless(c.labels == ('foo', 'bar', 'example', ''))
200
201 def testToText1(self):
202 n = dns.name.from_text('FOO.bar', origin=self.origin)
203 t = n.to_text()
204 self.failUnless(t == 'FOO.bar.example.')
205
206 def testToText2(self):
207 n = dns.name.from_text('FOO.bar', origin=self.origin)
208 t = n.to_text(True)
209 self.failUnless(t == 'FOO.bar.example')
210
211 def testToText3(self):
212 n = dns.name.from_text('FOO.bar', origin=None)
213 t = n.to_text()
214 self.failUnless(t == 'FOO.bar')
215
216 def testToText4(self):
217 t = dns.name.empty.to_text()
218 self.failUnless(t == '@')
219
220 def testToText5(self):
221 t = dns.name.root.to_text()
222 self.failUnless(t == '.')
223
224 def testToText6(self):
225 n = dns.name.from_text('FOO bar', origin=None)
226 t = n.to_text()
227 self.failUnless(t == r'FOO\032bar')
228
229 def testToText7(self):
230 n = dns.name.from_text(r'FOO\.bar', origin=None)
231 t = n.to_text()
232 self.failUnless(t == r'FOO\.bar')
233
234 def testToText8(self):
235 n = dns.name.from_text(r'\070OO\.bar', origin=None)
236 t = n.to_text()
237 self.failUnless(t == r'FOO\.bar')
238
239 def testSlice1(self):
240 n = dns.name.from_text(r'a.b.c.', origin=None)
241 s = n[:]
242 self.failUnless(s == ('a', 'b', 'c', ''))
243
244 def testSlice2(self):
245 n = dns.name.from_text(r'a.b.c.', origin=None)
246 s = n[:2]
247 self.failUnless(s == ('a', 'b'))
248
249 def testSlice3(self):
250 n = dns.name.from_text(r'a.b.c.', origin=None)
251 s = n[2:]
252 self.failUnless(s == ('c', ''))
253
254 def testEmptyLabel1(self):
255 def bad():
256 n = dns.name.Name(['a', '', 'b'])
257 self.failUnlessRaises(dns.name.EmptyLabel, bad)
258
259 def testEmptyLabel2(self):
260 def bad():
261 n = dns.name.Name(['', 'b'])
262 self.failUnlessRaises(dns.name.EmptyLabel, bad)
263
264 def testEmptyLabel3(self):
265 n = dns.name.Name(['b', ''])
266 self.failUnless(n)
267
268 def testLongLabel(self):
269 n = dns.name.Name(['a' * 63])
270 self.failUnless(n)
271
272 def testLabelTooLong(self):
273 def bad():
274 n = dns.name.Name(['a' * 64, 'b'])
275 self.failUnlessRaises(dns.name.LabelTooLong, bad)
276
277 def testLongName(self):
278 n = dns.name.Name(['a' * 63, 'a' * 63, 'a' * 63, 'a' * 62])
279 self.failUnless(n)
280
281 def testNameTooLong(self):
282 def bad():
283 n = dns.name.Name(['a' * 63, 'a' * 63, 'a' * 63, 'a' * 63])
284 self.failUnlessRaises(dns.name.NameTooLong, bad)
285
286 def testConcat1(self):
287 n1 = dns.name.Name(['a', 'b'])
288 n2 = dns.name.Name(['c', 'd'])
289 e = dns.name.Name(['a', 'b', 'c', 'd'])
290 r = n1 + n2
291 self.failUnless(r == e)
292
293 def testConcat2(self):
294 n1 = dns.name.Name(['a', 'b'])
295 n2 = dns.name.Name([])
296 e = dns.name.Name(['a', 'b'])
297 r = n1 + n2
298 self.failUnless(r == e)
299
300 def testConcat2(self):
301 n1 = dns.name.Name([])
302 n2 = dns.name.Name(['a', 'b'])
303 e = dns.name.Name(['a', 'b'])
304 r = n1 + n2
305 self.failUnless(r == e)
306
307 def testConcat3(self):
308 n1 = dns.name.Name(['a', 'b', ''])
309 n2 = dns.name.Name([])
310 e = dns.name.Name(['a', 'b', ''])
311 r = n1 + n2
312 self.failUnless(r == e)
313
314 def testConcat4(self):
315 n1 = dns.name.Name(['a', 'b'])
316 n2 = dns.name.Name(['c', ''])
317 e = dns.name.Name(['a', 'b', 'c', ''])
318 r = n1 + n2
319 self.failUnless(r == e)
320
321 def testConcat5(self):
322 def bad():
323 n1 = dns.name.Name(['a', 'b', ''])
324 n2 = dns.name.Name(['c'])
325 r = n1 + n2
326 self.failUnlessRaises(dns.name.AbsoluteConcatenation, bad)
327
328 def testBadEscape(self):
329 def bad():
330 n = dns.name.from_text(r'a.b\0q1.c.')
331 print n
332 self.failUnlessRaises(dns.name.BadEscape, bad)
333
334 def testDigestable1(self):
335 n = dns.name.from_text('FOO.bar')
336 d = n.to_digestable()
337 self.failUnless(d == '\x03foo\x03bar\x00')
338
339 def testDigestable2(self):
340 n1 = dns.name.from_text('FOO.bar')
341 n2 = dns.name.from_text('foo.BAR.')
342 d1 = n1.to_digestable()
343 d2 = n2.to_digestable()
344 self.failUnless(d1 == d2)
345
346 def testDigestable3(self):
347 d = dns.name.root.to_digestable()
348 self.failUnless(d == '\x00')
349
350 def testDigestable4(self):
351 n = dns.name.from_text('FOO.bar', None)
352 d = n.to_digestable(dns.name.root)
353 self.failUnless(d == '\x03foo\x03bar\x00')
354
355 def testBadDigestable(self):
356 def bad():
357 n = dns.name.from_text('FOO.bar', None)
358 d = n.to_digestable()
359 self.failUnlessRaises(dns.name.NeedAbsoluteNameOrOrigin, bad)
360
361 def testToWire1(self):
362 n = dns.name.from_text('FOO.bar')
363 f = cStringIO.StringIO()
364 compress = {}
365 n.to_wire(f, compress)
366 self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00')
367
368 def testToWire2(self):
369 n = dns.name.from_text('FOO.bar')
370 f = cStringIO.StringIO()
371 compress = {}
372 n.to_wire(f, compress)
373 n.to_wire(f, compress)
374 self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\xc0\x00')
375
376 def testToWire3(self):
377 n1 = dns.name.from_text('FOO.bar')
378 n2 = dns.name.from_text('foo.bar')
379 f = cStringIO.StringIO()
380 compress = {}
381 n1.to_wire(f, compress)
382 n2.to_wire(f, compress)
383 self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\xc0\x00')
384
385 def testToWire4(self):
386 n1 = dns.name.from_text('FOO.bar')
387 n2 = dns.name.from_text('a.foo.bar')
388 f = cStringIO.StringIO()
389 compress = {}
390 n1.to_wire(f, compress)
391 n2.to_wire(f, compress)
392 self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\x01\x61\xc0\x00')
393
394 def testToWire5(self):
395 n1 = dns.name.from_text('FOO.bar')
396 n2 = dns.name.from_text('a.foo.bar')
397 f = cStringIO.StringIO()
398 compress = {}
399 n1.to_wire(f, compress)
400 n2.to_wire(f, None)
401 self.failUnless(f.getvalue() == \
402 '\x03FOO\x03bar\x00\x01\x61\x03foo\x03bar\x00')
403
404 def testToWire6(self):
405 n = dns.name.from_text('FOO.bar')
406 v = n.to_wire()
407 self.failUnless(v == '\x03FOO\x03bar\x00')
408
409 def testBadToWire(self):
410 def bad():
411 n = dns.name.from_text('FOO.bar', None)
412 f = cStringIO.StringIO()
413 compress = {}
414 n.to_wire(f, compress)
415 self.failUnlessRaises(dns.name.NeedAbsoluteNameOrOrigin, bad)
416
417 def testSplit1(self):
418 n = dns.name.from_text('foo.bar.')
419 (prefix, suffix) = n.split(2)
420 ep = dns.name.from_text('foo', None)
421 es = dns.name.from_text('bar.', None)
422 self.failUnless(prefix == ep and suffix == es)
423
424 def testSplit2(self):
425 n = dns.name.from_text('foo.bar.')
426 (prefix, suffix) = n.split(1)
427 ep = dns.name.from_text('foo.bar', None)
428 es = dns.name.from_text('.', None)
429 self.failUnless(prefix == ep and suffix == es)
430
431 def testSplit3(self):
432 n = dns.name.from_text('foo.bar.')
433 (prefix, suffix) = n.split(0)
434 ep = dns.name.from_text('foo.bar.', None)
435 es = dns.name.from_text('', None)
436 self.failUnless(prefix == ep and suffix == es)
437
438 def testSplit4(self):
439 n = dns.name.from_text('foo.bar.')
440 (prefix, suffix) = n.split(3)
441 ep = dns.name.from_text('', None)
442 es = dns.name.from_text('foo.bar.', None)
443 self.failUnless(prefix == ep and suffix == es)
444
445 def testBadSplit1(self):
446 def bad():
447 n = dns.name.from_text('foo.bar.')
448 (prefix, suffix) = n.split(-1)
449 self.failUnlessRaises(ValueError, bad)
450
451 def testBadSplit2(self):
452 def bad():
453 n = dns.name.from_text('foo.bar.')
454 (prefix, suffix) = n.split(4)
455 self.failUnlessRaises(ValueError, bad)
456
457 def testRelativize1(self):
458 n = dns.name.from_text('a.foo.bar.', None)
459 o = dns.name.from_text('bar.', None)
460 e = dns.name.from_text('a.foo', None)
461 self.failUnless(n.relativize(o) == e)
462
463 def testRelativize2(self):
464 n = dns.name.from_text('a.foo.bar.', None)
465 o = n
466 e = dns.name.empty
467 self.failUnless(n.relativize(o) == e)
468
469 def testRelativize3(self):
470 n = dns.name.from_text('a.foo.bar.', None)
471 o = dns.name.from_text('blaz.', None)
472 e = n
473 self.failUnless(n.relativize(o) == e)
474
475 def testRelativize4(self):
476 n = dns.name.from_text('a.foo', None)
477 o = dns.name.root
478 e = n
479 self.failUnless(n.relativize(o) == e)
480
481 def testDerelativize1(self):
482 n = dns.name.from_text('a.foo', None)
483 o = dns.name.from_text('bar.', None)
484 e = dns.name.from_text('a.foo.bar.', None)
485 self.failUnless(n.derelativize(o) == e)
486
487 def testDerelativize2(self):
488 n = dns.name.empty
489 o = dns.name.from_text('a.foo.bar.', None)
490 e = o
491 self.failUnless(n.derelativize(o) == e)
492
493 def testDerelativize3(self):
494 n = dns.name.from_text('a.foo.bar.', None)
495 o = dns.name.from_text('blaz.', None)
496 e = n
497 self.failUnless(n.derelativize(o) == e)
498
499 def testChooseRelativity1(self):
500 n = dns.name.from_text('a.foo.bar.', None)
501 o = dns.name.from_text('bar.', None)
502 e = dns.name.from_text('a.foo', None)
503 self.failUnless(n.choose_relativity(o, True) == e)
504
505 def testChooseRelativity2(self):
506 n = dns.name.from_text('a.foo.bar.', None)
507 o = dns.name.from_text('bar.', None)
508 e = n
509 self.failUnless(n.choose_relativity(o, False) == e)
510
511 def testChooseRelativity3(self):
512 n = dns.name.from_text('a.foo', None)
513 o = dns.name.from_text('bar.', None)
514 e = dns.name.from_text('a.foo.bar.', None)
515 self.failUnless(n.choose_relativity(o, False) == e)
516
517 def testChooseRelativity4(self):
518 n = dns.name.from_text('a.foo', None)
519 o = None
520 e = n
521 self.failUnless(n.choose_relativity(o, True) == e)
522
523 def testChooseRelativity5(self):
524 n = dns.name.from_text('a.foo', None)
525 o = None
526 e = n
527 self.failUnless(n.choose_relativity(o, False) == e)
528
529 def testChooseRelativity6(self):
530 n = dns.name.from_text('a.foo.', None)
531 o = None
532 e = n
533 self.failUnless(n.choose_relativity(o, True) == e)
534
535 def testChooseRelativity7(self):
536 n = dns.name.from_text('a.foo.', None)
537 o = None
538 e = n
539 self.failUnless(n.choose_relativity(o, False) == e)
540
541 def testFromWire1(self):
542 w = '\x03foo\x00\xc0\x00'
543 (n1, cused1) = dns.name.from_wire(w, 0)
544 (n2, cused2) = dns.name.from_wire(w, cused1)
545 en1 = dns.name.from_text('foo.')
546 en2 = en1
547 ecused1 = 5
548 ecused2 = 2
549 self.failUnless(n1 == en1 and cused1 == ecused1 and \
550 n2 == en2 and cused2 == ecused2)
551
552 def testFromWire1(self):
553 w = '\x03foo\x00\x01a\xc0\x00\x01b\xc0\x05'
554 current = 0
555 (n1, cused1) = dns.name.from_wire(w, current)
556 current += cused1
557 (n2, cused2) = dns.name.from_wire(w, current)
558 current += cused2
559 (n3, cused3) = dns.name.from_wire(w, current)
560 en1 = dns.name.from_text('foo.')
561 en2 = dns.name.from_text('a.foo.')
562 en3 = dns.name.from_text('b.a.foo.')
563 ecused1 = 5
564 ecused2 = 4
565 ecused3 = 4
566 self.failUnless(n1 == en1 and cused1 == ecused1 and \
567 n2 == en2 and cused2 == ecused2 and \
568 n3 == en3 and cused3 == ecused3)
569
570 def testBadFromWire1(self):
571 def bad():
572 w = '\x03foo\xc0\x04'
573 (n, cused) = dns.name.from_wire(w, 0)
574 self.failUnlessRaises(dns.name.BadPointer, bad)
575
576 def testBadFromWire2(self):
577 def bad():
578 w = '\x03foo\xc0\x05'
579 (n, cused) = dns.name.from_wire(w, 0)
580 self.failUnlessRaises(dns.name.BadPointer, bad)
581
582 def testBadFromWire3(self):
583 def bad():
584 w = '\xbffoo'
585 (n, cused) = dns.name.from_wire(w, 0)
586 self.failUnlessRaises(dns.name.BadLabelType, bad)
587
588 def testBadFromWire4(self):
589 def bad():
590 w = '\x41foo'
591 (n, cused) = dns.name.from_wire(w, 0)
592 self.failUnlessRaises(dns.name.BadLabelType, bad)
593
594 def testParent1(self):
595 n = dns.name.from_text('foo.bar.')
596 self.failUnless(n.parent() == dns.name.from_text('bar.'))
597 self.failUnless(n.parent().parent() == dns.name.root)
598
599 def testParent2(self):
600 n = dns.name.from_text('foo.bar', None)
601 self.failUnless(n.parent() == dns.name.from_text('bar', None))
602 self.failUnless(n.parent().parent() == dns.name.empty)
603
604 def testParent3(self):
605 def bad():
606 n = dns.name.root
607 n.parent()
608 self.failUnlessRaises(dns.name.NoParent, bad)
609
610 def testParent4(self):
611 def bad():
612 n = dns.name.empty
613 n.parent()
614 self.failUnlessRaises(dns.name.NoParent, bad)
615
616 def testFromUnicode1(self):
617 n = dns.name.from_text(u'foo.bar')
618 self.failUnless(n.labels == ('foo', 'bar', ''))
619
620 def testFromUnicode2(self):
621 n = dns.name.from_text(u'foo\u1234bar.bar')
622 self.failUnless(n.labels == ('xn--foobar-r5z', 'bar', ''))
623
624 def testFromUnicodeAlternateDot1(self):
625 n = dns.name.from_text(u'foo\u3002bar')
626 self.failUnless(n.labels == ('foo', 'bar', ''))
627
628 def testFromUnicodeAlternateDot2(self):
629 n = dns.name.from_text(u'foo\uff0ebar')
630 self.failUnless(n.labels == ('foo', 'bar', ''))
631
632 def testFromUnicodeAlternateDot3(self):
633 n = dns.name.from_text(u'foo\uff61bar')
634 self.failUnless(n.labels == ('foo', 'bar', ''))
635
636 def testToUnicode1(self):
637 n = dns.name.from_text(u'foo.bar')
638 s = n.to_unicode()
639 self.failUnless(s == u'foo.bar.')
640
641 def testToUnicode2(self):
642 n = dns.name.from_text(u'foo\u1234bar.bar')
643 s = n.to_unicode()
644 self.failUnless(s == u'foo\u1234bar.bar.')
645
646 def testToUnicode3(self):
647 n = dns.name.from_text('foo.bar')
648 s = n.to_unicode()
649 self.failUnless(s == u'foo.bar.')
650
651 def testReverseIPv4(self):
652 e = dns.name.from_text('1.0.0.127.in-addr.arpa.')
653 n = dns.reversename.from_address('127.0.0.1')
654 self.failUnless(e == n)
655
656 def testReverseIPv6(self):
657 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.')
658 n = dns.reversename.from_address('::1')
659 self.failUnless(e == n)
660
661 def testBadReverseIPv4(self):
662 def bad():
663 n = dns.reversename.from_address('127.0.foo.1')
664 self.failUnlessRaises(dns.exception.SyntaxError, bad)
665
666 def testBadReverseIPv6(self):
667 def bad():
668 n = dns.reversename.from_address('::1::1')
669 self.failUnlessRaises(dns.exception.SyntaxError, bad)
670
671 def testForwardIPv4(self):
672 n = dns.name.from_text('1.0.0.127.in-addr.arpa.')
673 e = '127.0.0.1'
674 text = dns.reversename.to_address(n)
675 self.failUnless(text == e)
676
677 def testForwardIPv6(self):
678 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.')
679 e = '::1'
680 text = dns.reversename.to_address(n)
681 self.failUnless(text == e)
682
683 def testE164ToEnum(self):
684 text = '+1 650 555 1212'
685 e = dns.name.from_text('2.1.2.1.5.5.5.0.5.6.1.e164.arpa.')
686 n = dns.e164.from_e164(text)
687 self.failUnless(n == e)
688
689 def testEnumToE164(self):
690 n = dns.name.from_text('2.1.2.1.5.5.5.0.5.6.1.e164.arpa.')
691 e = '+16505551212'
692 text = dns.e164.to_e164(n)
693 self.failUnless(text == e)
694
695 if __name__ == '__main__':
696 unittest.main()
+0
-102
tests/namedict.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.name
18 import dns.namedict
19
20 class NameTestCase(unittest.TestCase):
21
22 def setUp(self):
23 self.ndict = dns.namedict.NameDict()
24 n1 = dns.name.from_text('foo.bar.')
25 n2 = dns.name.from_text('bar.')
26 self.ndict[n1] = 1
27 self.ndict[n2] = 2
28 self.rndict = dns.namedict.NameDict()
29 n1 = dns.name.from_text('foo.bar', None)
30 n2 = dns.name.from_text('bar', None)
31 self.rndict[n1] = 1
32 self.rndict[n2] = 2
33
34 def testDepth(self):
35 self.failUnless(self.ndict.max_depth == 3)
36
37 def testLookup1(self):
38 k = dns.name.from_text('foo.bar.')
39 self.failUnless(self.ndict[k] == 1)
40
41 def testLookup2(self):
42 k = dns.name.from_text('foo.bar.')
43 self.failUnless(self.ndict.get_deepest_match(k)[1] == 1)
44
45 def testLookup3(self):
46 k = dns.name.from_text('a.b.c.foo.bar.')
47 self.failUnless(self.ndict.get_deepest_match(k)[1] == 1)
48
49 def testLookup4(self):
50 k = dns.name.from_text('a.b.c.bar.')
51 self.failUnless(self.ndict.get_deepest_match(k)[1] == 2)
52
53 def testLookup5(self):
54 def bad():
55 n = dns.name.from_text('a.b.c.')
56 (k, v) = self.ndict.get_deepest_match(n)
57 self.failUnlessRaises(KeyError, bad)
58
59 def testLookup6(self):
60 def bad():
61 (k, v) = self.ndict.get_deepest_match(dns.name.empty)
62 self.failUnlessRaises(KeyError, bad)
63
64 def testLookup7(self):
65 self.ndict[dns.name.empty] = 100
66 n = dns.name.from_text('a.b.c.')
67 (k, v) = self.ndict.get_deepest_match(n)
68 self.failUnless(v == 100)
69
70 def testLookup8(self):
71 def bad():
72 self.ndict['foo'] = 100
73 self.failUnlessRaises(ValueError, bad)
74
75 def testRelDepth(self):
76 self.failUnless(self.rndict.max_depth == 2)
77
78 def testRelLookup1(self):
79 k = dns.name.from_text('foo.bar', None)
80 self.failUnless(self.rndict[k] == 1)
81
82 def testRelLookup2(self):
83 k = dns.name.from_text('foo.bar', None)
84 self.failUnless(self.rndict.get_deepest_match(k)[1] == 1)
85
86 def testRelLookup3(self):
87 k = dns.name.from_text('a.b.c.foo.bar', None)
88 self.failUnless(self.rndict.get_deepest_match(k)[1] == 1)
89
90 def testRelLookup4(self):
91 k = dns.name.from_text('a.b.c.bar', None)
92 self.failUnless(self.rndict.get_deepest_match(k)[1] == 2)
93
94 def testRelLookup7(self):
95 self.rndict[dns.name.empty] = 100
96 n = dns.name.from_text('a.b.c', None)
97 (k, v) = self.rndict.get_deepest_match(n)
98 self.failUnless(v == 100)
99
100 if __name__ == '__main__':
101 unittest.main()
+0
-203
tests/ntoaaton.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.exception
18 import dns.ipv4
19 import dns.ipv6
20
21 # for convenience
22 aton4 = dns.ipv4.inet_aton
23 ntoa4 = dns.ipv4.inet_ntoa
24 aton6 = dns.ipv6.inet_aton
25 ntoa6 = dns.ipv6.inet_ntoa
26
27 v4_bad_addrs = ['256.1.1.1', '1.1.1', '1.1.1.1.1', '01.1.1.1',
28 '+1.1.1.1', '1.1.1.1+', '1..2.3.4', '.1.2.3.4',
29 '1.2.3.4.']
30
31 class NtoAAtoNTestCase(unittest.TestCase):
32
33 def test_aton1(self):
34 a = aton6('::')
35 self.failUnless(a == '\x00' * 16)
36
37 def test_aton2(self):
38 a = aton6('::1')
39 self.failUnless(a == '\x00' * 15 + '\x01')
40
41 def test_aton3(self):
42 a = aton6('::10.0.0.1')
43 self.failUnless(a == '\x00' * 12 + '\x0a\x00\x00\x01')
44
45 def test_aton4(self):
46 a = aton6('abcd::dcba')
47 self.failUnless(a == '\xab\xcd' + '\x00' * 12 + '\xdc\xba')
48
49 def test_aton5(self):
50 a = aton6('1:2:3:4:5:6:7:8')
51 self.failUnless(a == \
52 '00010002000300040005000600070008'.decode('hex_codec'))
53
54 def test_bad_aton1(self):
55 def bad():
56 a = aton6('abcd:dcba')
57 self.failUnlessRaises(dns.exception.SyntaxError, bad)
58
59 def test_bad_aton2(self):
60 def bad():
61 a = aton6('abcd::dcba::1')
62 self.failUnlessRaises(dns.exception.SyntaxError, bad)
63
64 def test_bad_aton3(self):
65 def bad():
66 a = aton6('1:2:3:4:5:6:7:8:9')
67 self.failUnlessRaises(dns.exception.SyntaxError, bad)
68
69 def test_aton1(self):
70 a = aton6('::')
71 self.failUnless(a == '\x00' * 16)
72
73 def test_aton2(self):
74 a = aton6('::1')
75 self.failUnless(a == '\x00' * 15 + '\x01')
76
77 def test_aton3(self):
78 a = aton6('::10.0.0.1')
79 self.failUnless(a == '\x00' * 12 + '\x0a\x00\x00\x01')
80
81 def test_aton4(self):
82 a = aton6('abcd::dcba')
83 self.failUnless(a == '\xab\xcd' + '\x00' * 12 + '\xdc\xba')
84
85 def test_ntoa1(self):
86 b = '00010002000300040005000600070008'.decode('hex_codec')
87 t = ntoa6(b)
88 self.failUnless(t == '1:2:3:4:5:6:7:8')
89
90 def test_ntoa2(self):
91 b = '\x00' * 16
92 t = ntoa6(b)
93 self.failUnless(t == '::')
94
95 def test_ntoa3(self):
96 b = '\x00' * 15 + '\x01'
97 t = ntoa6(b)
98 self.failUnless(t == '::1')
99
100 def test_ntoa4(self):
101 b = '\x80' + '\x00' * 15
102 t = ntoa6(b)
103 self.failUnless(t == '8000::')
104
105 def test_ntoa5(self):
106 b = '\x01\xcd' + '\x00' * 12 + '\x03\xef'
107 t = ntoa6(b)
108 self.failUnless(t == '1cd::3ef')
109
110 def test_ntoa6(self):
111 b = 'ffff00000000ffff000000000000ffff'.decode('hex_codec')
112 t = ntoa6(b)
113 self.failUnless(t == 'ffff:0:0:ffff::ffff')
114
115 def test_ntoa7(self):
116 b = '00000000ffff000000000000ffffffff'.decode('hex_codec')
117 t = ntoa6(b)
118 self.failUnless(t == '0:0:ffff::ffff:ffff')
119
120 def test_ntoa8(self):
121 b = 'ffff0000ffff00000000ffff00000000'.decode('hex_codec')
122 t = ntoa6(b)
123 self.failUnless(t == 'ffff:0:ffff::ffff:0:0')
124
125 def test_ntoa9(self):
126 b = '0000000000000000000000000a000001'.decode('hex_codec')
127 t = ntoa6(b)
128 self.failUnless(t == '::10.0.0.1')
129
130 def test_ntoa10(self):
131 b = '0000000000000000000000010a000001'.decode('hex_codec')
132 t = ntoa6(b)
133 self.failUnless(t == '::1:a00:1')
134
135 def test_ntoa11(self):
136 b = '00000000000000000000ffff0a000001'.decode('hex_codec')
137 t = ntoa6(b)
138 self.failUnless(t == '::ffff:10.0.0.1')
139
140 def test_ntoa12(self):
141 b = '000000000000000000000000ffffffff'.decode('hex_codec')
142 t = ntoa6(b)
143 self.failUnless(t == '::255.255.255.255')
144
145 def test_ntoa13(self):
146 b = '00000000000000000000ffffffffffff'.decode('hex_codec')
147 t = ntoa6(b)
148 self.failUnless(t == '::ffff:255.255.255.255')
149
150 def test_ntoa14(self):
151 b = '0000000000000000000000000001ffff'.decode('hex_codec')
152 t = ntoa6(b)
153 self.failUnless(t == '::0.1.255.255')
154
155 def test_bad_ntoa1(self):
156 def bad():
157 a = ntoa6('')
158 self.failUnlessRaises(ValueError, bad)
159
160 def test_bad_ntoa2(self):
161 def bad():
162 a = ntoa6('\x00' * 17)
163 self.failUnlessRaises(ValueError, bad)
164
165 def test_good_v4_aton(self):
166 pairs = [('1.2.3.4', '\x01\x02\x03\x04'),
167 ('255.255.255.255', '\xff\xff\xff\xff'),
168 ('0.0.0.0', '\x00\x00\x00\x00')]
169 for (t, b) in pairs:
170 b1 = aton4(t)
171 t1 = ntoa4(b1)
172 self.failUnless(b1 == b)
173 self.failUnless(t1 == t)
174
175 def test_bad_v4_aton(self):
176 def make_bad(a):
177 def bad():
178 return aton4(a)
179 return bad
180 for addr in v4_bad_addrs:
181 self.failUnlessRaises(dns.exception.SyntaxError, make_bad(addr))
182
183 def test_bad_v6_aton(self):
184 addrs = ['+::0', '0::0::', '::0::', '1:2:3:4:5:6:7:8:9',
185 ':::::::']
186 embedded = ['::' + x for x in v4_bad_addrs]
187 addrs.extend(embedded)
188 def make_bad(a):
189 def bad():
190 x = aton6(a)
191 return bad
192 for addr in addrs:
193 self.failUnlessRaises(dns.exception.SyntaxError, make_bad(addr))
194
195 def test_rfc5952_section_4_2_2(self):
196 addr = '2001:db8:0:1:1:1:1:1'
197 b1 = aton6(addr)
198 t1 = ntoa6(b1)
199 self.failUnless(t1 == addr)
200
201 if __name__ == '__main__':
202 unittest.main()
+0
-123
tests/rdtypeandclass.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.rdataclass
18 import dns.rdatatype
19
20 class RdTypeAndClassTestCase(unittest.TestCase):
21
22 # Classes
23
24 def test_class_meta1(self):
25 self.failUnless(dns.rdataclass.is_metaclass(dns.rdataclass.ANY))
26
27 def test_class_meta2(self):
28 self.failUnless(not dns.rdataclass.is_metaclass(dns.rdataclass.IN))
29
30 def test_class_bytext1(self):
31 self.failUnless(dns.rdataclass.from_text('IN') == dns.rdataclass.IN)
32
33 def test_class_bytext2(self):
34 self.failUnless(dns.rdataclass.from_text('CLASS1') ==
35 dns.rdataclass.IN)
36
37 def test_class_bytext_bounds1(self):
38 self.failUnless(dns.rdataclass.from_text('CLASS0') == 0)
39 self.failUnless(dns.rdataclass.from_text('CLASS65535') == 65535)
40
41 def test_class_bytext_bounds2(self):
42 def bad():
43 junk = dns.rdataclass.from_text('CLASS65536')
44 self.failUnlessRaises(ValueError, bad)
45
46 def test_class_bytext_unknown(self):
47 def bad():
48 junk = dns.rdataclass.from_text('XXX')
49 self.failUnlessRaises(dns.rdataclass.UnknownRdataclass, bad)
50
51 def test_class_totext1(self):
52 self.failUnless(dns.rdataclass.to_text(dns.rdataclass.IN) == 'IN')
53
54 def test_class_totext1(self):
55 self.failUnless(dns.rdataclass.to_text(999) == 'CLASS999')
56
57 def test_class_totext_bounds1(self):
58 def bad():
59 junk = dns.rdataclass.to_text(-1)
60 self.failUnlessRaises(ValueError, bad)
61
62 def test_class_totext_bounds2(self):
63 def bad():
64 junk = dns.rdataclass.to_text(65536)
65 self.failUnlessRaises(ValueError, bad)
66
67 # Types
68
69 def test_type_meta1(self):
70 self.failUnless(dns.rdatatype.is_metatype(dns.rdatatype.ANY))
71
72 def test_type_meta2(self):
73 self.failUnless(dns.rdatatype.is_metatype(dns.rdatatype.OPT))
74
75 def test_type_meta3(self):
76 self.failUnless(not dns.rdatatype.is_metatype(dns.rdatatype.A))
77
78 def test_type_singleton1(self):
79 self.failUnless(dns.rdatatype.is_singleton(dns.rdatatype.SOA))
80
81 def test_type_singleton2(self):
82 self.failUnless(not dns.rdatatype.is_singleton(dns.rdatatype.A))
83
84 def test_type_bytext1(self):
85 self.failUnless(dns.rdatatype.from_text('A') == dns.rdatatype.A)
86
87 def test_type_bytext2(self):
88 self.failUnless(dns.rdatatype.from_text('TYPE1') ==
89 dns.rdatatype.A)
90
91 def test_type_bytext_bounds1(self):
92 self.failUnless(dns.rdatatype.from_text('TYPE0') == 0)
93 self.failUnless(dns.rdatatype.from_text('TYPE65535') == 65535)
94
95 def test_type_bytext_bounds2(self):
96 def bad():
97 junk = dns.rdatatype.from_text('TYPE65536')
98 self.failUnlessRaises(ValueError, bad)
99
100 def test_type_bytext_unknown(self):
101 def bad():
102 junk = dns.rdatatype.from_text('XXX')
103 self.failUnlessRaises(dns.rdatatype.UnknownRdatatype, bad)
104
105 def test_type_totext1(self):
106 self.failUnless(dns.rdatatype.to_text(dns.rdatatype.A) == 'A')
107
108 def test_type_totext1(self):
109 self.failUnless(dns.rdatatype.to_text(999) == 'TYPE999')
110
111 def test_type_totext_bounds1(self):
112 def bad():
113 junk = dns.rdatatype.to_text(-1)
114 self.failUnlessRaises(ValueError, bad)
115
116 def test_type_totext_bounds2(self):
117 def bad():
118 junk = dns.rdatatype.to_text(65536)
119 self.failUnlessRaises(ValueError, bad)
120
121 if __name__ == '__main__':
122 unittest.main()
+0
-184
tests/resolver.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import cStringIO
16 import select
17 import sys
18 import time
19 import unittest
20
21 import dns.name
22 import dns.message
23 import dns.name
24 import dns.rdataclass
25 import dns.rdatatype
26 import dns.resolver
27
28 resolv_conf = """
29 /t/t
30 # comment 1
31 ; comment 2
32 domain foo
33 nameserver 10.0.0.1
34 nameserver 10.0.0.2
35 """
36
37 message_text = """id 1234
38 opcode QUERY
39 rcode NOERROR
40 flags QR AA RD
41 ;QUESTION
42 example. IN A
43 ;ANSWER
44 example. 1 IN A 10.0.0.1
45 ;AUTHORITY
46 ;ADDITIONAL
47 """
48
49 class FakeAnswer(object):
50 def __init__(self, expiration):
51 self.expiration = expiration
52
53 class BaseResolverTests(object):
54
55 if sys.platform != 'win32':
56 def testRead(self):
57 f = cStringIO.StringIO(resolv_conf)
58 r = dns.resolver.Resolver(f)
59 self.failUnless(r.nameservers == ['10.0.0.1', '10.0.0.2'] and
60 r.domain == dns.name.from_text('foo'))
61
62 def testCacheExpiration(self):
63 message = dns.message.from_text(message_text)
64 name = dns.name.from_text('example.')
65 answer = dns.resolver.Answer(name, dns.rdatatype.A, dns.rdataclass.IN,
66 message)
67 cache = dns.resolver.Cache()
68 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
69 time.sleep(2)
70 self.failUnless(cache.get((name, dns.rdatatype.A, dns.rdataclass.IN))
71 is None)
72
73 def testCacheCleaning(self):
74 message = dns.message.from_text(message_text)
75 name = dns.name.from_text('example.')
76 answer = dns.resolver.Answer(name, dns.rdatatype.A, dns.rdataclass.IN,
77 message)
78 cache = dns.resolver.Cache(cleaning_interval=1.0)
79 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
80 time.sleep(2)
81 self.failUnless(cache.get((name, dns.rdatatype.A, dns.rdataclass.IN))
82 is None)
83
84 def testZoneForName1(self):
85 name = dns.name.from_text('www.dnspython.org.')
86 ezname = dns.name.from_text('dnspython.org.')
87 zname = dns.resolver.zone_for_name(name)
88 self.failUnless(zname == ezname)
89
90 def testZoneForName2(self):
91 name = dns.name.from_text('a.b.www.dnspython.org.')
92 ezname = dns.name.from_text('dnspython.org.')
93 zname = dns.resolver.zone_for_name(name)
94 self.failUnless(zname == ezname)
95
96 def testZoneForName3(self):
97 name = dns.name.from_text('dnspython.org.')
98 ezname = dns.name.from_text('dnspython.org.')
99 zname = dns.resolver.zone_for_name(name)
100 self.failUnless(zname == ezname)
101
102 def testZoneForName4(self):
103 def bad():
104 name = dns.name.from_text('dnspython.org', None)
105 zname = dns.resolver.zone_for_name(name)
106 self.failUnlessRaises(dns.resolver.NotAbsolute, bad)
107
108 def testLRUReplace(self):
109 cache = dns.resolver.LRUCache(4)
110 for i in xrange(0, 5):
111 name = dns.name.from_text('example%d.' % i)
112 answer = FakeAnswer(time.time() + 1)
113 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
114 for i in xrange(0, 5):
115 name = dns.name.from_text('example%d.' % i)
116 if i == 0:
117 self.failUnless(cache.get((name, dns.rdatatype.A,
118 dns.rdataclass.IN))
119 is None)
120 else:
121 self.failUnless(not cache.get((name, dns.rdatatype.A,
122 dns.rdataclass.IN))
123 is None)
124
125 def testLRUDoesLRU(self):
126 cache = dns.resolver.LRUCache(4)
127 for i in xrange(0, 4):
128 name = dns.name.from_text('example%d.' % i)
129 answer = FakeAnswer(time.time() + 1)
130 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
131 name = dns.name.from_text('example0.')
132 cache.get((name, dns.rdatatype.A, dns.rdataclass.IN))
133 # The LRU is now example1.
134 name = dns.name.from_text('example4.')
135 answer = FakeAnswer(time.time() + 1)
136 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
137 for i in xrange(0, 5):
138 name = dns.name.from_text('example%d.' % i)
139 if i == 1:
140 self.failUnless(cache.get((name, dns.rdatatype.A,
141 dns.rdataclass.IN))
142 is None)
143 else:
144 self.failUnless(not cache.get((name, dns.rdatatype.A,
145 dns.rdataclass.IN))
146 is None)
147
148 def testLRUExpiration(self):
149 cache = dns.resolver.LRUCache(4)
150 for i in xrange(0, 4):
151 name = dns.name.from_text('example%d.' % i)
152 answer = FakeAnswer(time.time() + 1)
153 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
154 time.sleep(2)
155 for i in xrange(0, 4):
156 name = dns.name.from_text('example%d.' % i)
157 self.failUnless(cache.get((name, dns.rdatatype.A,
158 dns.rdataclass.IN))
159 is None)
160
161 class PollingMonkeyPatchMixin(object):
162 def setUp(self):
163 self.__native_polling_backend = dns.query._polling_backend
164 dns.query._set_polling_backend(self.polling_backend())
165
166 unittest.TestCase.setUp(self)
167
168 def tearDown(self):
169 dns.query._set_polling_backend(self.__native_polling_backend)
170
171 unittest.TestCase.tearDown(self)
172
173 class SelectResolverTestCase(PollingMonkeyPatchMixin, BaseResolverTests, unittest.TestCase):
174 def polling_backend(self):
175 return dns.query._select_for
176
177 if hasattr(select, 'poll'):
178 class PollResolverTestCase(PollingMonkeyPatchMixin, BaseResolverTests, unittest.TestCase):
179 def polling_backend(self):
180 return dns.query._poll_for
181
182 if __name__ == '__main__':
183 unittest.main()
+0
-54
tests/rrset.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.rrset
18
19 class RRsetTestCase(unittest.TestCase):
20
21 def testEqual1(self):
22 r1 = dns.rrset.from_text('foo', 300, 'in', 'a', '10.0.0.1', '10.0.0.2')
23 r2 = dns.rrset.from_text('FOO', 300, 'in', 'a', '10.0.0.2', '10.0.0.1')
24 self.failUnless(r1 == r2)
25
26 def testEqual2(self):
27 r1 = dns.rrset.from_text('foo', 300, 'in', 'a', '10.0.0.1', '10.0.0.2')
28 r2 = dns.rrset.from_text('FOO', 600, 'in', 'a', '10.0.0.2', '10.0.0.1')
29 self.failUnless(r1 == r2)
30
31 def testNotEqual1(self):
32 r1 = dns.rrset.from_text('fooa', 30, 'in', 'a', '10.0.0.1', '10.0.0.2')
33 r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1')
34 self.failUnless(r1 != r2)
35
36 def testNotEqual2(self):
37 r1 = dns.rrset.from_text('foo', 30, 'in', 'a', '10.0.0.1', '10.0.0.3')
38 r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1')
39 self.failUnless(r1 != r2)
40
41 def testNotEqual3(self):
42 r1 = dns.rrset.from_text('foo', 30, 'in', 'a', '10.0.0.1', '10.0.0.2',
43 '10.0.0.3')
44 r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1')
45 self.failUnless(r1 != r2)
46
47 def testNotEqual4(self):
48 r1 = dns.rrset.from_text('foo', 30, 'in', 'a', '10.0.0.1')
49 r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1')
50 self.failUnless(r1 != r2)
51
52 if __name__ == '__main__':
53 unittest.main()
+0
-208
tests/set.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.set
18
19 # for convenience
20 S = dns.set.Set
21
22 class SimpleSetTestCase(unittest.TestCase):
23
24 def testLen1(self):
25 s1 = S()
26 self.failUnless(len(s1) == 0)
27
28 def testLen2(self):
29 s1 = S([1, 2, 3])
30 self.failUnless(len(s1) == 3)
31
32 def testLen3(self):
33 s1 = S([1, 2, 3, 3, 3])
34 self.failUnless(len(s1) == 3)
35
36 def testUnion1(self):
37 s1 = S([1, 2, 3])
38 s2 = S([1, 2, 3])
39 e = S([1, 2, 3])
40 self.failUnless(s1 | s2 == e)
41
42 def testUnion2(self):
43 s1 = S([1, 2, 3])
44 s2 = S([])
45 e = S([1, 2, 3])
46 self.failUnless(s1 | s2 == e)
47
48 def testUnion3(self):
49 s1 = S([1, 2, 3])
50 s2 = S([3, 4])
51 e = S([1, 2, 3, 4])
52 self.failUnless(s1 | s2 == e)
53
54 def testIntersection1(self):
55 s1 = S([1, 2, 3])
56 s2 = S([1, 2, 3])
57 e = S([1, 2, 3])
58 self.failUnless(s1 & s2 == e)
59
60 def testIntersection2(self):
61 s1 = S([0, 1, 2, 3])
62 s2 = S([1, 2, 3, 4])
63 e = S([1, 2, 3])
64 self.failUnless(s1 & s2 == e)
65
66 def testIntersection3(self):
67 s1 = S([1, 2, 3])
68 s2 = S([])
69 e = S([])
70 self.failUnless(s1 & s2 == e)
71
72 def testIntersection4(self):
73 s1 = S([1, 2, 3])
74 s2 = S([5, 4])
75 e = S([])
76 self.failUnless(s1 & s2 == e)
77
78 def testDifference1(self):
79 s1 = S([1, 2, 3])
80 s2 = S([5, 4])
81 e = S([1, 2, 3])
82 self.failUnless(s1 - s2 == e)
83
84 def testDifference2(self):
85 s1 = S([1, 2, 3])
86 s2 = S([])
87 e = S([1, 2, 3])
88 self.failUnless(s1 - s2 == e)
89
90 def testDifference3(self):
91 s1 = S([1, 2, 3])
92 s2 = S([3, 2])
93 e = S([1])
94 self.failUnless(s1 - s2 == e)
95
96 def testDifference4(self):
97 s1 = S([1, 2, 3])
98 s2 = S([3, 2, 1])
99 e = S([])
100 self.failUnless(s1 - s2 == e)
101
102 def testSubset1(self):
103 s1 = S([1, 2, 3])
104 s2 = S([3, 2, 1])
105 self.failUnless(s1.issubset(s2))
106
107 def testSubset2(self):
108 s1 = S([1, 2, 3])
109 self.failUnless(s1.issubset(s1))
110
111 def testSubset3(self):
112 s1 = S([])
113 s2 = S([1, 2, 3])
114 self.failUnless(s1.issubset(s2))
115
116 def testSubset4(self):
117 s1 = S([1])
118 s2 = S([1, 2, 3])
119 self.failUnless(s1.issubset(s2))
120
121 def testSubset5(self):
122 s1 = S([])
123 s2 = S([])
124 self.failUnless(s1.issubset(s2))
125
126 def testSubset6(self):
127 s1 = S([1, 4])
128 s2 = S([1, 2, 3])
129 self.failUnless(not s1.issubset(s2))
130
131 def testSuperset1(self):
132 s1 = S([1, 2, 3])
133 s2 = S([3, 2, 1])
134 self.failUnless(s1.issuperset(s2))
135
136 def testSuperset2(self):
137 s1 = S([1, 2, 3])
138 self.failUnless(s1.issuperset(s1))
139
140 def testSuperset3(self):
141 s1 = S([1, 2, 3])
142 s2 = S([])
143 self.failUnless(s1.issuperset(s2))
144
145 def testSuperset4(self):
146 s1 = S([1, 2, 3])
147 s2 = S([1])
148 self.failUnless(s1.issuperset(s2))
149
150 def testSuperset5(self):
151 s1 = S([])
152 s2 = S([])
153 self.failUnless(s1.issuperset(s2))
154
155 def testSuperset6(self):
156 s1 = S([1, 2, 3])
157 s2 = S([1, 4])
158 self.failUnless(not s1.issuperset(s2))
159
160 def testUpdate1(self):
161 s1 = S([1, 2, 3])
162 u = (4, 5, 6)
163 e = S([1, 2, 3, 4, 5, 6])
164 s1.update(u)
165 self.failUnless(s1 == e)
166
167 def testUpdate2(self):
168 s1 = S([1, 2, 3])
169 u = []
170 e = S([1, 2, 3])
171 s1.update(u)
172 self.failUnless(s1 == e)
173
174 def testGetitem(self):
175 s1 = S([1, 2, 3])
176 i0 = s1[0]
177 i1 = s1[1]
178 i2 = s1[2]
179 s2 = S([i0, i1, i2])
180 self.failUnless(s1 == s2)
181
182 def testGetslice(self):
183 s1 = S([1, 2, 3])
184 slice = s1[0:2]
185 self.failUnless(len(slice) == 2)
186 item = s1[2]
187 slice.append(item)
188 s2 = S(slice)
189 self.failUnless(s1 == s2)
190
191 def testDelitem(self):
192 s1 = S([1, 2, 3])
193 del s1[0]
194 i1 = s1[0]
195 i2 = s1[1]
196 self.failUnless(i1 != i2)
197 self.failUnless(i1 == 1 or i1 == 2 or i1 == 3)
198 self.failUnless(i2 == 1 or i2 == 2 or i2 == 3)
199
200 def testDelslice(self):
201 s1 = S([1, 2, 3])
202 del s1[0:2]
203 i1 = s1[0]
204 self.failUnless(i1 == 1 or i1 == 2 or i1 == 3)
205
206 if __name__ == '__main__':
207 unittest.main()
0 # Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.rdata
18 import dns.rdataclass
19 import dns.rdatatype
20 import dns.ttl
21
22 class BugsTestCase(unittest.TestCase):
23
24 def test_float_LOC(self):
25 rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.LOC,
26 "30 30 0.000 N 100 30 0.000 W 10.00m 20m 2000m 20m")
27 self.failUnless(rdata.float_latitude == 30.5)
28 self.failUnless(rdata.float_longitude == -100.5)
29
30 def test_SOA_BIND8_TTL(self):
31 rdata1 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
32 "a b 100 1s 1m 1h 1d")
33 rdata2 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
34 "a b 100 1 60 3600 86400")
35 self.failUnless(rdata1 == rdata2)
36
37 def test_TTL_bounds_check(self):
38 def bad():
39 ttl = dns.ttl.from_text("2147483648")
40 self.failUnlessRaises(dns.ttl.BadTTL, bad)
41
42 def test_empty_NSEC3_window(self):
43 rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NSEC3,
44 "1 0 100 ABCD SCBCQHKU35969L2A68P3AD59LHF30715")
45 self.failUnless(rdata.windows == [])
46
47 def test_zero_size_APL(self):
48 rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.APL,
49 "")
50 rdata2 = dns.rdata.from_wire(dns.rdataclass.IN, dns.rdatatype.APL,
51 "", 0, 0)
52 self.failUnless(rdata == rdata2)
53
54 if __name__ == '__main__':
55 unittest.main()
0 # Copyright (C) 2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.dnssec
18 import dns.name
19 import dns.rdata
20 import dns.rdataclass
21 import dns.rdatatype
22 import dns.rrset
23
24 abs_dnspython_org = dns.name.from_text('dnspython.org')
25
26 abs_keys = { abs_dnspython_org :
27 dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'DNSKEY',
28 '257 3 5 AwEAAenVTr9L1OMlL1/N2ta0Qj9LLLnnmFWIr1dJoAsWM9BQfsbV7kFZ XbAkER/FY9Ji2o7cELxBwAsVBuWn6IUUAJXLH74YbC1anY0lifjgt29z SwDzuB7zmC7yVYZzUunBulVW4zT0tg1aePbpVL2EtTL8VzREqbJbE25R KuQYHZtFwG8S4iBxJUmT2Bbd0921LLxSQgVoFXlQx/gFV2+UERXcJ5ce iX6A6wc02M/pdg/YbJd2rBa0MYL3/Fz/Xltre0tqsImZGxzi6YtYDs45 NC8gH+44egz82e2DATCVM1ICPmRDjXYTLldQiWA2ZXIWnK0iitl5ue24 7EsWJefrIhE=',
29 '256 3 5 AwEAAdSSghOGjU33IQZgwZM2Hh771VGXX05olJK49FxpSyuEAjDBXY58 LGU9R2Zgeecnk/b9EAhFu/vCV9oECtiTCvwuVAkt9YEweqYDluQInmgP NGMJCKdSLlnX93DkjDw8rMYv5dqXCuSGPlKChfTJOLQxIAxGloS7lL+c 0CTZydAF')
30 }
31
32 abs_keys_duplicate_keytag = { abs_dnspython_org :
33 dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'DNSKEY',
34 '257 3 5 AwEAAenVTr9L1OMlL1/N2ta0Qj9LLLnnmFWIr1dJoAsWM9BQfsbV7kFZ XbAkER/FY9Ji2o7cELxBwAsVBuWn6IUUAJXLH74YbC1anY0lifjgt29z SwDzuB7zmC7yVYZzUunBulVW4zT0tg1aePbpVL2EtTL8VzREqbJbE25R KuQYHZtFwG8S4iBxJUmT2Bbd0921LLxSQgVoFXlQx/gFV2+UERXcJ5ce iX6A6wc02M/pdg/YbJd2rBa0MYL3/Fz/Xltre0tqsImZGxzi6YtYDs45 NC8gH+44egz82e2DATCVM1ICPmRDjXYTLldQiWA2ZXIWnK0iitl5ue24 7EsWJefrIhE=',
35 '256 3 5 AwEAAdSSg++++THIS/IS/NOT/THE/CORRECT/KEY++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AaOSydAF',
36 '256 3 5 AwEAAdSSghOGjU33IQZgwZM2Hh771VGXX05olJK49FxpSyuEAjDBXY58 LGU9R2Zgeecnk/b9EAhFu/vCV9oECtiTCvwuVAkt9YEweqYDluQInmgP NGMJCKdSLlnX93DkjDw8rMYv5dqXCuSGPlKChfTJOLQxIAxGloS7lL+c 0CTZydAF')
37 }
38
39 rel_keys = { dns.name.empty :
40 dns.rrset.from_text('@', 3600, 'IN', 'DNSKEY',
41 '257 3 5 AwEAAenVTr9L1OMlL1/N2ta0Qj9LLLnnmFWIr1dJoAsWM9BQfsbV7kFZ XbAkER/FY9Ji2o7cELxBwAsVBuWn6IUUAJXLH74YbC1anY0lifjgt29z SwDzuB7zmC7yVYZzUunBulVW4zT0tg1aePbpVL2EtTL8VzREqbJbE25R KuQYHZtFwG8S4iBxJUmT2Bbd0921LLxSQgVoFXlQx/gFV2+UERXcJ5ce iX6A6wc02M/pdg/YbJd2rBa0MYL3/Fz/Xltre0tqsImZGxzi6YtYDs45 NC8gH+44egz82e2DATCVM1ICPmRDjXYTLldQiWA2ZXIWnK0iitl5ue24 7EsWJefrIhE=',
42 '256 3 5 AwEAAdSSghOGjU33IQZgwZM2Hh771VGXX05olJK49FxpSyuEAjDBXY58 LGU9R2Zgeecnk/b9EAhFu/vCV9oECtiTCvwuVAkt9YEweqYDluQInmgP NGMJCKdSLlnX93DkjDw8rMYv5dqXCuSGPlKChfTJOLQxIAxGloS7lL+c 0CTZydAF')
43 }
44
45 when = 1290250287
46
47 abs_soa = dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'SOA',
48 'howl.dnspython.org. hostmaster.dnspython.org. 2010020047 3600 1800 604800 3600')
49
50 abs_other_soa = dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'SOA',
51 'foo.dnspython.org. hostmaster.dnspython.org. 2010020047 3600 1800 604800 3600')
52
53 abs_soa_rrsig = dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'RRSIG',
54 'SOA 5 2 3600 20101127004331 20101119213831 61695 dnspython.org. sDUlltRlFTQw5ITFxOXW3TgmrHeMeNpdqcZ4EXxM9FHhIlte6V9YCnDw t6dvM9jAXdIEi03l9H/RAd9xNNW6gvGMHsBGzpvvqFQxIBR2PoiZA1mX /SWHZFdbt4xjYTtXqpyYvrMK0Dt7bUYPadyhPFCJ1B+I8Zi7B5WJEOd0 8vs=')
55
56 rel_soa = dns.rrset.from_text('@', 3600, 'IN', 'SOA',
57 'howl hostmaster 2010020047 3600 1800 604800 3600')
58
59 rel_other_soa = dns.rrset.from_text('@', 3600, 'IN', 'SOA',
60 'foo hostmaster 2010020047 3600 1800 604800 3600')
61
62 rel_soa_rrsig = dns.rrset.from_text('@', 3600, 'IN', 'RRSIG',
63 'SOA 5 2 3600 20101127004331 20101119213831 61695 @ sDUlltRlFTQw5ITFxOXW3TgmrHeMeNpdqcZ4EXxM9FHhIlte6V9YCnDw t6dvM9jAXdIEi03l9H/RAd9xNNW6gvGMHsBGzpvvqFQxIBR2PoiZA1mX /SWHZFdbt4xjYTtXqpyYvrMK0Dt7bUYPadyhPFCJ1B+I8Zi7B5WJEOd0 8vs=')
64
65 sep_key = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DNSKEY,
66 '257 3 5 AwEAAenVTr9L1OMlL1/N2ta0Qj9LLLnnmFWIr1dJoAsWM9BQfsbV7kFZ XbAkER/FY9Ji2o7cELxBwAsVBuWn6IUUAJXLH74YbC1anY0lifjgt29z SwDzuB7zmC7yVYZzUunBulVW4zT0tg1aePbpVL2EtTL8VzREqbJbE25R KuQYHZtFwG8S4iBxJUmT2Bbd0921LLxSQgVoFXlQx/gFV2+UERXcJ5ce iX6A6wc02M/pdg/YbJd2rBa0MYL3/Fz/Xltre0tqsImZGxzi6YtYDs45 NC8gH+44egz82e2DATCVM1ICPmRDjXYTLldQiWA2ZXIWnK0iitl5ue24 7EsWJefrIhE=')
67
68 good_ds = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DS,
69 '57349 5 2 53A79A3E7488AB44FFC56B2D1109F0699D1796DD977E72108B841F96 E47D7013')
70
71 when2 = 1290425644
72
73 abs_example = dns.name.from_text('example')
74
75 abs_dsa_keys = { abs_example :
76 dns.rrset.from_text('example.', 86400, 'IN', 'DNSKEY',
77 '257 3 3 CI3nCqyJsiCJHTjrNsJOT4RaszetzcJPYuoH3F9ZTVt3KJXncCVR3bwn 1w0iavKljb9hDlAYSfHbFCp4ic/rvg4p1L8vh5s8ToMjqDNl40A0hUGQ Ybx5hsECyK+qHoajilUX1phYSAD8d9WAGO3fDWzUPBuzR7o85NiZCDxz yXuNVfni0uhj9n1KYhEO5yAbbruDGN89wIZcxMKuQsdUY2GYD93ssnBv a55W6XRABYWayKZ90WkRVODLVYLSn53Pj/wwxGH+XdhIAZJXimrZL4yl My7rtBsLMqq8Ihs4Tows7LqYwY7cp6y/50tw6pj8tFqMYcPUjKZV36l1 M/2t5BVg3i7IK61Aidt6aoC3TDJtzAxg3ZxfjZWJfhHjMJqzQIfbW5b9 q1mjFsW5EUv39RaNnX+3JWPRLyDqD4pIwDyqfutMsdk/Py3paHn82FGp CaOg+nicqZ9TiMZURN/XXy5JoXUNQ3RNvbHCUiPUe18KUkY6mTfnyHld 1l9YCWmzXQVClkx/hOYxjJ4j8Ife58+Obu5X',
78 '256 3 3 CJE1yb9YRQiw5d2xZrMUMR+cGCTt1bp1KDCefmYKmS+Z1+q9f42ETVhx JRiQwXclYwmxborzIkSZegTNYIV6mrYwbNB27Q44c3UGcspb3PiOw5TC jNPRYEcdwGvDZ2wWy+vkSV/S9tHXY8O6ODiE6abZJDDg/RnITyi+eoDL R3KZ5n/V1f1T1b90rrV6EewhBGQJpQGDogaXb2oHww9Tm6NfXyo7SoMM pbwbzOckXv+GxRPJIQNSF4D4A9E8XCksuzVVdE/0lr37+uoiAiPia38U 5W2QWe/FJAEPLjIp2eTzf0TrADc1pKP1wrA2ASpdzpm/aX3IB5RPp8Ew S9U72eBFZJAUwg635HxJVxH1maG6atzorR566E+e0OZSaxXS9o1o6QqN 3oPlYLGPORDiExilKfez3C/x/yioOupW9K5eKF0gmtaqrHX0oq9s67f/ RIM2xVaKHgG9Vf2cgJIZkhv7sntujr+E4htnRmy9P9BxyFxsItYxPI6Z bzygHAZpGhlI/7ltEGlIwKxyTK3ZKBm67q7B')
79 }
80
81 abs_dsa_soa = dns.rrset.from_text('example.', 86400, 'IN', 'SOA',
82 'ns1.example. hostmaster.example. 2 10800 3600 604800 86400')
83
84 abs_other_dsa_soa = dns.rrset.from_text('example.', 86400, 'IN', 'SOA',
85 'ns1.example. hostmaster.example. 2 10800 3600 604800 86401')
86
87 abs_dsa_soa_rrsig = dns.rrset.from_text('example.', 86400, 'IN', 'RRSIG',
88 'SOA 3 1 86400 20101129143231 20101122112731 42088 example. CGul9SuBofsktunV8cJs4eRs6u+3NCS3yaPKvBbD+pB2C76OUXDZq9U=')
89
90 example_sep_key = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DNSKEY,
91 '257 3 3 CI3nCqyJsiCJHTjrNsJOT4RaszetzcJPYuoH3F9ZTVt3KJXncCVR3bwn 1w0iavKljb9hDlAYSfHbFCp4ic/rvg4p1L8vh5s8ToMjqDNl40A0hUGQ Ybx5hsECyK+qHoajilUX1phYSAD8d9WAGO3fDWzUPBuzR7o85NiZCDxz yXuNVfni0uhj9n1KYhEO5yAbbruDGN89wIZcxMKuQsdUY2GYD93ssnBv a55W6XRABYWayKZ90WkRVODLVYLSn53Pj/wwxGH+XdhIAZJXimrZL4yl My7rtBsLMqq8Ihs4Tows7LqYwY7cp6y/50tw6pj8tFqMYcPUjKZV36l1 M/2t5BVg3i7IK61Aidt6aoC3TDJtzAxg3ZxfjZWJfhHjMJqzQIfbW5b9 q1mjFsW5EUv39RaNnX+3JWPRLyDqD4pIwDyqfutMsdk/Py3paHn82FGp CaOg+nicqZ9TiMZURN/XXy5JoXUNQ3RNvbHCUiPUe18KUkY6mTfnyHld 1l9YCWmzXQVClkx/hOYxjJ4j8Ife58+Obu5X')
92
93 example_ds_sha1 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DS,
94 '18673 3 1 71b71d4f3e11bbd71b4eff12cde69f7f9215bbe7')
95
96 example_ds_sha256 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DS,
97 '18673 3 2 eb8344cbbf07c9d3d3d6c81d10c76653e28d8611a65e639ef8f716e4e4e5d913')
98
99 when3 = 1379801800
100
101 abs_ecdsa256_keys = { abs_example :
102 dns.rrset.from_text('example.', 86400, 'IN', 'DNSKEY',
103 "256 3 13 +3ss1sCpdARVA61DJigEsL/8quo2a8MszKtn2gkkfxgzFs8S2UHtpb4N fY+XFmNW+JK6MsCkI3jHYN8eEQUgMw==",
104 "257 3 13 eJCEVH7AS3wnoaQpaNlAXH0W8wxymtT9P6P3qjN2ZCV641ED8pF7wZ5V yWfOpgTs6oaZevbJgehl/GaRPUgVyQ==")
105 }
106
107 abs_ecdsa256_soa = dns.rrset.from_text('example.', 86400, 'IN', 'SOA',
108 'ns1.example. hostmaster.example. 4 10800 3600 604800 86400')
109
110 abs_other_ecdsa256_soa = dns.rrset.from_text('example.', 86400, 'IN', 'SOA',
111 'ns1.example. hostmaster.example. 2 10800 3600 604800 86401')
112
113 abs_ecdsa256_soa_rrsig = dns.rrset.from_text('example.', 86400, 'IN', 'RRSIG',
114 "SOA 13 1 86400 20130921221753 20130921221638 7460 example. Sm09SOGz1ULB5D/duwdE2Zpn8bWbVBM77H6N1wPkc42LevvVO+kZEjpq 2nq4GOMJcih52667GIAbMrwmU5P2MQ==")
115
116 when4 = 1379804850
117
118 abs_ecdsa384_keys = { abs_example :
119 dns.rrset.from_text('example.', 86400, 'IN', 'DNSKEY',
120 "256 3 14 1bG8qWviKNXQX3BIuG6/T5jrP1FISiLW/8qGF6BsM9DQtWYhhZUA3Owr OAEiyHAhQwjkN2kTvWiAYoPN80Ii+5ff9/atzY4F9W50P4l75Dj9PYrL HN/hLUgWMNVc9pvA",
121 "257 3 14 mSub2n0KRt6u2FaD5XJ3oQu0R4XvB/9vUJcyW6+oo0y+KzfQeTdkf1ro ZMVKoyWXW9zUKBYGJpMUIdbAxzrYi7f5HyZ3yDpBFz1hw9+o3CX+gtgb +RyhHfJDwwFXBid9")
122 }
123
124 abs_ecdsa384_soa = dns.rrset.from_text('example.', 86400, 'IN', 'SOA',
125 'ns1.example. hostmaster.example. 2 10800 3600 604800 86400')
126
127 abs_other_ecdsa384_soa = dns.rrset.from_text('example.', 86400, 'IN', 'SOA',
128 'ns1.example. hostmaster.example. 2 10800 3600 604800 86401')
129
130 abs_ecdsa384_soa_rrsig = dns.rrset.from_text('example.', 86400, 'IN', 'RRSIG',
131 "SOA 14 1 86400 20130929021229 20130921230729 63571 example. CrnCu34EeeRz0fEhL9PLlwjpBKGYW8QjBjFQTwd+ViVLRAS8tNkcDwQE NhSV89NEjj7ze1a/JcCfcJ+/mZgnvH4NHLNg3Tf6KuLZsgs2I4kKQXEk 37oIHravPEOlGYNI")
132
133 class DNSSECValidatorTestCase(unittest.TestCase):
134
135 @unittest.skipIf(not dns.dnssec._have_pycrypto,
136 "PyCrypto cannot be imported")
137 def testAbsoluteRSAGood(self):
138 dns.dnssec.validate(abs_soa, abs_soa_rrsig, abs_keys, None, when)
139
140 @unittest.skipIf(not dns.dnssec._have_pycrypto,
141 "PyCrypto cannot be imported")
142 def testDuplicateKeytag(self):
143 dns.dnssec.validate(abs_soa, abs_soa_rrsig, abs_keys_duplicate_keytag, None, when)
144
145 @unittest.skipIf(not dns.dnssec._have_pycrypto,
146 "PyCrypto cannot be imported")
147 def testAbsoluteRSABad(self):
148 def bad():
149 dns.dnssec.validate(abs_other_soa, abs_soa_rrsig, abs_keys, None,
150 when)
151 self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
152
153 @unittest.skipIf(not dns.dnssec._have_pycrypto,
154 "PyCrypto cannot be imported")
155 def testRelativeRSAGood(self):
156 dns.dnssec.validate(rel_soa, rel_soa_rrsig, rel_keys,
157 abs_dnspython_org, when)
158
159 @unittest.skipIf(not dns.dnssec._have_pycrypto,
160 "PyCrypto cannot be imported")
161 def testRelativeRSABad(self):
162 def bad():
163 dns.dnssec.validate(rel_other_soa, rel_soa_rrsig, rel_keys,
164 abs_dnspython_org, when)
165 self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
166
167 def testMakeSHA256DS(self):
168 ds = dns.dnssec.make_ds(abs_dnspython_org, sep_key, 'SHA256')
169 self.failUnless(ds == good_ds)
170
171 @unittest.skipIf(not dns.dnssec._have_pycrypto,
172 "PyCrypto cannot be imported")
173 def testAbsoluteDSAGood(self):
174 dns.dnssec.validate(abs_dsa_soa, abs_dsa_soa_rrsig, abs_dsa_keys, None,
175 when2)
176
177 @unittest.skipIf(not dns.dnssec._have_pycrypto,
178 "PyCrypto cannot be imported")
179 def testAbsoluteDSABad(self):
180 def bad():
181 dns.dnssec.validate(abs_other_dsa_soa, abs_dsa_soa_rrsig,
182 abs_dsa_keys, None, when2)
183 self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
184
185 def testMakeExampleSHA1DS(self):
186 ds = dns.dnssec.make_ds(abs_example, example_sep_key, 'SHA1')
187 self.failUnless(ds == example_ds_sha1)
188
189 def testMakeExampleSHA256DS(self):
190 ds = dns.dnssec.make_ds(abs_example, example_sep_key, 'SHA256')
191 self.failUnless(ds == example_ds_sha256)
192
193 @unittest.skipIf(not dns.dnssec._have_ecdsa,
194 "python ECDSA cannot be imported")
195 def testAbsoluteECDSA256Good(self):
196 dns.dnssec.validate(abs_ecdsa256_soa, abs_ecdsa256_soa_rrsig,
197 abs_ecdsa256_keys, None, when3)
198
199 @unittest.skipIf(not dns.dnssec._have_ecdsa,
200 "python ECDSA cannot be imported")
201 def testAbsoluteECDSA256Bad(self):
202 def bad():
203 dns.dnssec.validate(abs_other_ecdsa256_soa, abs_ecdsa256_soa_rrsig,
204 abs_ecdsa256_keys, None, when3)
205 self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
206
207 @unittest.skipIf(not dns.dnssec._have_ecdsa,
208 "python ECDSA can not be imported")
209 def testAbsoluteECDSA384Good(self):
210 dns.dnssec.validate(abs_ecdsa384_soa, abs_ecdsa384_soa_rrsig,
211 abs_ecdsa384_keys, None, when4)
212
213 @unittest.skipIf(not dns.dnssec._have_ecdsa,
214 "python ECDSA can not be imported")
215 def testAbsoluteECDSA384Bad(self):
216 def bad():
217 dns.dnssec.validate(abs_other_ecdsa384_soa, abs_ecdsa384_soa_rrsig,
218 abs_ecdsa384_keys, None, when4)
219 self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
220
221
222 if __name__ == '__main__':
223 import_ok = False
224 try:
225 import Crypto.Util.number
226 import_ok = True
227 except:
228 pass
229 if import_ok:
230 unittest.main()
231 else:
232 print 'skipping DNSSEC tests because pycrypto is not installed'
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.flags
18 import dns.rcode
19 import dns.opcode
20
21 class FlagsTestCase(unittest.TestCase):
22
23 def test_rcode1(self):
24 self.failUnless(dns.rcode.from_text('FORMERR') == dns.rcode.FORMERR)
25
26 def test_rcode2(self):
27 self.failUnless(dns.rcode.to_text(dns.rcode.FORMERR) == "FORMERR")
28
29 def test_rcode3(self):
30 self.failUnless(dns.rcode.to_flags(dns.rcode.FORMERR) == (1, 0))
31
32 def test_rcode4(self):
33 self.failUnless(dns.rcode.to_flags(dns.rcode.BADVERS) == \
34 (0, 0x01000000))
35
36 def test_rcode6(self):
37 self.failUnless(dns.rcode.from_flags(0, 0x01000000) == \
38 dns.rcode.BADVERS)
39
40 def test_rcode6(self):
41 self.failUnless(dns.rcode.from_flags(5, 0) == dns.rcode.REFUSED)
42
43 def test_rcode7(self):
44 def bad():
45 dns.rcode.to_flags(4096)
46 self.failUnlessRaises(ValueError, bad)
47
48 def test_flags1(self):
49 self.failUnless(dns.flags.from_text("RA RD AA QR") == \
50 dns.flags.QR|dns.flags.AA|dns.flags.RD|dns.flags.RA)
51
52 def test_flags2(self):
53 flags = dns.flags.QR|dns.flags.AA|dns.flags.RD|dns.flags.RA
54 self.failUnless(dns.flags.to_text(flags) == "QR AA RD RA")
55
56
57 if __name__ == '__main__':
58 unittest.main()
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import sys
16 sys.path.insert(0, '../') # Force the local project to be *the* dns
17
18 import cStringIO
19 import filecmp
20 import os
21 import unittest
22
23 import dns.exception
24 import dns.rdata
25 import dns.rdataclass
26 import dns.rdatatype
27 import dns.rrset
28 import dns.zone
29
30 import pprint
31
32 pp = pprint.PrettyPrinter(indent=2)
33
34 import pdb
35 example_text = """$TTL 1h
36 $ORIGIN 0.0.192.IN-ADDR.ARPA.
37 $GENERATE 1-2 0 CNAME SERVER$.EXAMPLE.
38 """
39
40 example_text1 = """$TTL 1h
41 $ORIGIN 0.0.192.IN-ADDR.ARPA.
42 $GENERATE 1-10 fooo$ CNAME $.0
43 """
44
45 example_text2 = """$TTL 1h
46 @ 3600 IN SOA foo bar 1 2 3 4 5
47 @ 3600 IN NS ns1
48 @ 3600 IN NS ns2
49 bar.foo 300 IN MX 0 blaz.foo
50 ns1 3600 IN A 10.0.0.1
51 ns2 3600 IN A 10.0.0.2
52 $GENERATE 3-5 foo$ A 10.0.0.$
53 """
54
55 example_text3 = """$TTL 1h
56 @ 3600 IN SOA foo bar 1 2 3 4 5
57 @ 3600 IN NS ns1
58 @ 3600 IN NS ns2
59 bar.foo 300 IN MX 0 blaz.foo
60 ns1 3600 IN A 10.0.0.1
61 ns2 3600 IN A 10.0.0.2
62 $GENERATE 4-8/2 foo$ A 10.0.0.$
63 """
64
65 example_text4 = """$TTL 1h
66 @ 3600 IN SOA foo bar 1 2 3 4 5
67 @ 3600 IN NS ns1
68 @ 3600 IN NS ns2
69 bar.foo 300 IN MX 0 blaz.foo
70 ns1 3600 IN A 10.0.0.1
71 ns2 3600 IN A 10.0.0.2
72 $GENERATE 11-13 wp-db${-10,2,d}.services.mozilla.com 0 CNAME SERVER.FOOBAR.
73 """
74
75 example_text5 = """$TTL 1h
76 @ 3600 IN SOA foo bar 1 2 3 4 5
77 @ 3600 IN NS ns1
78 @ 3600 IN NS ns2
79 bar.foo 300 IN MX 0 blaz.foo
80 ns1 3600 IN A 10.0.0.1
81 ns2 3600 IN A 10.0.0.2
82 $GENERATE 11-13 wp-db${10,2,d}.services.mozilla.com 0 CNAME SERVER.FOOBAR.
83 """
84
85 example_text6 = """$TTL 1h
86 @ 3600 IN SOA foo bar 1 2 3 4 5
87 @ 3600 IN NS ns1
88 @ 3600 IN NS ns2
89 bar.foo 300 IN MX 0 blaz.foo
90 ns1 3600 IN A 10.0.0.1
91 ns2 3600 IN A 10.0.0.2
92 $GENERATE 11-13 wp-db${+10,2,d}.services.mozilla.com 0 CNAME SERVER.FOOBAR.
93 """
94
95 example_text7 = """$TTL 1h
96 @ 3600 IN SOA foo bar 1 2 3 4 5
97 @ 3600 IN NS ns1
98 @ 3600 IN NS ns2
99 bar.foo 300 IN MX 0 blaz.foo
100 ns1 3600 IN A 10.0.0.1
101 ns2 3600 IN A 10.0.0.2
102 $GENERATE 11-13 sync${-10}.db IN A 10.10.16.0
103 """
104
105 example_text8 = """$TTL 1h
106 @ 3600 IN SOA foo bar 1 2 3 4 5
107 @ 3600 IN NS ns1
108 @ 3600 IN NS ns2
109 bar.foo 300 IN MX 0 blaz.foo
110 ns1 3600 IN A 10.0.0.1
111 ns2 3600 IN A 10.0.0.2
112 $GENERATE 11-12 wp-db${-10,2,d} IN A 10.10.16.0
113 """
114
115 example_text9 = """$TTL 1h
116 @ 3600 IN SOA foo bar 1 2 3 4 5
117 @ 3600 IN NS ns1
118 @ 3600 IN NS ns2
119 bar.foo 300 IN MX 0 blaz.foo
120 ns1 3600 IN A 10.0.0.1
121 ns2 3600 IN A 10.0.0.2
122 $GENERATE 11-12 wp-db${-10,2,d} IN A 10.10.16.0
123 $GENERATE 11-13 sync${-10}.db IN A 10.10.16.0
124 """
125 example_text10 = """$TTL 1h
126 @ 3600 IN SOA foo bar 1 2 3 4 5
127 @ 3600 IN NS ns1
128 @ 3600 IN NS ns2
129 bar.foo 300 IN MX 0 blaz.foo
130 ns1 3600 IN A 10.0.0.1
131 ns2 3600 IN A 10.0.0.2
132 $GENERATE 27-28 $.2 PTR zlb${-26}.oob
133 """
134
135
136 class GenerateTestCase(unittest.TestCase):
137
138 def testFromText(self):
139 def bad():
140 z = dns.zone.from_text(example_text, 'example.', relativize=True)
141 self.failUnlessRaises(dns.zone.NoSOA, bad)
142
143 def testFromText1(self):
144 def bad():
145 z = dns.zone.from_text(example_text1, 'example.', relativize=True)
146 self.failUnlessRaises(dns.zone.NoSOA, bad)
147
148 def testIterateAllRdatas2(self):
149 z = dns.zone.from_text(example_text2, 'example.', relativize=True)
150 l = list(z.iterate_rdatas())
151 l.sort()
152 exl = [(dns.name.from_text('@', None),
153 3600,
154 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
155 'ns1')),
156 (dns.name.from_text('@', None),
157 3600,
158 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
159 'ns2')),
160 (dns.name.from_text('@', None),
161 3600,
162 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
163 'foo bar 1 2 3 4 5')),
164 (dns.name.from_text('bar.foo', None),
165 300,
166 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
167 '0 blaz.foo')),
168 (dns.name.from_text('ns1', None),
169 3600,
170 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
171 '10.0.0.1')),
172 (dns.name.from_text('ns2', None),
173 3600,
174 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
175 '10.0.0.2')),
176 (dns.name.from_text('foo3', None),
177 3600,
178 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
179 '10.0.0.3')),
180 (dns.name.from_text('foo4', None),
181 3600,
182 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
183 '10.0.0.4')),
184 (dns.name.from_text('foo5', None),
185 3600,
186 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
187 '10.0.0.5'))]
188
189 exl.sort()
190 self.failUnless(l == exl)
191
192 def testIterateAllRdatas3(self):
193 z = dns.zone.from_text(example_text3, 'example.', relativize=True)
194 l = list(z.iterate_rdatas())
195 l.sort()
196 exl = [(dns.name.from_text('@', None),
197 3600,
198 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
199 'ns1')),
200 (dns.name.from_text('@', None),
201 3600,
202 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
203 'ns2')),
204 (dns.name.from_text('@', None),
205 3600,
206 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
207 'foo bar 1 2 3 4 5')),
208 (dns.name.from_text('bar.foo', None),
209 300,
210 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
211 '0 blaz.foo')),
212 (dns.name.from_text('ns1', None),
213 3600,
214 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
215 '10.0.0.1')),
216 (dns.name.from_text('ns2', None),
217 3600,
218 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
219 '10.0.0.2')),
220 (dns.name.from_text('foo4', None), 3600,
221 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
222 '10.0.0.4')),
223 (dns.name.from_text('foo6', None), 3600,
224 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
225 '10.0.0.6')),
226 (dns.name.from_text('foo8', None), 3600,
227 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
228 '10.0.0.8'))]
229 exl.sort()
230 self.failUnless(l == exl)
231 def testGenerate1(self):
232 z = dns.zone.from_text(example_text4, 'example.', relativize=True)
233 l = list(z.iterate_rdatas())
234 l.sort()
235 exl = [(dns.name.from_text('@', None),
236 3600L,
237 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
238 'ns1')),
239 (dns.name.from_text('@', None),
240 3600L,
241 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
242 'ns2')),
243 (dns.name.from_text('@', None),
244 3600L,
245 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
246 'foo bar 1 2 3 4 5')),
247 (dns.name.from_text('bar.foo', None),
248 300L,
249 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
250 '0 blaz.foo')),
251 (dns.name.from_text('ns1', None),
252 3600L,
253 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
254 '10.0.0.1')),
255 (dns.name.from_text('ns2', None),
256 3600L,
257 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
258 '10.0.0.2')),
259
260 (dns.name.from_text('wp-db01.services.mozilla.com', None),
261 0L,
262 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
263 'SERVER.FOOBAR.')),
264
265 (dns.name.from_text('wp-db02.services.mozilla.com', None),
266 0L,
267 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
268 'SERVER.FOOBAR.')),
269
270 (dns.name.from_text('wp-db03.services.mozilla.com', None),
271 0L,
272 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
273 'SERVER.FOOBAR.'))]
274 exl.sort()
275 self.failUnless(l == exl)
276
277 def testGenerate2(self):
278 z = dns.zone.from_text(example_text5, 'example.', relativize=True)
279 l = list(z.iterate_rdatas())
280 l.sort()
281 exl = [(dns.name.from_text('@', None),
282 3600L,
283 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
284 'ns1')),
285 (dns.name.from_text('@', None),
286 3600L,
287 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
288 'ns2')),
289 (dns.name.from_text('@', None),
290 3600L,
291 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
292 'foo bar 1 2 3 4 5')),
293 (dns.name.from_text('bar.foo', None),
294 300L,
295 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
296 '0 blaz.foo')),
297 (dns.name.from_text('ns1', None),
298 3600L,
299 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
300 '10.0.0.1')),
301 (dns.name.from_text('ns2', None),
302 3600L,
303 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
304 '10.0.0.2')),
305
306 (dns.name.from_text('wp-db21.services.mozilla.com', None), 0L,
307 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
308 'SERVER.FOOBAR.')),
309
310 (dns.name.from_text('wp-db22.services.mozilla.com', None), 0L,
311 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
312 'SERVER.FOOBAR.')),
313
314 (dns.name.from_text('wp-db23.services.mozilla.com', None), 0L,
315 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
316 'SERVER.FOOBAR.'))]
317 exl.sort()
318 self.failUnless(l == exl)
319
320 def testGenerate3(self):
321 z = dns.zone.from_text(example_text6, 'example.', relativize=True)
322 l = list(z.iterate_rdatas())
323 l.sort()
324
325 exl = [(dns.name.from_text('@', None),
326 3600L,
327 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
328 'ns1')),
329 (dns.name.from_text('@', None),
330 3600L,
331 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
332 'ns2')),
333 (dns.name.from_text('@', None),
334 3600L,
335 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
336 'foo bar 1 2 3 4 5')),
337 (dns.name.from_text('bar.foo', None),
338 300L,
339 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
340 '0 blaz.foo')),
341 (dns.name.from_text('ns1', None),
342 3600L,
343 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
344 '10.0.0.1')),
345 (dns.name.from_text('ns2', None),
346 3600L,
347 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
348 '10.0.0.2')),
349 (dns.name.from_text('wp-db21.services.mozilla.com', None), 0L,
350 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
351 'SERVER.FOOBAR.')),
352
353 (dns.name.from_text('wp-db22.services.mozilla.com', None), 0L,
354 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
355 'SERVER.FOOBAR.')),
356
357 (dns.name.from_text('wp-db23.services.mozilla.com', None), 0L,
358 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
359 'SERVER.FOOBAR.'))]
360 exl.sort()
361 self.failUnless(l == exl)
362
363 def testGenerate4(self):
364 z = dns.zone.from_text(example_text7, 'example.', relativize=True)
365 l = list(z.iterate_rdatas())
366 l.sort()
367 exl = [(dns.name.from_text('@', None),
368 3600L,
369 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
370 'ns1')),
371 (dns.name.from_text('@', None),
372 3600L,
373 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
374 'ns2')),
375 (dns.name.from_text('@', None),
376 3600L,
377 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
378 'foo bar 1 2 3 4 5')),
379 (dns.name.from_text('bar.foo', None),
380 300L,
381 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
382 '0 blaz.foo')),
383 (dns.name.from_text('ns1', None),
384 3600L,
385 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
386 '10.0.0.1')),
387 (dns.name.from_text('ns2', None),
388 3600L,
389 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
390 '10.0.0.2')),
391
392 (dns.name.from_text('sync1.db', None), 3600L,
393 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
394 '10.10.16.0')),
395
396 (dns.name.from_text('sync2.db', None), 3600L,
397 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
398 '10.10.16.0')),
399
400 (dns.name.from_text('sync3.db', None), 3600L,
401 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
402 '10.10.16.0'))]
403 exl.sort()
404 self.failUnless(l == exl)
405
406 def testGenerate6(self):
407 z = dns.zone.from_text(example_text9, 'example.', relativize=True)
408 l = list(z.iterate_rdatas())
409 l.sort()
410 exl = [(dns.name.from_text('@', None),
411 3600L,
412 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
413 'ns1')),
414 (dns.name.from_text('@', None),
415 3600L,
416 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
417 'ns2')),
418 (dns.name.from_text('@', None),
419 3600L,
420 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
421 'foo bar 1 2 3 4 5')),
422 (dns.name.from_text('bar.foo', None),
423 300L,
424 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
425 '0 blaz.foo')),
426 (dns.name.from_text('ns1', None),
427 3600L,
428 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
429 '10.0.0.1')),
430 (dns.name.from_text('ns2', None),
431 3600L,
432 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
433 '10.0.0.2')),
434
435 (dns.name.from_text('wp-db01', None), 3600L,
436 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
437 '10.10.16.0')),
438 (dns.name.from_text('wp-db02', None), 3600L,
439 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
440 '10.10.16.0')),
441
442 (dns.name.from_text('sync1.db', None), 3600L,
443 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
444 '10.10.16.0')),
445
446 (dns.name.from_text('sync2.db', None), 3600L,
447 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
448 '10.10.16.0')),
449
450 (dns.name.from_text('sync3.db', None), 3600L,
451 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
452 '10.10.16.0'))]
453 exl.sort()
454 self.failUnless(l == exl)
455
456 def testGenerate7(self):
457 z = dns.zone.from_text(example_text10, 'example.', relativize=True)
458 l = list(z.iterate_rdatas())
459 l.sort()
460 exl = [(dns.name.from_text('@', None),
461 3600L,
462 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
463 'ns1')),
464 (dns.name.from_text('@', None),
465 3600L,
466 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
467 'ns2')),
468 (dns.name.from_text('@', None),
469 3600L,
470 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
471 'foo bar 1 2 3 4 5')),
472 (dns.name.from_text('bar.foo', None),
473 300L,
474 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
475 '0 blaz.foo')),
476 (dns.name.from_text('ns1', None),
477 3600L,
478 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
479 '10.0.0.1')),
480 (dns.name.from_text('ns2', None),
481 3600L,
482 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
483 '10.0.0.2')),
484
485 (dns.name.from_text('27.2', None), 3600L,
486 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.PTR,
487 'zlb1.oob')),
488
489 (dns.name.from_text('28.2', None), 3600L,
490 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.PTR,
491 'zlb2.oob'))]
492
493 exl.sort()
494 self.failUnless(l == exl)
495
496
497 if __name__ == '__main__':
498 unittest.main()
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import sys
16 sys.path.insert(0, '../')
17
18 import cStringIO
19 import filecmp
20 import os
21 import unittest
22
23 import dns
24 import dns.exception
25 import dns.grange
26
27 import pdb
28
29
30
31 class GRangeTestCase(unittest.TestCase):
32
33 def testFromText1(self):
34 start, stop, step = dns.grange.from_text('1-1')
35 self.assertEqual(start, 1)
36 self.assertEqual(stop, 1)
37 self.assertEqual(step, 1)
38
39 def testFromText2(self):
40 start, stop, step = dns.grange.from_text('1-4')
41 self.assertEqual(start, 1)
42 self.assertEqual(stop, 4)
43 self.assertEqual(step, 1)
44
45 def testFromText3(self):
46 start, stop, step = dns.grange.from_text('4-255')
47 self.assertEqual(start, 4)
48 self.assertEqual(stop, 255)
49 self.assertEqual(step, 1)
50
51 def testFromText4(self):
52 start, stop, step = dns.grange.from_text('1-1/1')
53 self.assertEqual(start, 1)
54 self.assertEqual(stop, 1)
55 self.assertEqual(step, 1)
56
57 def testFromText5(self):
58 start, stop, step = dns.grange.from_text('1-4/2')
59 self.assertEqual(start, 1)
60 self.assertEqual(stop, 4)
61 self.assertEqual(step, 2)
62
63 def testFromText6(self):
64 start, stop, step = dns.grange.from_text('4-255/77')
65 self.assertEqual(start, 4)
66 self.assertEqual(stop, 255)
67 self.assertEqual(step, 77)
68
69 def testFailFromText1(self):
70 def bad():
71 start = 2
72 stop = 1
73 step = 1
74 dns.grange.from_text('%d-%d/%d' % (start, stop, step))
75 self.assertRaises(AssertionError, bad)
76
77 def testFailFromText2(self):
78 def bad():
79 start = '-1'
80 stop = 3
81 step = 1
82 dns.grange.from_text('%s-%d/%d' % (start, stop, step))
83 self.assertRaises(dns.exception.SyntaxError, bad)
84
85 def testFailFromText2(self):
86 def bad():
87 start = 1
88 stop = 4
89 step = '-2'
90 dns.grange.from_text('%d-%d/%s' % (start, stop, step))
91 self.assertRaises(dns.exception.SyntaxError, bad)
92
93 if __name__ == '__main__':
94 unittest.main()
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import cStringIO
16 import os
17 import unittest
18
19 import dns.exception
20 import dns.message
21
22 query_text = """id 1234
23 opcode QUERY
24 rcode NOERROR
25 flags RD
26 edns 0
27 eflags DO
28 payload 4096
29 ;QUESTION
30 wwww.dnspython.org. IN A
31 ;ANSWER
32 ;AUTHORITY
33 ;ADDITIONAL"""
34
35 goodhex = '04d201000001000000000001047777777709646e73707974686f6e' \
36 '036f726700000100010000291000000080000000'
37
38 goodwire = goodhex.decode('hex_codec')
39
40 answer_text = """id 1234
41 opcode QUERY
42 rcode NOERROR
43 flags QR AA RD
44 ;QUESTION
45 dnspython.org. IN SOA
46 ;ANSWER
47 dnspython.org. 3600 IN SOA woof.dnspython.org. hostmaster.dnspython.org. 2003052700 3600 1800 604800 3600
48 ;AUTHORITY
49 dnspython.org. 3600 IN NS ns1.staff.nominum.org.
50 dnspython.org. 3600 IN NS ns2.staff.nominum.org.
51 dnspython.org. 3600 IN NS woof.play-bow.org.
52 ;ADDITIONAL
53 woof.play-bow.org. 3600 IN A 204.152.186.150
54 """
55
56 goodhex2 = '04d2 8500 0001 0001 0003 0001' \
57 '09646e73707974686f6e036f726700 0006 0001' \
58 'c00c 0006 0001 00000e10 0028 ' \
59 '04776f6f66c00c 0a686f73746d6173746572c00c' \
60 '7764289c 00000e10 00000708 00093a80 00000e10' \
61 'c00c 0002 0001 00000e10 0014' \
62 '036e7331057374616666076e6f6d696e756dc016' \
63 'c00c 0002 0001 00000e10 0006 036e7332c063' \
64 'c00c 0002 0001 00000e10 0010 04776f6f6608706c61792d626f77c016' \
65 'c091 0001 0001 00000e10 0004 cc98ba96'
66
67
68 goodwire2 = goodhex2.replace(' ', '').decode('hex_codec')
69
70 query_text_2 = """id 1234
71 opcode QUERY
72 rcode 4095
73 flags RD
74 edns 0
75 eflags DO
76 payload 4096
77 ;QUESTION
78 wwww.dnspython.org. IN A
79 ;ANSWER
80 ;AUTHORITY
81 ;ADDITIONAL"""
82
83 goodhex3 = '04d2010f0001000000000001047777777709646e73707974686f6e' \
84 '036f726700000100010000291000ff0080000000'
85
86 goodwire3 = goodhex3.decode('hex_codec')
87
88 class MessageTestCase(unittest.TestCase):
89
90 def test_comparison_eq1(self):
91 q1 = dns.message.from_text(query_text)
92 q2 = dns.message.from_text(query_text)
93 self.failUnless(q1 == q2)
94
95 def test_comparison_ne1(self):
96 q1 = dns.message.from_text(query_text)
97 q2 = dns.message.from_text(query_text)
98 q2.id = 10
99 self.failUnless(q1 != q2)
100
101 def test_comparison_ne2(self):
102 q1 = dns.message.from_text(query_text)
103 q2 = dns.message.from_text(query_text)
104 q2.question = []
105 self.failUnless(q1 != q2)
106
107 def test_comparison_ne3(self):
108 q1 = dns.message.from_text(query_text)
109 self.failUnless(q1 != 1)
110
111 def test_EDNS_to_wire1(self):
112 q = dns.message.from_text(query_text)
113 w = q.to_wire()
114 self.failUnless(w == goodwire)
115
116 def test_EDNS_from_wire1(self):
117 m = dns.message.from_wire(goodwire)
118 self.failUnless(str(m) == query_text)
119
120 def test_EDNS_to_wire2(self):
121 q = dns.message.from_text(query_text_2)
122 w = q.to_wire()
123 self.failUnless(w == goodwire3)
124
125 def test_EDNS_from_wire2(self):
126 m = dns.message.from_wire(goodwire3)
127 self.failUnless(str(m) == query_text_2)
128
129 def test_TooBig(self):
130 def bad():
131 q = dns.message.from_text(query_text)
132 for i in xrange(0, 25):
133 rrset = dns.rrset.from_text('foo%d.' % i, 3600,
134 dns.rdataclass.IN,
135 dns.rdatatype.A,
136 '10.0.0.%d' % i)
137 q.additional.append(rrset)
138 w = q.to_wire(max_size=512)
139 self.failUnlessRaises(dns.exception.TooBig, bad)
140
141 def test_answer1(self):
142 a = dns.message.from_text(answer_text)
143 wire = a.to_wire(want_shuffle=False)
144 self.failUnless(wire == goodwire2)
145
146 def test_TrailingJunk(self):
147 def bad():
148 badwire = goodwire + '\x00'
149 m = dns.message.from_wire(badwire)
150 self.failUnlessRaises(dns.message.TrailingJunk, bad)
151
152 def test_ShortHeader(self):
153 def bad():
154 badwire = '\x00' * 11
155 m = dns.message.from_wire(badwire)
156 self.failUnlessRaises(dns.message.ShortHeader, bad)
157
158 def test_RespondingToResponse(self):
159 def bad():
160 q = dns.message.make_query('foo', 'A')
161 r1 = dns.message.make_response(q)
162 r2 = dns.message.make_response(r1)
163 self.failUnlessRaises(dns.exception.FormError, bad)
164
165 def test_ExtendedRcodeSetting(self):
166 m = dns.message.make_query('foo', 'A')
167 m.set_rcode(4095)
168 self.failUnless(m.rcode() == 4095)
169 m.set_rcode(2)
170 self.failUnless(m.rcode() == 2)
171
172 def test_EDNSVersionCoherence(self):
173 m = dns.message.make_query('foo', 'A')
174 m.use_edns(1)
175 self.failUnless((m.ednsflags >> 16) & 0xFF == 1)
176
177 if __name__ == '__main__':
178 unittest.main()
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import cStringIO
18 import socket
19
20 import dns.name
21 import dns.reversename
22 import dns.e164
23
24 class NameTestCase(unittest.TestCase):
25 def setUp(self):
26 self.origin = dns.name.from_text('example.')
27
28 def testFromTextRel1(self):
29 n = dns.name.from_text('foo.bar')
30 self.failUnless(n.labels == ('foo', 'bar', ''))
31
32 def testFromTextRel2(self):
33 n = dns.name.from_text('foo.bar', origin=self.origin)
34 self.failUnless(n.labels == ('foo', 'bar', 'example', ''))
35
36 def testFromTextRel3(self):
37 n = dns.name.from_text('foo.bar', origin=None)
38 self.failUnless(n.labels == ('foo', 'bar'))
39
40 def testFromTextRel4(self):
41 n = dns.name.from_text('@', origin=None)
42 self.failUnless(n == dns.name.empty)
43
44 def testFromTextRel5(self):
45 n = dns.name.from_text('@', origin=self.origin)
46 self.failUnless(n == self.origin)
47
48 def testFromTextAbs1(self):
49 n = dns.name.from_text('foo.bar.')
50 self.failUnless(n.labels == ('foo', 'bar', ''))
51
52 def testTortureFromText(self):
53 good = [
54 r'.',
55 r'a',
56 r'a.',
57 r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
58 r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
59 r'\000.\008.\010.\032.\046.\092.\099.\255',
60 r'\\',
61 r'\..\.',
62 r'\\.\\',
63 r'!"#%&/()=+-',
64 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',
65 ]
66 bad = [
67 r'..',
68 r'.a',
69 r'\\..',
70 '\\', # yes, we don't want the 'r' prefix!
71 r'\0',
72 r'\00',
73 r'\00Z',
74 r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
75 r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
76 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',
77 ]
78 for t in good:
79 try:
80 n = dns.name.from_text(t)
81 except:
82 self.fail("good test '%s' raised an exception" % t)
83 for t in bad:
84 caught = False
85 try:
86 n = dns.name.from_text(t)
87 except:
88 caught = True
89 if not caught:
90 self.fail("bad test '%s' did not raise an exception" % t)
91
92 def testImmutable1(self):
93 def bad():
94 self.origin.labels = ()
95 self.failUnlessRaises(TypeError, bad)
96
97 def testImmutable2(self):
98 def bad():
99 self.origin.labels[0] = 'foo'
100 self.failUnlessRaises(TypeError, bad)
101
102 def testAbs1(self):
103 self.failUnless(dns.name.root.is_absolute())
104
105 def testAbs2(self):
106 self.failUnless(not dns.name.empty.is_absolute())
107
108 def testAbs3(self):
109 self.failUnless(self.origin.is_absolute())
110
111 def testAbs3(self):
112 n = dns.name.from_text('foo', origin=None)
113 self.failUnless(not n.is_absolute())
114
115 def testWild1(self):
116 n = dns.name.from_text('*.foo', origin=None)
117 self.failUnless(n.is_wild())
118
119 def testWild2(self):
120 n = dns.name.from_text('*a.foo', origin=None)
121 self.failUnless(not n.is_wild())
122
123 def testWild3(self):
124 n = dns.name.from_text('a.*.foo', origin=None)
125 self.failUnless(not n.is_wild())
126
127 def testWild4(self):
128 self.failUnless(not dns.name.root.is_wild())
129
130 def testWild5(self):
131 self.failUnless(not dns.name.empty.is_wild())
132
133 def testHash1(self):
134 n1 = dns.name.from_text('fOo.COM')
135 n2 = dns.name.from_text('foo.com')
136 self.failUnless(hash(n1) == hash(n2))
137
138 def testCompare1(self):
139 n1 = dns.name.from_text('a')
140 n2 = dns.name.from_text('b')
141 self.failUnless(n1 < n2)
142 self.failUnless(n2 > n1)
143
144 def testCompare2(self):
145 n1 = dns.name.from_text('')
146 n2 = dns.name.from_text('b')
147 self.failUnless(n1 < n2)
148 self.failUnless(n2 > n1)
149
150 def testCompare3(self):
151 self.failUnless(dns.name.empty < dns.name.root)
152 self.failUnless(dns.name.root > dns.name.empty)
153
154 def testCompare4(self):
155 self.failUnless(dns.name.root != 1)
156
157 def testCompare5(self):
158 self.failUnless(dns.name.root < 1 or dns.name.root > 1)
159
160 def testSubdomain1(self):
161 self.failUnless(not dns.name.empty.is_subdomain(dns.name.root))
162
163 def testSubdomain2(self):
164 self.failUnless(not dns.name.root.is_subdomain(dns.name.empty))
165
166 def testSubdomain3(self):
167 n = dns.name.from_text('foo', origin=self.origin)
168 self.failUnless(n.is_subdomain(self.origin))
169
170 def testSubdomain4(self):
171 n = dns.name.from_text('foo', origin=self.origin)
172 self.failUnless(n.is_subdomain(dns.name.root))
173
174 def testSubdomain5(self):
175 n = dns.name.from_text('foo', origin=self.origin)
176 self.failUnless(n.is_subdomain(n))
177
178 def testSuperdomain1(self):
179 self.failUnless(not dns.name.empty.is_superdomain(dns.name.root))
180
181 def testSuperdomain2(self):
182 self.failUnless(not dns.name.root.is_superdomain(dns.name.empty))
183
184 def testSuperdomain3(self):
185 n = dns.name.from_text('foo', origin=self.origin)
186 self.failUnless(self.origin.is_superdomain(n))
187
188 def testSuperdomain4(self):
189 n = dns.name.from_text('foo', origin=self.origin)
190 self.failUnless(dns.name.root.is_superdomain(n))
191
192 def testSuperdomain5(self):
193 n = dns.name.from_text('foo', origin=self.origin)
194 self.failUnless(n.is_superdomain(n))
195
196 def testCanonicalize1(self):
197 n = dns.name.from_text('FOO.bar', origin=self.origin)
198 c = n.canonicalize()
199 self.failUnless(c.labels == ('foo', 'bar', 'example', ''))
200
201 def testToText1(self):
202 n = dns.name.from_text('FOO.bar', origin=self.origin)
203 t = n.to_text()
204 self.failUnless(t == 'FOO.bar.example.')
205
206 def testToText2(self):
207 n = dns.name.from_text('FOO.bar', origin=self.origin)
208 t = n.to_text(True)
209 self.failUnless(t == 'FOO.bar.example')
210
211 def testToText3(self):
212 n = dns.name.from_text('FOO.bar', origin=None)
213 t = n.to_text()
214 self.failUnless(t == 'FOO.bar')
215
216 def testToText4(self):
217 t = dns.name.empty.to_text()
218 self.failUnless(t == '@')
219
220 def testToText5(self):
221 t = dns.name.root.to_text()
222 self.failUnless(t == '.')
223
224 def testToText6(self):
225 n = dns.name.from_text('FOO bar', origin=None)
226 t = n.to_text()
227 self.failUnless(t == r'FOO\032bar')
228
229 def testToText7(self):
230 n = dns.name.from_text(r'FOO\.bar', origin=None)
231 t = n.to_text()
232 self.failUnless(t == r'FOO\.bar')
233
234 def testToText8(self):
235 n = dns.name.from_text(r'\070OO\.bar', origin=None)
236 t = n.to_text()
237 self.failUnless(t == r'FOO\.bar')
238
239 def testSlice1(self):
240 n = dns.name.from_text(r'a.b.c.', origin=None)
241 s = n[:]
242 self.failUnless(s == ('a', 'b', 'c', ''))
243
244 def testSlice2(self):
245 n = dns.name.from_text(r'a.b.c.', origin=None)
246 s = n[:2]
247 self.failUnless(s == ('a', 'b'))
248
249 def testSlice3(self):
250 n = dns.name.from_text(r'a.b.c.', origin=None)
251 s = n[2:]
252 self.failUnless(s == ('c', ''))
253
254 def testEmptyLabel1(self):
255 def bad():
256 n = dns.name.Name(['a', '', 'b'])
257 self.failUnlessRaises(dns.name.EmptyLabel, bad)
258
259 def testEmptyLabel2(self):
260 def bad():
261 n = dns.name.Name(['', 'b'])
262 self.failUnlessRaises(dns.name.EmptyLabel, bad)
263
264 def testEmptyLabel3(self):
265 n = dns.name.Name(['b', ''])
266 self.failUnless(n)
267
268 def testLongLabel(self):
269 n = dns.name.Name(['a' * 63])
270 self.failUnless(n)
271
272 def testLabelTooLong(self):
273 def bad():
274 n = dns.name.Name(['a' * 64, 'b'])
275 self.failUnlessRaises(dns.name.LabelTooLong, bad)
276
277 def testLongName(self):
278 n = dns.name.Name(['a' * 63, 'a' * 63, 'a' * 63, 'a' * 62])
279 self.failUnless(n)
280
281 def testNameTooLong(self):
282 def bad():
283 n = dns.name.Name(['a' * 63, 'a' * 63, 'a' * 63, 'a' * 63])
284 self.failUnlessRaises(dns.name.NameTooLong, bad)
285
286 def testConcat1(self):
287 n1 = dns.name.Name(['a', 'b'])
288 n2 = dns.name.Name(['c', 'd'])
289 e = dns.name.Name(['a', 'b', 'c', 'd'])
290 r = n1 + n2
291 self.failUnless(r == e)
292
293 def testConcat2(self):
294 n1 = dns.name.Name(['a', 'b'])
295 n2 = dns.name.Name([])
296 e = dns.name.Name(['a', 'b'])
297 r = n1 + n2
298 self.failUnless(r == e)
299
300 def testConcat2(self):
301 n1 = dns.name.Name([])
302 n2 = dns.name.Name(['a', 'b'])
303 e = dns.name.Name(['a', 'b'])
304 r = n1 + n2
305 self.failUnless(r == e)
306
307 def testConcat3(self):
308 n1 = dns.name.Name(['a', 'b', ''])
309 n2 = dns.name.Name([])
310 e = dns.name.Name(['a', 'b', ''])
311 r = n1 + n2
312 self.failUnless(r == e)
313
314 def testConcat4(self):
315 n1 = dns.name.Name(['a', 'b'])
316 n2 = dns.name.Name(['c', ''])
317 e = dns.name.Name(['a', 'b', 'c', ''])
318 r = n1 + n2
319 self.failUnless(r == e)
320
321 def testConcat5(self):
322 def bad():
323 n1 = dns.name.Name(['a', 'b', ''])
324 n2 = dns.name.Name(['c'])
325 r = n1 + n2
326 self.failUnlessRaises(dns.name.AbsoluteConcatenation, bad)
327
328 def testBadEscape(self):
329 def bad():
330 n = dns.name.from_text(r'a.b\0q1.c.')
331 print n
332 self.failUnlessRaises(dns.name.BadEscape, bad)
333
334 def testDigestable1(self):
335 n = dns.name.from_text('FOO.bar')
336 d = n.to_digestable()
337 self.failUnless(d == '\x03foo\x03bar\x00')
338
339 def testDigestable2(self):
340 n1 = dns.name.from_text('FOO.bar')
341 n2 = dns.name.from_text('foo.BAR.')
342 d1 = n1.to_digestable()
343 d2 = n2.to_digestable()
344 self.failUnless(d1 == d2)
345
346 def testDigestable3(self):
347 d = dns.name.root.to_digestable()
348 self.failUnless(d == '\x00')
349
350 def testDigestable4(self):
351 n = dns.name.from_text('FOO.bar', None)
352 d = n.to_digestable(dns.name.root)
353 self.failUnless(d == '\x03foo\x03bar\x00')
354
355 def testBadDigestable(self):
356 def bad():
357 n = dns.name.from_text('FOO.bar', None)
358 d = n.to_digestable()
359 self.failUnlessRaises(dns.name.NeedAbsoluteNameOrOrigin, bad)
360
361 def testToWire1(self):
362 n = dns.name.from_text('FOO.bar')
363 f = cStringIO.StringIO()
364 compress = {}
365 n.to_wire(f, compress)
366 self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00')
367
368 def testToWire2(self):
369 n = dns.name.from_text('FOO.bar')
370 f = cStringIO.StringIO()
371 compress = {}
372 n.to_wire(f, compress)
373 n.to_wire(f, compress)
374 self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\xc0\x00')
375
376 def testToWire3(self):
377 n1 = dns.name.from_text('FOO.bar')
378 n2 = dns.name.from_text('foo.bar')
379 f = cStringIO.StringIO()
380 compress = {}
381 n1.to_wire(f, compress)
382 n2.to_wire(f, compress)
383 self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\xc0\x00')
384
385 def testToWire4(self):
386 n1 = dns.name.from_text('FOO.bar')
387 n2 = dns.name.from_text('a.foo.bar')
388 f = cStringIO.StringIO()
389 compress = {}
390 n1.to_wire(f, compress)
391 n2.to_wire(f, compress)
392 self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\x01\x61\xc0\x00')
393
394 def testToWire5(self):
395 n1 = dns.name.from_text('FOO.bar')
396 n2 = dns.name.from_text('a.foo.bar')
397 f = cStringIO.StringIO()
398 compress = {}
399 n1.to_wire(f, compress)
400 n2.to_wire(f, None)
401 self.failUnless(f.getvalue() == \
402 '\x03FOO\x03bar\x00\x01\x61\x03foo\x03bar\x00')
403
404 def testToWire6(self):
405 n = dns.name.from_text('FOO.bar')
406 v = n.to_wire()
407 self.failUnless(v == '\x03FOO\x03bar\x00')
408
409 def testBadToWire(self):
410 def bad():
411 n = dns.name.from_text('FOO.bar', None)
412 f = cStringIO.StringIO()
413 compress = {}
414 n.to_wire(f, compress)
415 self.failUnlessRaises(dns.name.NeedAbsoluteNameOrOrigin, bad)
416
417 def testSplit1(self):
418 n = dns.name.from_text('foo.bar.')
419 (prefix, suffix) = n.split(2)
420 ep = dns.name.from_text('foo', None)
421 es = dns.name.from_text('bar.', None)
422 self.failUnless(prefix == ep and suffix == es)
423
424 def testSplit2(self):
425 n = dns.name.from_text('foo.bar.')
426 (prefix, suffix) = n.split(1)
427 ep = dns.name.from_text('foo.bar', None)
428 es = dns.name.from_text('.', None)
429 self.failUnless(prefix == ep and suffix == es)
430
431 def testSplit3(self):
432 n = dns.name.from_text('foo.bar.')
433 (prefix, suffix) = n.split(0)
434 ep = dns.name.from_text('foo.bar.', None)
435 es = dns.name.from_text('', None)
436 self.failUnless(prefix == ep and suffix == es)
437
438 def testSplit4(self):
439 n = dns.name.from_text('foo.bar.')
440 (prefix, suffix) = n.split(3)
441 ep = dns.name.from_text('', None)
442 es = dns.name.from_text('foo.bar.', None)
443 self.failUnless(prefix == ep and suffix == es)
444
445 def testBadSplit1(self):
446 def bad():
447 n = dns.name.from_text('foo.bar.')
448 (prefix, suffix) = n.split(-1)
449 self.failUnlessRaises(ValueError, bad)
450
451 def testBadSplit2(self):
452 def bad():
453 n = dns.name.from_text('foo.bar.')
454 (prefix, suffix) = n.split(4)
455 self.failUnlessRaises(ValueError, bad)
456
457 def testRelativize1(self):
458 n = dns.name.from_text('a.foo.bar.', None)
459 o = dns.name.from_text('bar.', None)
460 e = dns.name.from_text('a.foo', None)
461 self.failUnless(n.relativize(o) == e)
462
463 def testRelativize2(self):
464 n = dns.name.from_text('a.foo.bar.', None)
465 o = n
466 e = dns.name.empty
467 self.failUnless(n.relativize(o) == e)
468
469 def testRelativize3(self):
470 n = dns.name.from_text('a.foo.bar.', None)
471 o = dns.name.from_text('blaz.', None)
472 e = n
473 self.failUnless(n.relativize(o) == e)
474
475 def testRelativize4(self):
476 n = dns.name.from_text('a.foo', None)
477 o = dns.name.root
478 e = n
479 self.failUnless(n.relativize(o) == e)
480
481 def testDerelativize1(self):
482 n = dns.name.from_text('a.foo', None)
483 o = dns.name.from_text('bar.', None)
484 e = dns.name.from_text('a.foo.bar.', None)
485 self.failUnless(n.derelativize(o) == e)
486
487 def testDerelativize2(self):
488 n = dns.name.empty
489 o = dns.name.from_text('a.foo.bar.', None)
490 e = o
491 self.failUnless(n.derelativize(o) == e)
492
493 def testDerelativize3(self):
494 n = dns.name.from_text('a.foo.bar.', None)
495 o = dns.name.from_text('blaz.', None)
496 e = n
497 self.failUnless(n.derelativize(o) == e)
498
499 def testChooseRelativity1(self):
500 n = dns.name.from_text('a.foo.bar.', None)
501 o = dns.name.from_text('bar.', None)
502 e = dns.name.from_text('a.foo', None)
503 self.failUnless(n.choose_relativity(o, True) == e)
504
505 def testChooseRelativity2(self):
506 n = dns.name.from_text('a.foo.bar.', None)
507 o = dns.name.from_text('bar.', None)
508 e = n
509 self.failUnless(n.choose_relativity(o, False) == e)
510
511 def testChooseRelativity3(self):
512 n = dns.name.from_text('a.foo', None)
513 o = dns.name.from_text('bar.', None)
514 e = dns.name.from_text('a.foo.bar.', None)
515 self.failUnless(n.choose_relativity(o, False) == e)
516
517 def testChooseRelativity4(self):
518 n = dns.name.from_text('a.foo', None)
519 o = None
520 e = n
521 self.failUnless(n.choose_relativity(o, True) == e)
522
523 def testChooseRelativity5(self):
524 n = dns.name.from_text('a.foo', None)
525 o = None
526 e = n
527 self.failUnless(n.choose_relativity(o, False) == e)
528
529 def testChooseRelativity6(self):
530 n = dns.name.from_text('a.foo.', None)
531 o = None
532 e = n
533 self.failUnless(n.choose_relativity(o, True) == e)
534
535 def testChooseRelativity7(self):
536 n = dns.name.from_text('a.foo.', None)
537 o = None
538 e = n
539 self.failUnless(n.choose_relativity(o, False) == e)
540
541 def testFromWire1(self):
542 w = '\x03foo\x00\xc0\x00'
543 (n1, cused1) = dns.name.from_wire(w, 0)
544 (n2, cused2) = dns.name.from_wire(w, cused1)
545 en1 = dns.name.from_text('foo.')
546 en2 = en1
547 ecused1 = 5
548 ecused2 = 2
549 self.failUnless(n1 == en1 and cused1 == ecused1 and \
550 n2 == en2 and cused2 == ecused2)
551
552 def testFromWire1(self):
553 w = '\x03foo\x00\x01a\xc0\x00\x01b\xc0\x05'
554 current = 0
555 (n1, cused1) = dns.name.from_wire(w, current)
556 current += cused1
557 (n2, cused2) = dns.name.from_wire(w, current)
558 current += cused2
559 (n3, cused3) = dns.name.from_wire(w, current)
560 en1 = dns.name.from_text('foo.')
561 en2 = dns.name.from_text('a.foo.')
562 en3 = dns.name.from_text('b.a.foo.')
563 ecused1 = 5
564 ecused2 = 4
565 ecused3 = 4
566 self.failUnless(n1 == en1 and cused1 == ecused1 and \
567 n2 == en2 and cused2 == ecused2 and \
568 n3 == en3 and cused3 == ecused3)
569
570 def testBadFromWire1(self):
571 def bad():
572 w = '\x03foo\xc0\x04'
573 (n, cused) = dns.name.from_wire(w, 0)
574 self.failUnlessRaises(dns.name.BadPointer, bad)
575
576 def testBadFromWire2(self):
577 def bad():
578 w = '\x03foo\xc0\x05'
579 (n, cused) = dns.name.from_wire(w, 0)
580 self.failUnlessRaises(dns.name.BadPointer, bad)
581
582 def testBadFromWire3(self):
583 def bad():
584 w = '\xbffoo'
585 (n, cused) = dns.name.from_wire(w, 0)
586 self.failUnlessRaises(dns.name.BadLabelType, bad)
587
588 def testBadFromWire4(self):
589 def bad():
590 w = '\x41foo'
591 (n, cused) = dns.name.from_wire(w, 0)
592 self.failUnlessRaises(dns.name.BadLabelType, bad)
593
594 def testParent1(self):
595 n = dns.name.from_text('foo.bar.')
596 self.failUnless(n.parent() == dns.name.from_text('bar.'))
597 self.failUnless(n.parent().parent() == dns.name.root)
598
599 def testParent2(self):
600 n = dns.name.from_text('foo.bar', None)
601 self.failUnless(n.parent() == dns.name.from_text('bar', None))
602 self.failUnless(n.parent().parent() == dns.name.empty)
603
604 def testParent3(self):
605 def bad():
606 n = dns.name.root
607 n.parent()
608 self.failUnlessRaises(dns.name.NoParent, bad)
609
610 def testParent4(self):
611 def bad():
612 n = dns.name.empty
613 n.parent()
614 self.failUnlessRaises(dns.name.NoParent, bad)
615
616 def testFromUnicode1(self):
617 n = dns.name.from_text(u'foo.bar')
618 self.failUnless(n.labels == ('foo', 'bar', ''))
619
620 def testFromUnicode2(self):
621 n = dns.name.from_text(u'foo\u1234bar.bar')
622 self.failUnless(n.labels == ('xn--foobar-r5z', 'bar', ''))
623
624 def testFromUnicodeAlternateDot1(self):
625 n = dns.name.from_text(u'foo\u3002bar')
626 self.failUnless(n.labels == ('foo', 'bar', ''))
627
628 def testFromUnicodeAlternateDot2(self):
629 n = dns.name.from_text(u'foo\uff0ebar')
630 self.failUnless(n.labels == ('foo', 'bar', ''))
631
632 def testFromUnicodeAlternateDot3(self):
633 n = dns.name.from_text(u'foo\uff61bar')
634 self.failUnless(n.labels == ('foo', 'bar', ''))
635
636 def testToUnicode1(self):
637 n = dns.name.from_text(u'foo.bar')
638 s = n.to_unicode()
639 self.failUnless(s == u'foo.bar.')
640
641 def testToUnicode2(self):
642 n = dns.name.from_text(u'foo\u1234bar.bar')
643 s = n.to_unicode()
644 self.failUnless(s == u'foo\u1234bar.bar.')
645
646 def testToUnicode3(self):
647 n = dns.name.from_text('foo.bar')
648 s = n.to_unicode()
649 self.failUnless(s == u'foo.bar.')
650
651 def testReverseIPv4(self):
652 e = dns.name.from_text('1.0.0.127.in-addr.arpa.')
653 n = dns.reversename.from_address('127.0.0.1')
654 self.failUnless(e == n)
655
656 def testReverseIPv6(self):
657 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.')
658 n = dns.reversename.from_address('::1')
659 self.failUnless(e == n)
660
661 def testReverseIPv6MappedIpv4(self):
662 e = dns.name.from_text('1.0.0.127.in-addr.arpa.')
663 n = dns.reversename.from_address('::ffff:127.0.0.1')
664 self.failUnless(e == n)
665
666 def testBadReverseIPv4(self):
667 def bad():
668 n = dns.reversename.from_address('127.0.foo.1')
669 self.failUnlessRaises(dns.exception.SyntaxError, bad)
670
671 def testBadReverseIPv6(self):
672 def bad():
673 n = dns.reversename.from_address('::1::1')
674 self.failUnlessRaises(dns.exception.SyntaxError, bad)
675
676 def testForwardIPv4(self):
677 n = dns.name.from_text('1.0.0.127.in-addr.arpa.')
678 e = '127.0.0.1'
679 text = dns.reversename.to_address(n)
680 self.failUnless(text == e)
681
682 def testForwardIPv6(self):
683 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.')
684 e = '::1'
685 text = dns.reversename.to_address(n)
686 self.failUnless(text == e)
687
688 def testE164ToEnum(self):
689 text = '+1 650 555 1212'
690 e = dns.name.from_text('2.1.2.1.5.5.5.0.5.6.1.e164.arpa.')
691 n = dns.e164.from_e164(text)
692 self.failUnless(n == e)
693
694 def testEnumToE164(self):
695 n = dns.name.from_text('2.1.2.1.5.5.5.0.5.6.1.e164.arpa.')
696 e = '+16505551212'
697 text = dns.e164.to_e164(n)
698 self.failUnless(text == e)
699
700 if __name__ == '__main__':
701 unittest.main()
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.name
18 import dns.namedict
19
20 class NameTestCase(unittest.TestCase):
21
22 def setUp(self):
23 self.ndict = dns.namedict.NameDict()
24 n1 = dns.name.from_text('foo.bar.')
25 n2 = dns.name.from_text('bar.')
26 self.ndict[n1] = 1
27 self.ndict[n2] = 2
28 self.rndict = dns.namedict.NameDict()
29 n1 = dns.name.from_text('foo.bar', None)
30 n2 = dns.name.from_text('bar', None)
31 self.rndict[n1] = 1
32 self.rndict[n2] = 2
33
34 def testDepth(self):
35 self.failUnless(self.ndict.max_depth == 3)
36
37 def testLookup1(self):
38 k = dns.name.from_text('foo.bar.')
39 self.failUnless(self.ndict[k] == 1)
40
41 def testLookup2(self):
42 k = dns.name.from_text('foo.bar.')
43 self.failUnless(self.ndict.get_deepest_match(k)[1] == 1)
44
45 def testLookup3(self):
46 k = dns.name.from_text('a.b.c.foo.bar.')
47 self.failUnless(self.ndict.get_deepest_match(k)[1] == 1)
48
49 def testLookup4(self):
50 k = dns.name.from_text('a.b.c.bar.')
51 self.failUnless(self.ndict.get_deepest_match(k)[1] == 2)
52
53 def testLookup5(self):
54 def bad():
55 n = dns.name.from_text('a.b.c.')
56 (k, v) = self.ndict.get_deepest_match(n)
57 self.failUnlessRaises(KeyError, bad)
58
59 def testLookup6(self):
60 def bad():
61 (k, v) = self.ndict.get_deepest_match(dns.name.empty)
62 self.failUnlessRaises(KeyError, bad)
63
64 def testLookup7(self):
65 self.ndict[dns.name.empty] = 100
66 n = dns.name.from_text('a.b.c.')
67 (k, v) = self.ndict.get_deepest_match(n)
68 self.failUnless(v == 100)
69
70 def testLookup8(self):
71 def bad():
72 self.ndict['foo'] = 100
73 self.failUnlessRaises(ValueError, bad)
74
75 def testRelDepth(self):
76 self.failUnless(self.rndict.max_depth == 2)
77
78 def testRelLookup1(self):
79 k = dns.name.from_text('foo.bar', None)
80 self.failUnless(self.rndict[k] == 1)
81
82 def testRelLookup2(self):
83 k = dns.name.from_text('foo.bar', None)
84 self.failUnless(self.rndict.get_deepest_match(k)[1] == 1)
85
86 def testRelLookup3(self):
87 k = dns.name.from_text('a.b.c.foo.bar', None)
88 self.failUnless(self.rndict.get_deepest_match(k)[1] == 1)
89
90 def testRelLookup4(self):
91 k = dns.name.from_text('a.b.c.bar', None)
92 self.failUnless(self.rndict.get_deepest_match(k)[1] == 2)
93
94 def testRelLookup7(self):
95 self.rndict[dns.name.empty] = 100
96 n = dns.name.from_text('a.b.c', None)
97 (k, v) = self.rndict.get_deepest_match(n)
98 self.failUnless(v == 100)
99
100 if __name__ == '__main__':
101 unittest.main()
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.exception
18 import dns.ipv4
19 import dns.ipv6
20
21 # for convenience
22 aton4 = dns.ipv4.inet_aton
23 ntoa4 = dns.ipv4.inet_ntoa
24 aton6 = dns.ipv6.inet_aton
25 ntoa6 = dns.ipv6.inet_ntoa
26
27 v4_bad_addrs = ['256.1.1.1', '1.1.1', '1.1.1.1.1', '01.1.1.1',
28 '+1.1.1.1', '1.1.1.1+', '1..2.3.4', '.1.2.3.4',
29 '1.2.3.4.']
30
31 class NtoAAtoNTestCase(unittest.TestCase):
32
33 def test_aton1(self):
34 a = aton6('::')
35 self.failUnless(a == '\x00' * 16)
36
37 def test_aton2(self):
38 a = aton6('::1')
39 self.failUnless(a == '\x00' * 15 + '\x01')
40
41 def test_aton3(self):
42 a = aton6('::10.0.0.1')
43 self.failUnless(a == '\x00' * 12 + '\x0a\x00\x00\x01')
44
45 def test_aton4(self):
46 a = aton6('abcd::dcba')
47 self.failUnless(a == '\xab\xcd' + '\x00' * 12 + '\xdc\xba')
48
49 def test_aton5(self):
50 a = aton6('1:2:3:4:5:6:7:8')
51 self.failUnless(a == \
52 '00010002000300040005000600070008'.decode('hex_codec'))
53
54 def test_bad_aton1(self):
55 def bad():
56 a = aton6('abcd:dcba')
57 self.failUnlessRaises(dns.exception.SyntaxError, bad)
58
59 def test_bad_aton2(self):
60 def bad():
61 a = aton6('abcd::dcba::1')
62 self.failUnlessRaises(dns.exception.SyntaxError, bad)
63
64 def test_bad_aton3(self):
65 def bad():
66 a = aton6('1:2:3:4:5:6:7:8:9')
67 self.failUnlessRaises(dns.exception.SyntaxError, bad)
68
69 def test_aton1(self):
70 a = aton6('::')
71 self.failUnless(a == '\x00' * 16)
72
73 def test_aton2(self):
74 a = aton6('::1')
75 self.failUnless(a == '\x00' * 15 + '\x01')
76
77 def test_aton3(self):
78 a = aton6('::10.0.0.1')
79 self.failUnless(a == '\x00' * 12 + '\x0a\x00\x00\x01')
80
81 def test_aton4(self):
82 a = aton6('abcd::dcba')
83 self.failUnless(a == '\xab\xcd' + '\x00' * 12 + '\xdc\xba')
84
85 def test_ntoa1(self):
86 b = '00010002000300040005000600070008'.decode('hex_codec')
87 t = ntoa6(b)
88 self.failUnless(t == '1:2:3:4:5:6:7:8')
89
90 def test_ntoa2(self):
91 b = '\x00' * 16
92 t = ntoa6(b)
93 self.failUnless(t == '::')
94
95 def test_ntoa3(self):
96 b = '\x00' * 15 + '\x01'
97 t = ntoa6(b)
98 self.failUnless(t == '::1')
99
100 def test_ntoa4(self):
101 b = '\x80' + '\x00' * 15
102 t = ntoa6(b)
103 self.failUnless(t == '8000::')
104
105 def test_ntoa5(self):
106 b = '\x01\xcd' + '\x00' * 12 + '\x03\xef'
107 t = ntoa6(b)
108 self.failUnless(t == '1cd::3ef')
109
110 def test_ntoa6(self):
111 b = 'ffff00000000ffff000000000000ffff'.decode('hex_codec')
112 t = ntoa6(b)
113 self.failUnless(t == 'ffff:0:0:ffff::ffff')
114
115 def test_ntoa7(self):
116 b = '00000000ffff000000000000ffffffff'.decode('hex_codec')
117 t = ntoa6(b)
118 self.failUnless(t == '0:0:ffff::ffff:ffff')
119
120 def test_ntoa8(self):
121 b = 'ffff0000ffff00000000ffff00000000'.decode('hex_codec')
122 t = ntoa6(b)
123 self.failUnless(t == 'ffff:0:ffff::ffff:0:0')
124
125 def test_ntoa9(self):
126 b = '0000000000000000000000000a000001'.decode('hex_codec')
127 t = ntoa6(b)
128 self.failUnless(t == '::10.0.0.1')
129
130 def test_ntoa10(self):
131 b = '0000000000000000000000010a000001'.decode('hex_codec')
132 t = ntoa6(b)
133 self.failUnless(t == '::1:a00:1')
134
135 def test_ntoa11(self):
136 b = '00000000000000000000ffff0a000001'.decode('hex_codec')
137 t = ntoa6(b)
138 self.failUnless(t == '::ffff:10.0.0.1')
139
140 def test_ntoa12(self):
141 b = '000000000000000000000000ffffffff'.decode('hex_codec')
142 t = ntoa6(b)
143 self.failUnless(t == '::255.255.255.255')
144
145 def test_ntoa13(self):
146 b = '00000000000000000000ffffffffffff'.decode('hex_codec')
147 t = ntoa6(b)
148 self.failUnless(t == '::ffff:255.255.255.255')
149
150 def test_ntoa14(self):
151 b = '0000000000000000000000000001ffff'.decode('hex_codec')
152 t = ntoa6(b)
153 self.failUnless(t == '::0.1.255.255')
154
155 def test_bad_ntoa1(self):
156 def bad():
157 a = ntoa6('')
158 self.failUnlessRaises(ValueError, bad)
159
160 def test_bad_ntoa2(self):
161 def bad():
162 a = ntoa6('\x00' * 17)
163 self.failUnlessRaises(ValueError, bad)
164
165 def test_good_v4_aton(self):
166 pairs = [('1.2.3.4', '\x01\x02\x03\x04'),
167 ('255.255.255.255', '\xff\xff\xff\xff'),
168 ('0.0.0.0', '\x00\x00\x00\x00')]
169 for (t, b) in pairs:
170 b1 = aton4(t)
171 t1 = ntoa4(b1)
172 self.failUnless(b1 == b)
173 self.failUnless(t1 == t)
174
175 def test_bad_v4_aton(self):
176 def make_bad(a):
177 def bad():
178 return aton4(a)
179 return bad
180 for addr in v4_bad_addrs:
181 self.failUnlessRaises(dns.exception.SyntaxError, make_bad(addr))
182
183 def test_bad_v6_aton(self):
184 addrs = ['+::0', '0::0::', '::0::', '1:2:3:4:5:6:7:8:9',
185 ':::::::']
186 embedded = ['::' + x for x in v4_bad_addrs]
187 addrs.extend(embedded)
188 def make_bad(a):
189 def bad():
190 x = aton6(a)
191 return bad
192 for addr in addrs:
193 self.failUnlessRaises(dns.exception.SyntaxError, make_bad(addr))
194
195 def test_rfc5952_section_4_2_2(self):
196 addr = '2001:db8:0:1:1:1:1:1'
197 b1 = aton6(addr)
198 t1 = ntoa6(b1)
199 self.failUnless(t1 == addr)
200
201 def test_is_mapped(self):
202 t1 = '2001:db8:0:1:1:1:1:1'
203 t2 = '::ffff:127.0.0.1'
204 t3 = '1::ffff:127.0.0.1'
205 self.failIf(dns.ipv6.is_mapped(aton6(t1)))
206 self.failUnless(dns.ipv6.is_mapped(aton6(t2)))
207 self.failIf(dns.ipv6.is_mapped(aton6(t3)))
208
209 if __name__ == '__main__':
210 unittest.main()
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.rdataclass
18 import dns.rdatatype
19
20 class RdTypeAndClassTestCase(unittest.TestCase):
21
22 # Classes
23
24 def test_class_meta1(self):
25 self.failUnless(dns.rdataclass.is_metaclass(dns.rdataclass.ANY))
26
27 def test_class_meta2(self):
28 self.failUnless(not dns.rdataclass.is_metaclass(dns.rdataclass.IN))
29
30 def test_class_bytext1(self):
31 self.failUnless(dns.rdataclass.from_text('IN') == dns.rdataclass.IN)
32
33 def test_class_bytext2(self):
34 self.failUnless(dns.rdataclass.from_text('CLASS1') ==
35 dns.rdataclass.IN)
36
37 def test_class_bytext_bounds1(self):
38 self.failUnless(dns.rdataclass.from_text('CLASS0') == 0)
39 self.failUnless(dns.rdataclass.from_text('CLASS65535') == 65535)
40
41 def test_class_bytext_bounds2(self):
42 def bad():
43 junk = dns.rdataclass.from_text('CLASS65536')
44 self.failUnlessRaises(ValueError, bad)
45
46 def test_class_bytext_unknown(self):
47 def bad():
48 junk = dns.rdataclass.from_text('XXX')
49 self.failUnlessRaises(dns.rdataclass.UnknownRdataclass, bad)
50
51 def test_class_totext1(self):
52 self.failUnless(dns.rdataclass.to_text(dns.rdataclass.IN) == 'IN')
53
54 def test_class_totext1(self):
55 self.failUnless(dns.rdataclass.to_text(999) == 'CLASS999')
56
57 def test_class_totext_bounds1(self):
58 def bad():
59 junk = dns.rdataclass.to_text(-1)
60 self.failUnlessRaises(ValueError, bad)
61
62 def test_class_totext_bounds2(self):
63 def bad():
64 junk = dns.rdataclass.to_text(65536)
65 self.failUnlessRaises(ValueError, bad)
66
67 # Types
68
69 def test_type_meta1(self):
70 self.failUnless(dns.rdatatype.is_metatype(dns.rdatatype.ANY))
71
72 def test_type_meta2(self):
73 self.failUnless(dns.rdatatype.is_metatype(dns.rdatatype.OPT))
74
75 def test_type_meta3(self):
76 self.failUnless(not dns.rdatatype.is_metatype(dns.rdatatype.A))
77
78 def test_type_singleton1(self):
79 self.failUnless(dns.rdatatype.is_singleton(dns.rdatatype.SOA))
80
81 def test_type_singleton2(self):
82 self.failUnless(not dns.rdatatype.is_singleton(dns.rdatatype.A))
83
84 def test_type_bytext1(self):
85 self.failUnless(dns.rdatatype.from_text('A') == dns.rdatatype.A)
86
87 def test_type_bytext2(self):
88 self.failUnless(dns.rdatatype.from_text('TYPE1') ==
89 dns.rdatatype.A)
90
91 def test_type_bytext_bounds1(self):
92 self.failUnless(dns.rdatatype.from_text('TYPE0') == 0)
93 self.failUnless(dns.rdatatype.from_text('TYPE65535') == 65535)
94
95 def test_type_bytext_bounds2(self):
96 def bad():
97 junk = dns.rdatatype.from_text('TYPE65536')
98 self.failUnlessRaises(ValueError, bad)
99
100 def test_type_bytext_unknown(self):
101 def bad():
102 junk = dns.rdatatype.from_text('XXX')
103 self.failUnlessRaises(dns.rdatatype.UnknownRdatatype, bad)
104
105 def test_type_totext1(self):
106 self.failUnless(dns.rdatatype.to_text(dns.rdatatype.A) == 'A')
107
108 def test_type_totext1(self):
109 self.failUnless(dns.rdatatype.to_text(999) == 'TYPE999')
110
111 def test_type_totext_bounds1(self):
112 def bad():
113 junk = dns.rdatatype.to_text(-1)
114 self.failUnlessRaises(ValueError, bad)
115
116 def test_type_totext_bounds2(self):
117 def bad():
118 junk = dns.rdatatype.to_text(65536)
119 self.failUnlessRaises(ValueError, bad)
120
121 if __name__ == '__main__':
122 unittest.main()
0 # Copyright (C) 2014 Red Hat, Inc.
1 # Author: Petr Spacek <pspacek@redhat.com>
2 #
3 # Permission to use, copy, modify, and distribute this software and its
4 # documentation for any purpose with or without fee is hereby granted,
5 # provided that the above copyright notice and this permission notice
6 # appear in all copies.
7 #
8 # THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES
9 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
11 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
14 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
16 import unittest
17
18 import dns.rrset
19 import dns.rdtypes.ANY.DNSKEY
20
21
22 class RdtypeAnyDnskeyTestCase(unittest.TestCase):
23
24 def testFlagsEmpty(self):
25 '''Test DNSKEY flag to/from text conversion for zero flag/empty set.'''
26 good_s = set()
27 good_f = 0
28 from_flags = dns.rdtypes.ANY.DNSKEY.flags_to_text_set(good_f)
29 self.failUnless(from_flags == good_s,
30 '"%s" != "%s"' % (from_flags, good_s))
31 from_set = dns.rdtypes.ANY.DNSKEY.flags_from_text_set(good_s)
32 self.failUnless(from_set == good_f,
33 '"0x%x" != "0x%x"' % (from_set, good_f))
34
35 def testFlagsAll(self):
36 '''Test that all defined flags are recognized.'''
37 good_s = set(['SEP', 'REVOKE', 'ZONE'])
38 good_f = 0x181
39 from_flags = dns.rdtypes.ANY.DNSKEY.flags_to_text_set(good_f)
40 self.failUnless(from_flags == good_s,
41 '"%s" != "%s"' % (from_flags, good_s))
42 from_text = dns.rdtypes.ANY.DNSKEY.flags_from_text_set(good_s)
43 self.failUnless(from_text == good_f,
44 '"0x%x" != "0x%x"' % (from_text, good_f))
45
46 def testFlagsUnknownToText(self):
47 '''Test that undefined flags are returned in hexadecimal notation.'''
48 unk_s = set(['0x8000'])
49 flags_s = dns.rdtypes.ANY.DNSKEY.flags_to_text_set(0x8000)
50 self.failUnless(flags_s == unk_s, '"%s" != "%s"' % (flags_s, unk_s))
51
52 def testFlagsUnknownToFlags(self):
53 '''Test that conversion from undefined mnemonic raises error.'''
54 self.failUnlessRaises(NotImplementedError,
55 dns.rdtypes.ANY.DNSKEY.flags_from_text_set,
56 (['0x8000']))
57
58 def testFlagsRRToText(self):
59 '''Test that RR method returns correct flags.'''
60 rr = dns.rrset.from_text('foo', 300, 'IN', 'DNSKEY', '257 3 8 KEY=')[0]
61 rr_s = set(['ZONE', 'SEP'])
62 flags_s = rr.flags_to_text_set()
63 self.failUnless(flags_s == rr_s, '"%s" != "%s"' % (flags_s, rr_s))
64
65
66 if __name__ == '__main__':
67 unittest.main()
0 # Copyright (C) 2014 Red Hat, Inc.
1 # Author: Petr Spacek <pspacek@redhat.com>
2 #
3 # Permission to use, copy, modify, and distribute this software and its
4 # documentation for any purpose with or without fee is hereby granted,
5 # provided that the above copyright notice and this permission notice
6 # appear in all copies.
7 #
8 # THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES
9 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
11 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
14 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
16 import unittest
17
18 import dns.rrset
19 import dns.rdtypes.ANY.LOC
20
21 class RdtypeAnyLocTestCase(unittest.TestCase):
22
23 def testEqual1(self):
24 '''Test default values for size, horizontal and vertical precision.'''
25 r1 = dns.rrset.from_text('foo', 300, 'IN', 'LOC',
26 '49 11 42.400 N 16 36 29.600 E 227.64m')
27 r2 = dns.rrset.from_text('FOO', 600, 'in', 'loc',
28 '49 11 42.400 N 16 36 29.600 E 227.64m '
29 '1.00m 10000.00m 10.00m')
30 self.failUnless(r1 == r2, '"%s" != "%s"' % (r1, r2))
31
32 def testEqual2(self):
33 '''Test default values for size, horizontal and vertical precision.'''
34 r1 = dns.rdtypes.ANY.LOC.LOC(1, 29, (49, 11, 42, 400),
35 (16, 36, 29, 600), 22764.0) # centimeters
36 r2 = dns.rdtypes.ANY.LOC.LOC(1, 29, (49, 11, 42, 400),
37 (16, 36, 29, 600), 22764.0, # centimeters
38 100.0, 1000000.00, 1000.0) # centimeters
39 self.failUnless(r1 == r2, '"%s" != "%s"' % (r1, r2))
40
41 def testEqual3(self):
42 '''Test size, horizontal and vertical precision parsers: 100 cm == 1 m.
43
44 Parsers in from_text() and __init__() have to produce equal results.'''
45 r1 = dns.rdtypes.ANY.LOC.LOC(1, 29, (49, 11, 42, 400),
46 (16, 36, 29, 600), 22764.0,
47 200.0, 1000.00, 200.0) # centimeters
48 r2 = dns.rrset.from_text('FOO', 600, 'in', 'loc',
49 '49 11 42.400 N 16 36 29.600 E 227.64m '
50 '2.00m 10.00m 2.00m')[0]
51 self.failUnless(r1 == r2, '"%s" != "%s"' % (r1, r2))
52
53 def testEqual4(self):
54 '''Test size, horizontal and vertical precision parsers without unit.
55
56 Parsers in from_text() and __init__() have produce equal result
57 for values with and without trailing "m".'''
58 r1 = dns.rdtypes.ANY.LOC.LOC(1, 29, (49, 11, 42, 400),
59 (16, 36, 29, 600), 22764.0,
60 200.0, 1000.00, 200.0) # centimeters
61 r2 = dns.rrset.from_text('FOO', 600, 'in', 'loc',
62 '49 11 42.400 N 16 36 29.600 E 227.64 '
63 '2 10 2')[0] # meters without explicit unit
64 self.failUnless(r1 == r2, '"%s" != "%s"' % (r1, r2))
65
66 if __name__ == '__main__':
67 unittest.main()
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import cStringIO
16 import select
17 import sys
18 import time
19 import unittest
20
21 import dns.name
22 import dns.message
23 import dns.name
24 import dns.rdataclass
25 import dns.rdatatype
26 import dns.resolver
27
28 resolv_conf = """
29 /t/t
30 # comment 1
31 ; comment 2
32 domain foo
33 nameserver 10.0.0.1
34 nameserver 10.0.0.2
35 """
36
37 message_text = """id 1234
38 opcode QUERY
39 rcode NOERROR
40 flags QR AA RD
41 ;QUESTION
42 example. IN A
43 ;ANSWER
44 example. 1 IN A 10.0.0.1
45 ;AUTHORITY
46 ;ADDITIONAL
47 """
48
49 class FakeAnswer(object):
50 def __init__(self, expiration):
51 self.expiration = expiration
52
53 class BaseResolverTests(object):
54
55 if sys.platform != 'win32':
56 def testRead(self):
57 f = cStringIO.StringIO(resolv_conf)
58 r = dns.resolver.Resolver(f)
59 self.failUnless(r.nameservers == ['10.0.0.1', '10.0.0.2'] and
60 r.domain == dns.name.from_text('foo'))
61
62 def testCacheExpiration(self):
63 message = dns.message.from_text(message_text)
64 name = dns.name.from_text('example.')
65 answer = dns.resolver.Answer(name, dns.rdatatype.A, dns.rdataclass.IN,
66 message)
67 cache = dns.resolver.Cache()
68 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
69 time.sleep(2)
70 self.failUnless(cache.get((name, dns.rdatatype.A, dns.rdataclass.IN))
71 is None)
72
73 def testCacheCleaning(self):
74 message = dns.message.from_text(message_text)
75 name = dns.name.from_text('example.')
76 answer = dns.resolver.Answer(name, dns.rdatatype.A, dns.rdataclass.IN,
77 message)
78 cache = dns.resolver.Cache(cleaning_interval=1.0)
79 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
80 time.sleep(2)
81 self.failUnless(cache.get((name, dns.rdatatype.A, dns.rdataclass.IN))
82 is None)
83
84 def testZoneForName1(self):
85 name = dns.name.from_text('www.dnspython.org.')
86 ezname = dns.name.from_text('dnspython.org.')
87 zname = dns.resolver.zone_for_name(name)
88 self.failUnless(zname == ezname)
89
90 def testZoneForName2(self):
91 name = dns.name.from_text('a.b.www.dnspython.org.')
92 ezname = dns.name.from_text('dnspython.org.')
93 zname = dns.resolver.zone_for_name(name)
94 self.failUnless(zname == ezname)
95
96 def testZoneForName3(self):
97 name = dns.name.from_text('dnspython.org.')
98 ezname = dns.name.from_text('dnspython.org.')
99 zname = dns.resolver.zone_for_name(name)
100 self.failUnless(zname == ezname)
101
102 def testZoneForName4(self):
103 def bad():
104 name = dns.name.from_text('dnspython.org', None)
105 zname = dns.resolver.zone_for_name(name)
106 self.failUnlessRaises(dns.resolver.NotAbsolute, bad)
107
108 def testLRUReplace(self):
109 cache = dns.resolver.LRUCache(4)
110 for i in xrange(0, 5):
111 name = dns.name.from_text('example%d.' % i)
112 answer = FakeAnswer(time.time() + 1)
113 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
114 for i in xrange(0, 5):
115 name = dns.name.from_text('example%d.' % i)
116 if i == 0:
117 self.failUnless(cache.get((name, dns.rdatatype.A,
118 dns.rdataclass.IN))
119 is None)
120 else:
121 self.failUnless(not cache.get((name, dns.rdatatype.A,
122 dns.rdataclass.IN))
123 is None)
124
125 def testLRUDoesLRU(self):
126 cache = dns.resolver.LRUCache(4)
127 for i in xrange(0, 4):
128 name = dns.name.from_text('example%d.' % i)
129 answer = FakeAnswer(time.time() + 1)
130 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
131 name = dns.name.from_text('example0.')
132 cache.get((name, dns.rdatatype.A, dns.rdataclass.IN))
133 # The LRU is now example1.
134 name = dns.name.from_text('example4.')
135 answer = FakeAnswer(time.time() + 1)
136 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
137 for i in xrange(0, 5):
138 name = dns.name.from_text('example%d.' % i)
139 if i == 1:
140 self.failUnless(cache.get((name, dns.rdatatype.A,
141 dns.rdataclass.IN))
142 is None)
143 else:
144 self.failUnless(not cache.get((name, dns.rdatatype.A,
145 dns.rdataclass.IN))
146 is None)
147
148 def testLRUExpiration(self):
149 cache = dns.resolver.LRUCache(4)
150 for i in xrange(0, 4):
151 name = dns.name.from_text('example%d.' % i)
152 answer = FakeAnswer(time.time() + 1)
153 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
154 time.sleep(2)
155 for i in xrange(0, 4):
156 name = dns.name.from_text('example%d.' % i)
157 self.failUnless(cache.get((name, dns.rdatatype.A,
158 dns.rdataclass.IN))
159 is None)
160
161 class PollingMonkeyPatchMixin(object):
162 def setUp(self):
163 self.__native_polling_backend = dns.query._polling_backend
164 dns.query._set_polling_backend(self.polling_backend())
165
166 unittest.TestCase.setUp(self)
167
168 def tearDown(self):
169 dns.query._set_polling_backend(self.__native_polling_backend)
170
171 unittest.TestCase.tearDown(self)
172
173 class SelectResolverTestCase(PollingMonkeyPatchMixin, BaseResolverTests, unittest.TestCase):
174 def polling_backend(self):
175 return dns.query._select_for
176
177 if hasattr(select, 'poll'):
178 class PollResolverTestCase(PollingMonkeyPatchMixin, BaseResolverTests, unittest.TestCase):
179 def polling_backend(self):
180 return dns.query._poll_for
181
182 if __name__ == '__main__':
183 unittest.main()
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.rrset
18
19 class RRsetTestCase(unittest.TestCase):
20
21 def testEqual1(self):
22 r1 = dns.rrset.from_text('foo', 300, 'in', 'a', '10.0.0.1', '10.0.0.2')
23 r2 = dns.rrset.from_text('FOO', 300, 'in', 'a', '10.0.0.2', '10.0.0.1')
24 self.failUnless(r1 == r2)
25
26 def testEqual2(self):
27 r1 = dns.rrset.from_text('foo', 300, 'in', 'a', '10.0.0.1', '10.0.0.2')
28 r2 = dns.rrset.from_text('FOO', 600, 'in', 'a', '10.0.0.2', '10.0.0.1')
29 self.failUnless(r1 == r2)
30
31 def testNotEqual1(self):
32 r1 = dns.rrset.from_text('fooa', 30, 'in', 'a', '10.0.0.1', '10.0.0.2')
33 r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1')
34 self.failUnless(r1 != r2)
35
36 def testNotEqual2(self):
37 r1 = dns.rrset.from_text('foo', 30, 'in', 'a', '10.0.0.1', '10.0.0.3')
38 r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1')
39 self.failUnless(r1 != r2)
40
41 def testNotEqual3(self):
42 r1 = dns.rrset.from_text('foo', 30, 'in', 'a', '10.0.0.1', '10.0.0.2',
43 '10.0.0.3')
44 r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1')
45 self.failUnless(r1 != r2)
46
47 def testNotEqual4(self):
48 r1 = dns.rrset.from_text('foo', 30, 'in', 'a', '10.0.0.1')
49 r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1')
50 self.failUnless(r1 != r2)
51
52 if __name__ == '__main__':
53 unittest.main()
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.set
18
19 # for convenience
20 S = dns.set.Set
21
22 class SimpleSetTestCase(unittest.TestCase):
23
24 def testLen1(self):
25 s1 = S()
26 self.failUnless(len(s1) == 0)
27
28 def testLen2(self):
29 s1 = S([1, 2, 3])
30 self.failUnless(len(s1) == 3)
31
32 def testLen3(self):
33 s1 = S([1, 2, 3, 3, 3])
34 self.failUnless(len(s1) == 3)
35
36 def testUnion1(self):
37 s1 = S([1, 2, 3])
38 s2 = S([1, 2, 3])
39 e = S([1, 2, 3])
40 self.failUnless(s1 | s2 == e)
41
42 def testUnion2(self):
43 s1 = S([1, 2, 3])
44 s2 = S([])
45 e = S([1, 2, 3])
46 self.failUnless(s1 | s2 == e)
47
48 def testUnion3(self):
49 s1 = S([1, 2, 3])
50 s2 = S([3, 4])
51 e = S([1, 2, 3, 4])
52 self.failUnless(s1 | s2 == e)
53
54 def testIntersection1(self):
55 s1 = S([1, 2, 3])
56 s2 = S([1, 2, 3])
57 e = S([1, 2, 3])
58 self.failUnless(s1 & s2 == e)
59
60 def testIntersection2(self):
61 s1 = S([0, 1, 2, 3])
62 s2 = S([1, 2, 3, 4])
63 e = S([1, 2, 3])
64 self.failUnless(s1 & s2 == e)
65
66 def testIntersection3(self):
67 s1 = S([1, 2, 3])
68 s2 = S([])
69 e = S([])
70 self.failUnless(s1 & s2 == e)
71
72 def testIntersection4(self):
73 s1 = S([1, 2, 3])
74 s2 = S([5, 4])
75 e = S([])
76 self.failUnless(s1 & s2 == e)
77
78 def testDifference1(self):
79 s1 = S([1, 2, 3])
80 s2 = S([5, 4])
81 e = S([1, 2, 3])
82 self.failUnless(s1 - s2 == e)
83
84 def testDifference2(self):
85 s1 = S([1, 2, 3])
86 s2 = S([])
87 e = S([1, 2, 3])
88 self.failUnless(s1 - s2 == e)
89
90 def testDifference3(self):
91 s1 = S([1, 2, 3])
92 s2 = S([3, 2])
93 e = S([1])
94 self.failUnless(s1 - s2 == e)
95
96 def testDifference4(self):
97 s1 = S([1, 2, 3])
98 s2 = S([3, 2, 1])
99 e = S([])
100 self.failUnless(s1 - s2 == e)
101
102 def testSubset1(self):
103 s1 = S([1, 2, 3])
104 s2 = S([3, 2, 1])
105 self.failUnless(s1.issubset(s2))
106
107 def testSubset2(self):
108 s1 = S([1, 2, 3])
109 self.failUnless(s1.issubset(s1))
110
111 def testSubset3(self):
112 s1 = S([])
113 s2 = S([1, 2, 3])
114 self.failUnless(s1.issubset(s2))
115
116 def testSubset4(self):
117 s1 = S([1])
118 s2 = S([1, 2, 3])
119 self.failUnless(s1.issubset(s2))
120
121 def testSubset5(self):
122 s1 = S([])
123 s2 = S([])
124 self.failUnless(s1.issubset(s2))
125
126 def testSubset6(self):
127 s1 = S([1, 4])
128 s2 = S([1, 2, 3])
129 self.failUnless(not s1.issubset(s2))
130
131 def testSuperset1(self):
132 s1 = S([1, 2, 3])
133 s2 = S([3, 2, 1])
134 self.failUnless(s1.issuperset(s2))
135
136 def testSuperset2(self):
137 s1 = S([1, 2, 3])
138 self.failUnless(s1.issuperset(s1))
139
140 def testSuperset3(self):
141 s1 = S([1, 2, 3])
142 s2 = S([])
143 self.failUnless(s1.issuperset(s2))
144
145 def testSuperset4(self):
146 s1 = S([1, 2, 3])
147 s2 = S([1])
148 self.failUnless(s1.issuperset(s2))
149
150 def testSuperset5(self):
151 s1 = S([])
152 s2 = S([])
153 self.failUnless(s1.issuperset(s2))
154
155 def testSuperset6(self):
156 s1 = S([1, 2, 3])
157 s2 = S([1, 4])
158 self.failUnless(not s1.issuperset(s2))
159
160 def testUpdate1(self):
161 s1 = S([1, 2, 3])
162 u = (4, 5, 6)
163 e = S([1, 2, 3, 4, 5, 6])
164 s1.update(u)
165 self.failUnless(s1 == e)
166
167 def testUpdate2(self):
168 s1 = S([1, 2, 3])
169 u = []
170 e = S([1, 2, 3])
171 s1.update(u)
172 self.failUnless(s1 == e)
173
174 def testGetitem(self):
175 s1 = S([1, 2, 3])
176 i0 = s1[0]
177 i1 = s1[1]
178 i2 = s1[2]
179 s2 = S([i0, i1, i2])
180 self.failUnless(s1 == s2)
181
182 def testGetslice(self):
183 s1 = S([1, 2, 3])
184 slice = s1[0:2]
185 self.failUnless(len(slice) == 2)
186 item = s1[2]
187 slice.append(item)
188 s2 = S(slice)
189 self.failUnless(s1 == s2)
190
191 def testDelitem(self):
192 s1 = S([1, 2, 3])
193 del s1[0]
194 i1 = s1[0]
195 i2 = s1[1]
196 self.failUnless(i1 != i2)
197 self.failUnless(i1 == 1 or i1 == 2 or i1 == 3)
198 self.failUnless(i2 == 1 or i2 == 2 or i2 == 3)
199
200 def testDelslice(self):
201 s1 = S([1, 2, 3])
202 del s1[0:2]
203 i1 = s1[0]
204 self.failUnless(i1 == 1 or i1 == 2 or i1 == 3)
205
206 if __name__ == '__main__':
207 unittest.main()
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.exception
18 import dns.tokenizer
19
20 Token = dns.tokenizer.Token
21
22 class TokenizerTestCase(unittest.TestCase):
23
24 def testQuotedString1(self):
25 tok = dns.tokenizer.Tokenizer(r'"foo"')
26 token = tok.get()
27 self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, 'foo'))
28
29 def testQuotedString2(self):
30 tok = dns.tokenizer.Tokenizer(r'""')
31 token = tok.get()
32 self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, ''))
33
34 def testQuotedString3(self):
35 tok = dns.tokenizer.Tokenizer(r'"\"foo\""')
36 token = tok.get()
37 self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, '"foo"'))
38
39 def testQuotedString4(self):
40 tok = dns.tokenizer.Tokenizer(r'"foo\010bar"')
41 token = tok.get()
42 self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, 'foo\x0abar'))
43
44 def testQuotedString5(self):
45 def bad():
46 tok = dns.tokenizer.Tokenizer(r'"foo')
47 token = tok.get()
48 self.failUnlessRaises(dns.exception.UnexpectedEnd, bad)
49
50 def testQuotedString6(self):
51 def bad():
52 tok = dns.tokenizer.Tokenizer(r'"foo\01')
53 token = tok.get()
54 self.failUnlessRaises(dns.exception.SyntaxError, bad)
55
56 def testQuotedString7(self):
57 def bad():
58 tok = dns.tokenizer.Tokenizer('"foo\nbar"')
59 token = tok.get()
60 self.failUnlessRaises(dns.exception.SyntaxError, bad)
61
62 def testEmpty1(self):
63 tok = dns.tokenizer.Tokenizer('')
64 token = tok.get()
65 self.failUnless(token.is_eof())
66
67 def testEmpty2(self):
68 tok = dns.tokenizer.Tokenizer('')
69 token1 = tok.get()
70 token2 = tok.get()
71 self.failUnless(token1.is_eof() and token2.is_eof())
72
73 def testEOL(self):
74 tok = dns.tokenizer.Tokenizer('\n')
75 token1 = tok.get()
76 token2 = tok.get()
77 self.failUnless(token1.is_eol() and token2.is_eof())
78
79 def testWS1(self):
80 tok = dns.tokenizer.Tokenizer(' \n')
81 token1 = tok.get()
82 self.failUnless(token1.is_eol())
83
84 def testWS2(self):
85 tok = dns.tokenizer.Tokenizer(' \n')
86 token1 = tok.get(want_leading=True)
87 self.failUnless(token1.is_whitespace())
88
89 def testComment1(self):
90 tok = dns.tokenizer.Tokenizer(' ;foo\n')
91 token1 = tok.get()
92 self.failUnless(token1.is_eol())
93
94 def testComment2(self):
95 tok = dns.tokenizer.Tokenizer(' ;foo\n')
96 token1 = tok.get(want_comment = True)
97 token2 = tok.get()
98 self.failUnless(token1 == Token(dns.tokenizer.COMMENT, 'foo') and
99 token2.is_eol())
100
101 def testComment3(self):
102 tok = dns.tokenizer.Tokenizer(' ;foo bar\n')
103 token1 = tok.get(want_comment = True)
104 token2 = tok.get()
105 self.failUnless(token1 == Token(dns.tokenizer.COMMENT, 'foo bar') and
106 token2.is_eol())
107
108 def testMultiline1(self):
109 tok = dns.tokenizer.Tokenizer('( foo\n\n bar\n)')
110 tokens = list(iter(tok))
111 self.failUnless(tokens == [Token(dns.tokenizer.IDENTIFIER, 'foo'),
112 Token(dns.tokenizer.IDENTIFIER, 'bar')])
113
114 def testMultiline2(self):
115 tok = dns.tokenizer.Tokenizer('( foo\n\n bar\n)\n')
116 tokens = list(iter(tok))
117 self.failUnless(tokens == [Token(dns.tokenizer.IDENTIFIER, 'foo'),
118 Token(dns.tokenizer.IDENTIFIER, 'bar'),
119 Token(dns.tokenizer.EOL, '\n')])
120 def testMultiline3(self):
121 def bad():
122 tok = dns.tokenizer.Tokenizer('foo)')
123 tokens = list(iter(tok))
124 self.failUnlessRaises(dns.exception.SyntaxError, bad)
125
126 def testMultiline4(self):
127 def bad():
128 tok = dns.tokenizer.Tokenizer('((foo)')
129 tokens = list(iter(tok))
130 self.failUnlessRaises(dns.exception.SyntaxError, bad)
131
132 def testUnget1(self):
133 tok = dns.tokenizer.Tokenizer('foo')
134 t1 = tok.get()
135 tok.unget(t1)
136 t2 = tok.get()
137 self.failUnless(t1 == t2 and t1.ttype == dns.tokenizer.IDENTIFIER and \
138 t1.value == 'foo')
139
140 def testUnget2(self):
141 def bad():
142 tok = dns.tokenizer.Tokenizer('foo')
143 t1 = tok.get()
144 tok.unget(t1)
145 tok.unget(t1)
146 self.failUnlessRaises(dns.tokenizer.UngetBufferFull, bad)
147
148 def testGetEOL1(self):
149 tok = dns.tokenizer.Tokenizer('\n')
150 t = tok.get_eol()
151 self.failUnless(t == '\n')
152
153 def testGetEOL2(self):
154 tok = dns.tokenizer.Tokenizer('')
155 t = tok.get_eol()
156 self.failUnless(t == '')
157
158 def testEscapedDelimiter1(self):
159 tok = dns.tokenizer.Tokenizer(r'ch\ ld')
160 t = tok.get()
161 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\ ld')
162
163 def testEscapedDelimiter2(self):
164 tok = dns.tokenizer.Tokenizer(r'ch\032ld')
165 t = tok.get()
166 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\032ld')
167
168 def testEscapedDelimiter3(self):
169 tok = dns.tokenizer.Tokenizer(r'ch\ild')
170 t = tok.get()
171 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\ild')
172
173 def testEscapedDelimiter1u(self):
174 tok = dns.tokenizer.Tokenizer(r'ch\ ld')
175 t = tok.get().unescape()
176 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch ld')
177
178 def testEscapedDelimiter2u(self):
179 tok = dns.tokenizer.Tokenizer(r'ch\032ld')
180 t = tok.get().unescape()
181 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == 'ch ld')
182
183 def testEscapedDelimiter3u(self):
184 tok = dns.tokenizer.Tokenizer(r'ch\ild')
185 t = tok.get().unescape()
186 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'child')
187
188 if __name__ == '__main__':
189 unittest.main()
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.update
18 import dns.rdata
19 import dns.rdataset
20
21 goodhex = '0001 2800 0001 0005 0007 0000' \
22 '076578616d706c6500 0006 0001' \
23 '03666f6fc00c 00ff 00ff 00000000 0000' \
24 'c019 0001 00ff 00000000 0000' \
25 '03626172c00c 0001 0001 00000000 0004 0a000005' \
26 '05626c617a32c00c 00ff 00fe 00000000 0000' \
27 'c049 0001 00fe 00000000 0000' \
28 'c019 0001 00ff 00000000 0000' \
29 'c019 0001 0001 0000012c 0004 0a000001' \
30 'c019 0001 0001 0000012c 0004 0a000002' \
31 'c035 0001 0001 0000012c 0004 0a000003' \
32 'c035 0001 00fe 00000000 0004 0a000004' \
33 '04626c617ac00c 0001 00ff 00000000 0000' \
34 'c049 00ff 00ff 00000000 0000'
35
36 goodwire = goodhex.replace(' ', '').decode('hex_codec')
37
38 update_text="""id 1
39 opcode UPDATE
40 rcode NOERROR
41 ;ZONE
42 example. IN SOA
43 ;PREREQ
44 foo ANY ANY
45 foo ANY A
46 bar 0 IN A 10.0.0.5
47 blaz2 NONE ANY
48 blaz2 NONE A
49 ;UPDATE
50 foo ANY A
51 foo 300 IN A 10.0.0.1
52 foo 300 IN A 10.0.0.2
53 bar 300 IN A 10.0.0.3
54 bar 0 NONE A 10.0.0.4
55 blaz ANY A
56 blaz2 ANY ANY
57 """
58
59 class UpdateTestCase(unittest.TestCase):
60
61 def test_to_wire1(self):
62 update = dns.update.Update('example')
63 update.id = 1
64 update.present('foo')
65 update.present('foo', 'a')
66 update.present('bar', 'a', '10.0.0.5')
67 update.absent('blaz2')
68 update.absent('blaz2', 'a')
69 update.replace('foo', 300, 'a', '10.0.0.1', '10.0.0.2')
70 update.add('bar', 300, 'a', '10.0.0.3')
71 update.delete('bar', 'a', '10.0.0.4')
72 update.delete('blaz','a')
73 update.delete('blaz2')
74 self.failUnless(update.to_wire() == goodwire)
75
76 def test_to_wire2(self):
77 update = dns.update.Update('example')
78 update.id = 1
79 update.present('foo')
80 update.present('foo', 'a')
81 update.present('bar', 'a', '10.0.0.5')
82 update.absent('blaz2')
83 update.absent('blaz2', 'a')
84 update.replace('foo', 300, 'a', '10.0.0.1', '10.0.0.2')
85 update.add('bar', 300, dns.rdata.from_text(1, 1, '10.0.0.3'))
86 update.delete('bar', 'a', '10.0.0.4')
87 update.delete('blaz','a')
88 update.delete('blaz2')
89 self.failUnless(update.to_wire() == goodwire)
90
91 def test_to_wire3(self):
92 update = dns.update.Update('example')
93 update.id = 1
94 update.present('foo')
95 update.present('foo', 'a')
96 update.present('bar', 'a', '10.0.0.5')
97 update.absent('blaz2')
98 update.absent('blaz2', 'a')
99 update.replace('foo', 300, 'a', '10.0.0.1', '10.0.0.2')
100 update.add('bar', dns.rdataset.from_text(1, 1, 300, '10.0.0.3'))
101 update.delete('bar', 'a', '10.0.0.4')
102 update.delete('blaz','a')
103 update.delete('blaz2')
104 self.failUnless(update.to_wire() == goodwire)
105
106 def test_from_text1(self):
107 update = dns.message.from_text(update_text)
108 w = update.to_wire(origin=dns.name.from_text('example'),
109 want_shuffle=False)
110 self.failUnless(w == goodwire)
111
112 if __name__ == '__main__':
113 unittest.main()
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import cStringIO
16 import filecmp
17 import os
18 import unittest
19
20 import dns.exception
21 import dns.rdata
22 import dns.rdataclass
23 import dns.rdatatype
24 import dns.rrset
25 import dns.zone
26
27 example_text = """$TTL 3600
28 $ORIGIN example.
29 @ soa foo bar 1 2 3 4 5
30 @ ns ns1
31 @ ns ns2
32 ns1 a 10.0.0.1
33 ns2 a 10.0.0.2
34 $TTL 300
35 $ORIGIN foo.example.
36 bar mx 0 blaz
37 """
38
39 example_text_output = """@ 3600 IN SOA foo bar 1 2 3 4 5
40 @ 3600 IN NS ns1
41 @ 3600 IN NS ns2
42 bar.foo 300 IN MX 0 blaz.foo
43 ns1 3600 IN A 10.0.0.1
44 ns2 3600 IN A 10.0.0.2
45 """
46
47 something_quite_similar = """@ 3600 IN SOA foo bar 1 2 3 4 5
48 @ 3600 IN NS ns1
49 @ 3600 IN NS ns2
50 bar.foo 300 IN MX 0 blaz.foo
51 ns1 3600 IN A 10.0.0.1
52 ns2 3600 IN A 10.0.0.3
53 """
54
55 something_different = """@ 3600 IN SOA fooa bar 1 2 3 4 5
56 @ 3600 IN NS ns11
57 @ 3600 IN NS ns21
58 bar.fooa 300 IN MX 0 blaz.fooa
59 ns11 3600 IN A 10.0.0.11
60 ns21 3600 IN A 10.0.0.21
61 """
62
63 ttl_example_text = """$TTL 1h
64 $ORIGIN example.
65 @ soa foo bar 1 2 3 4 5
66 @ ns ns1
67 @ ns ns2
68 ns1 1d1s a 10.0.0.1
69 ns2 1w1D1h1m1S a 10.0.0.2
70 """
71
72 no_soa_text = """$TTL 1h
73 $ORIGIN example.
74 @ ns ns1
75 @ ns ns2
76 ns1 1d1s a 10.0.0.1
77 ns2 1w1D1h1m1S a 10.0.0.2
78 """
79
80 no_ns_text = """$TTL 1h
81 $ORIGIN example.
82 @ soa foo bar 1 2 3 4 5
83 """
84
85 include_text = """$INCLUDE "example"
86 """
87
88 bad_directive_text = """$FOO bar
89 $ORIGIN example.
90 @ soa foo bar 1 2 3 4 5
91 @ ns ns1
92 @ ns ns2
93 ns1 1d1s a 10.0.0.1
94 ns2 1w1D1h1m1S a 10.0.0.2
95 """
96
97 _keep_output = False
98
99 class ZoneTestCase(unittest.TestCase):
100
101 def testFromFile1(self):
102 z = dns.zone.from_file('example', 'example')
103 ok = False
104 try:
105 z.to_file('example1.out', nl='\x0a')
106 ok = filecmp.cmp('example1.out', 'example1.good')
107 finally:
108 if not _keep_output:
109 os.unlink('example1.out')
110 self.failUnless(ok)
111
112 def testFromFile2(self):
113 z = dns.zone.from_file('example', 'example', relativize=False)
114 ok = False
115 try:
116 z.to_file('example2.out', relativize=False, nl='\x0a')
117 ok = filecmp.cmp('example2.out', 'example2.good')
118 finally:
119 if not _keep_output:
120 os.unlink('example2.out')
121 self.failUnless(ok)
122
123 def testToText(self):
124 z = dns.zone.from_file('example', 'example')
125 ok = False
126 try:
127 text_zone = z.to_text(nl='\x0a')
128 f = open('example3.out', 'wb')
129 f.write(text_zone)
130 f.close()
131 ok = filecmp.cmp('example3.out', 'example3.good')
132 finally:
133 if not _keep_output:
134 os.unlink('example3.out')
135 self.failUnless(ok)
136
137 def testFromText(self):
138 z = dns.zone.from_text(example_text, 'example.', relativize=True)
139 f = cStringIO.StringIO()
140 names = z.nodes.keys()
141 names.sort()
142 for n in names:
143 print >> f, z[n].to_text(n)
144 self.failUnless(f.getvalue() == example_text_output)
145
146 def testTorture1(self):
147 #
148 # Read a zone containing all our supported RR types, and
149 # for each RR in the zone, convert the rdata into wire format
150 # and then back out, and see if we get equal rdatas.
151 #
152 f = cStringIO.StringIO()
153 o = dns.name.from_text('example.')
154 z = dns.zone.from_file('example', o)
155 for (name, node) in z.iteritems():
156 for rds in node:
157 for rd in rds:
158 f.seek(0)
159 f.truncate()
160 rd.to_wire(f, origin=o)
161 wire = f.getvalue()
162 rd2 = dns.rdata.from_wire(rds.rdclass, rds.rdtype,
163 wire, 0, len(wire),
164 origin = o)
165 self.failUnless(rd == rd2)
166
167 def testEqual(self):
168 z1 = dns.zone.from_text(example_text, 'example.', relativize=True)
169 z2 = dns.zone.from_text(example_text_output, 'example.',
170 relativize=True)
171 self.failUnless(z1 == z2)
172
173 def testNotEqual1(self):
174 z1 = dns.zone.from_text(example_text, 'example.', relativize=True)
175 z2 = dns.zone.from_text(something_quite_similar, 'example.',
176 relativize=True)
177 self.failUnless(z1 != z2)
178
179 def testNotEqual2(self):
180 z1 = dns.zone.from_text(example_text, 'example.', relativize=True)
181 z2 = dns.zone.from_text(something_different, 'example.',
182 relativize=True)
183 self.failUnless(z1 != z2)
184
185 def testNotEqual3(self):
186 z1 = dns.zone.from_text(example_text, 'example.', relativize=True)
187 z2 = dns.zone.from_text(something_different, 'example2.',
188 relativize=True)
189 self.failUnless(z1 != z2)
190
191 def testFindRdataset1(self):
192 z = dns.zone.from_text(example_text, 'example.', relativize=True)
193 rds = z.find_rdataset('@', 'soa')
194 exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
195 self.failUnless(rds == exrds)
196
197 def testFindRdataset2(self):
198 def bad():
199 z = dns.zone.from_text(example_text, 'example.', relativize=True)
200 rds = z.find_rdataset('@', 'loc')
201 self.failUnlessRaises(KeyError, bad)
202
203 def testFindRRset1(self):
204 z = dns.zone.from_text(example_text, 'example.', relativize=True)
205 rrs = z.find_rrset('@', 'soa')
206 exrrs = dns.rrset.from_text('@', 300, 'IN', 'SOA', 'foo bar 1 2 3 4 5')
207 self.failUnless(rrs == exrrs)
208
209 def testFindRRset2(self):
210 def bad():
211 z = dns.zone.from_text(example_text, 'example.', relativize=True)
212 rrs = z.find_rrset('@', 'loc')
213 self.failUnlessRaises(KeyError, bad)
214
215 def testGetRdataset1(self):
216 z = dns.zone.from_text(example_text, 'example.', relativize=True)
217 rds = z.get_rdataset('@', 'soa')
218 exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
219 self.failUnless(rds == exrds)
220
221 def testGetRdataset2(self):
222 z = dns.zone.from_text(example_text, 'example.', relativize=True)
223 rds = z.get_rdataset('@', 'loc')
224 self.failUnless(rds == None)
225
226 def testGetRRset1(self):
227 z = dns.zone.from_text(example_text, 'example.', relativize=True)
228 rrs = z.get_rrset('@', 'soa')
229 exrrs = dns.rrset.from_text('@', 300, 'IN', 'SOA', 'foo bar 1 2 3 4 5')
230 self.failUnless(rrs == exrrs)
231
232 def testGetRRset2(self):
233 z = dns.zone.from_text(example_text, 'example.', relativize=True)
234 rrs = z.get_rrset('@', 'loc')
235 self.failUnless(rrs == None)
236
237 def testReplaceRdataset1(self):
238 z = dns.zone.from_text(example_text, 'example.', relativize=True)
239 rdataset = dns.rdataset.from_text('in', 'ns', 300, 'ns3', 'ns4')
240 z.replace_rdataset('@', rdataset)
241 rds = z.get_rdataset('@', 'ns')
242 self.failUnless(rds is rdataset)
243
244 def testReplaceRdataset2(self):
245 z = dns.zone.from_text(example_text, 'example.', relativize=True)
246 rdataset = dns.rdataset.from_text('in', 'txt', 300, '"foo"')
247 z.replace_rdataset('@', rdataset)
248 rds = z.get_rdataset('@', 'txt')
249 self.failUnless(rds is rdataset)
250
251 def testDeleteRdataset1(self):
252 z = dns.zone.from_text(example_text, 'example.', relativize=True)
253 z.delete_rdataset('@', 'ns')
254 rds = z.get_rdataset('@', 'ns')
255 self.failUnless(rds is None)
256
257 def testDeleteRdataset2(self):
258 z = dns.zone.from_text(example_text, 'example.', relativize=True)
259 z.delete_rdataset('ns1', 'a')
260 node = z.get_node('ns1')
261 self.failUnless(node is None)
262
263 def testNodeFindRdataset1(self):
264 z = dns.zone.from_text(example_text, 'example.', relativize=True)
265 node = z['@']
266 rds = node.find_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
267 exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
268 self.failUnless(rds == exrds)
269
270 def testNodeFindRdataset2(self):
271 def bad():
272 z = dns.zone.from_text(example_text, 'example.', relativize=True)
273 node = z['@']
274 rds = node.find_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC)
275 self.failUnlessRaises(KeyError, bad)
276
277 def testNodeGetRdataset1(self):
278 z = dns.zone.from_text(example_text, 'example.', relativize=True)
279 node = z['@']
280 rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
281 exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
282 self.failUnless(rds == exrds)
283
284 def testNodeGetRdataset2(self):
285 z = dns.zone.from_text(example_text, 'example.', relativize=True)
286 node = z['@']
287 rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC)
288 self.failUnless(rds == None)
289
290 def testNodeDeleteRdataset1(self):
291 z = dns.zone.from_text(example_text, 'example.', relativize=True)
292 node = z['@']
293 rds = node.delete_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
294 rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
295 self.failUnless(rds == None)
296
297 def testNodeDeleteRdataset2(self):
298 z = dns.zone.from_text(example_text, 'example.', relativize=True)
299 node = z['@']
300 rds = node.delete_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC)
301 rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC)
302 self.failUnless(rds == None)
303
304 def testIterateRdatasets(self):
305 z = dns.zone.from_text(example_text, 'example.', relativize=True)
306 ns = [n for n, r in z.iterate_rdatasets('A')]
307 ns.sort()
308 self.failUnless(ns == [dns.name.from_text('ns1', None),
309 dns.name.from_text('ns2', None)])
310
311 def testIterateAllRdatasets(self):
312 z = dns.zone.from_text(example_text, 'example.', relativize=True)
313 ns = [n for n, r in z.iterate_rdatasets()]
314 ns.sort()
315 self.failUnless(ns == [dns.name.from_text('@', None),
316 dns.name.from_text('@', None),
317 dns.name.from_text('bar.foo', None),
318 dns.name.from_text('ns1', None),
319 dns.name.from_text('ns2', None)])
320
321 def testIterateRdatas(self):
322 z = dns.zone.from_text(example_text, 'example.', relativize=True)
323 l = list(z.iterate_rdatas('A'))
324 l.sort()
325 exl = [(dns.name.from_text('ns1', None),
326 3600,
327 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
328 '10.0.0.1')),
329 (dns.name.from_text('ns2', None),
330 3600,
331 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
332 '10.0.0.2'))]
333 self.failUnless(l == exl)
334
335 def testIterateAllRdatas(self):
336 z = dns.zone.from_text(example_text, 'example.', relativize=True)
337 l = list(z.iterate_rdatas())
338 l.sort()
339 exl = [(dns.name.from_text('@', None),
340 3600,
341 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
342 'ns1')),
343 (dns.name.from_text('@', None),
344 3600,
345 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
346 'ns2')),
347 (dns.name.from_text('@', None),
348 3600,
349 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
350 'foo bar 1 2 3 4 5')),
351 (dns.name.from_text('bar.foo', None),
352 300,
353 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
354 '0 blaz.foo')),
355 (dns.name.from_text('ns1', None),
356 3600,
357 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
358 '10.0.0.1')),
359 (dns.name.from_text('ns2', None),
360 3600,
361 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
362 '10.0.0.2'))]
363 self.failUnless(l == exl)
364
365 def testTTLs(self):
366 z = dns.zone.from_text(ttl_example_text, 'example.', relativize=True)
367 n = z['@']
368 rds = n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
369 self.failUnless(rds.ttl == 3600)
370 n = z['ns1']
371 rds = n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A)
372 self.failUnless(rds.ttl == 86401)
373 n = z['ns2']
374 rds = n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A)
375 self.failUnless(rds.ttl == 694861)
376
377 def testNoSOA(self):
378 def bad():
379 z = dns.zone.from_text(no_soa_text, 'example.',
380 relativize=True)
381 self.failUnlessRaises(dns.zone.NoSOA, bad)
382
383 def testNoNS(self):
384 def bad():
385 z = dns.zone.from_text(no_ns_text, 'example.',
386 relativize=True)
387 self.failUnlessRaises(dns.zone.NoNS, bad)
388
389 def testInclude(self):
390 z1 = dns.zone.from_text(include_text, 'example.', relativize=True,
391 allow_include=True)
392 z2 = dns.zone.from_file('example', 'example.', relativize=True)
393 self.failUnless(z1 == z2)
394
395 def testBadDirective(self):
396 def bad():
397 z = dns.zone.from_text(bad_directive_text, 'example.',
398 relativize=True)
399 self.failUnlessRaises(dns.exception.SyntaxError, bad)
400
401 def testFirstRRStartsWithWhitespace(self):
402 # no name is specified, so default to the intial origin
403 # no ttl is specified, so default to the initial TTL of 0
404 z = dns.zone.from_text(' IN A 10.0.0.1', origin='example.',
405 check_origin=False)
406 n = z['@']
407 rds = n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A)
408 self.failUnless(rds.ttl == 0)
409
410 if __name__ == '__main__':
411 unittest.main()
+0
-190
tests/tokenizer.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.exception
18 import dns.tokenizer
19
20 Token = dns.tokenizer.Token
21
22 class TokenizerTestCase(unittest.TestCase):
23
24 def testQuotedString1(self):
25 tok = dns.tokenizer.Tokenizer(r'"foo"')
26 token = tok.get()
27 self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, 'foo'))
28
29 def testQuotedString2(self):
30 tok = dns.tokenizer.Tokenizer(r'""')
31 token = tok.get()
32 self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, ''))
33
34 def testQuotedString3(self):
35 tok = dns.tokenizer.Tokenizer(r'"\"foo\""')
36 token = tok.get()
37 self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, '"foo"'))
38
39 def testQuotedString4(self):
40 tok = dns.tokenizer.Tokenizer(r'"foo\010bar"')
41 token = tok.get()
42 self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, 'foo\x0abar'))
43
44 def testQuotedString5(self):
45 def bad():
46 tok = dns.tokenizer.Tokenizer(r'"foo')
47 token = tok.get()
48 self.failUnlessRaises(dns.exception.UnexpectedEnd, bad)
49
50 def testQuotedString6(self):
51 def bad():
52 tok = dns.tokenizer.Tokenizer(r'"foo\01')
53 token = tok.get()
54 self.failUnlessRaises(dns.exception.SyntaxError, bad)
55
56 def testQuotedString7(self):
57 def bad():
58 tok = dns.tokenizer.Tokenizer('"foo\nbar"')
59 token = tok.get()
60 self.failUnlessRaises(dns.exception.SyntaxError, bad)
61
62 def testEmpty1(self):
63 tok = dns.tokenizer.Tokenizer('')
64 token = tok.get()
65 self.failUnless(token.is_eof())
66
67 def testEmpty2(self):
68 tok = dns.tokenizer.Tokenizer('')
69 token1 = tok.get()
70 token2 = tok.get()
71 self.failUnless(token1.is_eof() and token2.is_eof())
72
73 def testEOL(self):
74 tok = dns.tokenizer.Tokenizer('\n')
75 token1 = tok.get()
76 token2 = tok.get()
77 self.failUnless(token1.is_eol() and token2.is_eof())
78
79 def testWS1(self):
80 tok = dns.tokenizer.Tokenizer(' \n')
81 token1 = tok.get()
82 self.failUnless(token1.is_eol())
83
84 def testWS2(self):
85 tok = dns.tokenizer.Tokenizer(' \n')
86 token1 = tok.get(want_leading=True)
87 self.failUnless(token1.is_whitespace())
88
89 def testComment1(self):
90 tok = dns.tokenizer.Tokenizer(' ;foo\n')
91 token1 = tok.get()
92 self.failUnless(token1.is_eol())
93
94 def testComment2(self):
95 tok = dns.tokenizer.Tokenizer(' ;foo\n')
96 token1 = tok.get(want_comment = True)
97 token2 = tok.get()
98 self.failUnless(token1 == Token(dns.tokenizer.COMMENT, 'foo') and
99 token2.is_eol())
100
101 def testComment3(self):
102 tok = dns.tokenizer.Tokenizer(' ;foo bar\n')
103 token1 = tok.get(want_comment = True)
104 token2 = tok.get()
105 self.failUnless(token1 == Token(dns.tokenizer.COMMENT, 'foo bar') and
106 token2.is_eol())
107
108 def testMultiline1(self):
109 tok = dns.tokenizer.Tokenizer('( foo\n\n bar\n)')
110 tokens = list(iter(tok))
111 self.failUnless(tokens == [Token(dns.tokenizer.IDENTIFIER, 'foo'),
112 Token(dns.tokenizer.IDENTIFIER, 'bar')])
113
114 def testMultiline2(self):
115 tok = dns.tokenizer.Tokenizer('( foo\n\n bar\n)\n')
116 tokens = list(iter(tok))
117 self.failUnless(tokens == [Token(dns.tokenizer.IDENTIFIER, 'foo'),
118 Token(dns.tokenizer.IDENTIFIER, 'bar'),
119 Token(dns.tokenizer.EOL, '\n')])
120 def testMultiline3(self):
121 def bad():
122 tok = dns.tokenizer.Tokenizer('foo)')
123 tokens = list(iter(tok))
124 self.failUnlessRaises(dns.exception.SyntaxError, bad)
125
126 def testMultiline4(self):
127 def bad():
128 tok = dns.tokenizer.Tokenizer('((foo)')
129 tokens = list(iter(tok))
130 self.failUnlessRaises(dns.exception.SyntaxError, bad)
131
132 def testUnget1(self):
133 tok = dns.tokenizer.Tokenizer('foo')
134 t1 = tok.get()
135 tok.unget(t1)
136 t2 = tok.get()
137 self.failUnless(t1 == t2 and t1.ttype == dns.tokenizer.IDENTIFIER and \
138 t1.value == 'foo')
139
140 def testUnget2(self):
141 def bad():
142 tok = dns.tokenizer.Tokenizer('foo')
143 t1 = tok.get()
144 tok.unget(t1)
145 tok.unget(t1)
146 self.failUnlessRaises(dns.tokenizer.UngetBufferFull, bad)
147
148 def testGetEOL1(self):
149 tok = dns.tokenizer.Tokenizer('\n')
150 t = tok.get_eol()
151 self.failUnless(t == '\n')
152
153 def testGetEOL2(self):
154 tok = dns.tokenizer.Tokenizer('')
155 t = tok.get_eol()
156 self.failUnless(t == '')
157
158 def testEscapedDelimiter1(self):
159 tok = dns.tokenizer.Tokenizer(r'ch\ ld')
160 t = tok.get()
161 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\ ld')
162
163 def testEscapedDelimiter2(self):
164 tok = dns.tokenizer.Tokenizer(r'ch\032ld')
165 t = tok.get()
166 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\032ld')
167
168 def testEscapedDelimiter3(self):
169 tok = dns.tokenizer.Tokenizer(r'ch\ild')
170 t = tok.get()
171 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\ild')
172
173 def testEscapedDelimiter1u(self):
174 tok = dns.tokenizer.Tokenizer(r'ch\ ld')
175 t = tok.get().unescape()
176 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch ld')
177
178 def testEscapedDelimiter2u(self):
179 tok = dns.tokenizer.Tokenizer(r'ch\032ld')
180 t = tok.get().unescape()
181 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == 'ch ld')
182
183 def testEscapedDelimiter3u(self):
184 tok = dns.tokenizer.Tokenizer(r'ch\ild')
185 t = tok.get().unescape()
186 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'child')
187
188 if __name__ == '__main__':
189 unittest.main()
+0
-114
tests/update.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import unittest
16
17 import dns.update
18 import dns.rdata
19 import dns.rdataset
20
21 goodhex = '0001 2800 0001 0005 0007 0000' \
22 '076578616d706c6500 0006 0001' \
23 '03666f6fc00c 00ff 00ff 00000000 0000' \
24 'c019 0001 00ff 00000000 0000' \
25 '03626172c00c 0001 0001 00000000 0004 0a000005' \
26 '05626c617a32c00c 00ff 00fe 00000000 0000' \
27 'c049 0001 00fe 00000000 0000' \
28 'c019 0001 00ff 00000000 0000' \
29 'c019 0001 0001 0000012c 0004 0a000001' \
30 'c019 0001 0001 0000012c 0004 0a000002' \
31 'c035 0001 0001 0000012c 0004 0a000003' \
32 'c035 0001 00fe 00000000 0004 0a000004' \
33 '04626c617ac00c 0001 00ff 00000000 0000' \
34 'c049 00ff 00ff 00000000 0000'
35
36 goodwire = goodhex.replace(' ', '').decode('hex_codec')
37
38 update_text="""id 1
39 opcode UPDATE
40 rcode NOERROR
41 ;ZONE
42 example. IN SOA
43 ;PREREQ
44 foo ANY ANY
45 foo ANY A
46 bar 0 IN A 10.0.0.5
47 blaz2 NONE ANY
48 blaz2 NONE A
49 ;UPDATE
50 foo ANY A
51 foo 300 IN A 10.0.0.1
52 foo 300 IN A 10.0.0.2
53 bar 300 IN A 10.0.0.3
54 bar 0 NONE A 10.0.0.4
55 blaz ANY A
56 blaz2 ANY ANY
57 """
58
59 class UpdateTestCase(unittest.TestCase):
60
61 def test_to_wire1(self):
62 update = dns.update.Update('example')
63 update.id = 1
64 update.present('foo')
65 update.present('foo', 'a')
66 update.present('bar', 'a', '10.0.0.5')
67 update.absent('blaz2')
68 update.absent('blaz2', 'a')
69 update.replace('foo', 300, 'a', '10.0.0.1', '10.0.0.2')
70 update.add('bar', 300, 'a', '10.0.0.3')
71 update.delete('bar', 'a', '10.0.0.4')
72 update.delete('blaz','a')
73 update.delete('blaz2')
74 self.failUnless(update.to_wire() == goodwire)
75
76 def test_to_wire2(self):
77 update = dns.update.Update('example')
78 update.id = 1
79 update.present('foo')
80 update.present('foo', 'a')
81 update.present('bar', 'a', '10.0.0.5')
82 update.absent('blaz2')
83 update.absent('blaz2', 'a')
84 update.replace('foo', 300, 'a', '10.0.0.1', '10.0.0.2')
85 update.add('bar', 300, dns.rdata.from_text(1, 1, '10.0.0.3'))
86 update.delete('bar', 'a', '10.0.0.4')
87 update.delete('blaz','a')
88 update.delete('blaz2')
89 self.failUnless(update.to_wire() == goodwire)
90
91 def test_to_wire3(self):
92 update = dns.update.Update('example')
93 update.id = 1
94 update.present('foo')
95 update.present('foo', 'a')
96 update.present('bar', 'a', '10.0.0.5')
97 update.absent('blaz2')
98 update.absent('blaz2', 'a')
99 update.replace('foo', 300, 'a', '10.0.0.1', '10.0.0.2')
100 update.add('bar', dns.rdataset.from_text(1, 1, 300, '10.0.0.3'))
101 update.delete('bar', 'a', '10.0.0.4')
102 update.delete('blaz','a')
103 update.delete('blaz2')
104 self.failUnless(update.to_wire() == goodwire)
105
106 def test_from_text1(self):
107 update = dns.message.from_text(update_text)
108 w = update.to_wire(origin=dns.name.from_text('example'),
109 want_shuffle=False)
110 self.failUnless(w == goodwire)
111
112 if __name__ == '__main__':
113 unittest.main()
0 import os.path
1 import sys
2 import unittest
3
4 if __name__ == '__main__':
5 sys.path.insert(0, os.path.realpath('..'))
6 suites = unittest.defaultTestLoader.discover('.')
7 unittest.TextTestRunner(verbosity=2).run(suites)
+0
-389
tests/zone.py less more
0 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
1 #
2 # Permission to use, copy, modify, and distribute this software and its
3 # documentation for any purpose with or without fee is hereby granted,
4 # provided that the above copyright notice and this permission notice
5 # appear in all copies.
6 #
7 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 import cStringIO
16 import filecmp
17 import os
18 import unittest
19
20 import dns.exception
21 import dns.rdata
22 import dns.rdataclass
23 import dns.rdatatype
24 import dns.rrset
25 import dns.zone
26
27 example_text = """$TTL 3600
28 $ORIGIN example.
29 @ soa foo bar 1 2 3 4 5
30 @ ns ns1
31 @ ns ns2
32 ns1 a 10.0.0.1
33 ns2 a 10.0.0.2
34 $TTL 300
35 $ORIGIN foo.example.
36 bar mx 0 blaz
37 """
38
39 example_text_output = """@ 3600 IN SOA foo bar 1 2 3 4 5
40 @ 3600 IN NS ns1
41 @ 3600 IN NS ns2
42 bar.foo 300 IN MX 0 blaz.foo
43 ns1 3600 IN A 10.0.0.1
44 ns2 3600 IN A 10.0.0.2
45 """
46
47 something_quite_similar = """@ 3600 IN SOA foo bar 1 2 3 4 5
48 @ 3600 IN NS ns1
49 @ 3600 IN NS ns2
50 bar.foo 300 IN MX 0 blaz.foo
51 ns1 3600 IN A 10.0.0.1
52 ns2 3600 IN A 10.0.0.3
53 """
54
55 something_different = """@ 3600 IN SOA fooa bar 1 2 3 4 5
56 @ 3600 IN NS ns11
57 @ 3600 IN NS ns21
58 bar.fooa 300 IN MX 0 blaz.fooa
59 ns11 3600 IN A 10.0.0.11
60 ns21 3600 IN A 10.0.0.21
61 """
62
63 ttl_example_text = """$TTL 1h
64 $ORIGIN example.
65 @ soa foo bar 1 2 3 4 5
66 @ ns ns1
67 @ ns ns2
68 ns1 1d1s a 10.0.0.1
69 ns2 1w1D1h1m1S a 10.0.0.2
70 """
71
72 no_soa_text = """$TTL 1h
73 $ORIGIN example.
74 @ ns ns1
75 @ ns ns2
76 ns1 1d1s a 10.0.0.1
77 ns2 1w1D1h1m1S a 10.0.0.2
78 """
79
80 no_ns_text = """$TTL 1h
81 $ORIGIN example.
82 @ soa foo bar 1 2 3 4 5
83 """
84
85 include_text = """$INCLUDE "example"
86 """
87
88 bad_directive_text = """$FOO bar
89 $ORIGIN example.
90 @ soa foo bar 1 2 3 4 5
91 @ ns ns1
92 @ ns ns2
93 ns1 1d1s a 10.0.0.1
94 ns2 1w1D1h1m1S a 10.0.0.2
95 """
96
97 _keep_output = False
98
99 class ZoneTestCase(unittest.TestCase):
100
101 def testFromFile1(self):
102 z = dns.zone.from_file('example', 'example')
103 ok = False
104 try:
105 z.to_file('example1.out', nl='\x0a')
106 ok = filecmp.cmp('example1.out', 'example1.good')
107 finally:
108 if not _keep_output:
109 os.unlink('example1.out')
110 self.failUnless(ok)
111
112 def testFromFile2(self):
113 z = dns.zone.from_file('example', 'example', relativize=False)
114 ok = False
115 try:
116 z.to_file('example2.out', relativize=False, nl='\x0a')
117 ok = filecmp.cmp('example2.out', 'example2.good')
118 finally:
119 if not _keep_output:
120 os.unlink('example2.out')
121 self.failUnless(ok)
122
123 def testFromText(self):
124 z = dns.zone.from_text(example_text, 'example.', relativize=True)
125 f = cStringIO.StringIO()
126 names = z.nodes.keys()
127 names.sort()
128 for n in names:
129 print >> f, z[n].to_text(n)
130 self.failUnless(f.getvalue() == example_text_output)
131
132 def testTorture1(self):
133 #
134 # Read a zone containing all our supported RR types, and
135 # for each RR in the zone, convert the rdata into wire format
136 # and then back out, and see if we get equal rdatas.
137 #
138 f = cStringIO.StringIO()
139 o = dns.name.from_text('example.')
140 z = dns.zone.from_file('example', o)
141 for (name, node) in z.iteritems():
142 for rds in node:
143 for rd in rds:
144 f.seek(0)
145 f.truncate()
146 rd.to_wire(f, origin=o)
147 wire = f.getvalue()
148 rd2 = dns.rdata.from_wire(rds.rdclass, rds.rdtype,
149 wire, 0, len(wire),
150 origin = o)
151 self.failUnless(rd == rd2)
152
153 def testEqual(self):
154 z1 = dns.zone.from_text(example_text, 'example.', relativize=True)
155 z2 = dns.zone.from_text(example_text_output, 'example.',
156 relativize=True)
157 self.failUnless(z1 == z2)
158
159 def testNotEqual1(self):
160 z1 = dns.zone.from_text(example_text, 'example.', relativize=True)
161 z2 = dns.zone.from_text(something_quite_similar, 'example.',
162 relativize=True)
163 self.failUnless(z1 != z2)
164
165 def testNotEqual2(self):
166 z1 = dns.zone.from_text(example_text, 'example.', relativize=True)
167 z2 = dns.zone.from_text(something_different, 'example.',
168 relativize=True)
169 self.failUnless(z1 != z2)
170
171 def testNotEqual3(self):
172 z1 = dns.zone.from_text(example_text, 'example.', relativize=True)
173 z2 = dns.zone.from_text(something_different, 'example2.',
174 relativize=True)
175 self.failUnless(z1 != z2)
176
177 def testFindRdataset1(self):
178 z = dns.zone.from_text(example_text, 'example.', relativize=True)
179 rds = z.find_rdataset('@', 'soa')
180 exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
181 self.failUnless(rds == exrds)
182
183 def testFindRdataset2(self):
184 def bad():
185 z = dns.zone.from_text(example_text, 'example.', relativize=True)
186 rds = z.find_rdataset('@', 'loc')
187 self.failUnlessRaises(KeyError, bad)
188
189 def testFindRRset1(self):
190 z = dns.zone.from_text(example_text, 'example.', relativize=True)
191 rrs = z.find_rrset('@', 'soa')
192 exrrs = dns.rrset.from_text('@', 300, 'IN', 'SOA', 'foo bar 1 2 3 4 5')
193 self.failUnless(rrs == exrrs)
194
195 def testFindRRset2(self):
196 def bad():
197 z = dns.zone.from_text(example_text, 'example.', relativize=True)
198 rrs = z.find_rrset('@', 'loc')
199 self.failUnlessRaises(KeyError, bad)
200
201 def testGetRdataset1(self):
202 z = dns.zone.from_text(example_text, 'example.', relativize=True)
203 rds = z.get_rdataset('@', 'soa')
204 exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
205 self.failUnless(rds == exrds)
206
207 def testGetRdataset2(self):
208 z = dns.zone.from_text(example_text, 'example.', relativize=True)
209 rds = z.get_rdataset('@', 'loc')
210 self.failUnless(rds == None)
211
212 def testGetRRset1(self):
213 z = dns.zone.from_text(example_text, 'example.', relativize=True)
214 rrs = z.get_rrset('@', 'soa')
215 exrrs = dns.rrset.from_text('@', 300, 'IN', 'SOA', 'foo bar 1 2 3 4 5')
216 self.failUnless(rrs == exrrs)
217
218 def testGetRRset2(self):
219 z = dns.zone.from_text(example_text, 'example.', relativize=True)
220 rrs = z.get_rrset('@', 'loc')
221 self.failUnless(rrs == None)
222
223 def testReplaceRdataset1(self):
224 z = dns.zone.from_text(example_text, 'example.', relativize=True)
225 rdataset = dns.rdataset.from_text('in', 'ns', 300, 'ns3', 'ns4')
226 z.replace_rdataset('@', rdataset)
227 rds = z.get_rdataset('@', 'ns')
228 self.failUnless(rds is rdataset)
229
230 def testReplaceRdataset2(self):
231 z = dns.zone.from_text(example_text, 'example.', relativize=True)
232 rdataset = dns.rdataset.from_text('in', 'txt', 300, '"foo"')
233 z.replace_rdataset('@', rdataset)
234 rds = z.get_rdataset('@', 'txt')
235 self.failUnless(rds is rdataset)
236
237 def testDeleteRdataset1(self):
238 z = dns.zone.from_text(example_text, 'example.', relativize=True)
239 z.delete_rdataset('@', 'ns')
240 rds = z.get_rdataset('@', 'ns')
241 self.failUnless(rds is None)
242
243 def testDeleteRdataset2(self):
244 z = dns.zone.from_text(example_text, 'example.', relativize=True)
245 z.delete_rdataset('ns1', 'a')
246 node = z.get_node('ns1')
247 self.failUnless(node is None)
248
249 def testNodeFindRdataset1(self):
250 z = dns.zone.from_text(example_text, 'example.', relativize=True)
251 node = z['@']
252 rds = node.find_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
253 exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
254 self.failUnless(rds == exrds)
255
256 def testNodeFindRdataset2(self):
257 def bad():
258 z = dns.zone.from_text(example_text, 'example.', relativize=True)
259 node = z['@']
260 rds = node.find_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC)
261 self.failUnlessRaises(KeyError, bad)
262
263 def testNodeGetRdataset1(self):
264 z = dns.zone.from_text(example_text, 'example.', relativize=True)
265 node = z['@']
266 rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
267 exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
268 self.failUnless(rds == exrds)
269
270 def testNodeGetRdataset2(self):
271 z = dns.zone.from_text(example_text, 'example.', relativize=True)
272 node = z['@']
273 rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC)
274 self.failUnless(rds == None)
275
276 def testNodeDeleteRdataset1(self):
277 z = dns.zone.from_text(example_text, 'example.', relativize=True)
278 node = z['@']
279 rds = node.delete_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
280 rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
281 self.failUnless(rds == None)
282
283 def testNodeDeleteRdataset2(self):
284 z = dns.zone.from_text(example_text, 'example.', relativize=True)
285 node = z['@']
286 rds = node.delete_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC)
287 rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC)
288 self.failUnless(rds == None)
289
290 def testIterateRdatasets(self):
291 z = dns.zone.from_text(example_text, 'example.', relativize=True)
292 ns = [n for n, r in z.iterate_rdatasets('A')]
293 ns.sort()
294 self.failUnless(ns == [dns.name.from_text('ns1', None),
295 dns.name.from_text('ns2', None)])
296
297 def testIterateAllRdatasets(self):
298 z = dns.zone.from_text(example_text, 'example.', relativize=True)
299 ns = [n for n, r in z.iterate_rdatasets()]
300 ns.sort()
301 self.failUnless(ns == [dns.name.from_text('@', None),
302 dns.name.from_text('@', None),
303 dns.name.from_text('bar.foo', None),
304 dns.name.from_text('ns1', None),
305 dns.name.from_text('ns2', None)])
306
307 def testIterateRdatas(self):
308 z = dns.zone.from_text(example_text, 'example.', relativize=True)
309 l = list(z.iterate_rdatas('A'))
310 l.sort()
311 exl = [(dns.name.from_text('ns1', None),
312 3600,
313 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
314 '10.0.0.1')),
315 (dns.name.from_text('ns2', None),
316 3600,
317 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
318 '10.0.0.2'))]
319 self.failUnless(l == exl)
320
321 def testIterateAllRdatas(self):
322 z = dns.zone.from_text(example_text, 'example.', relativize=True)
323 l = list(z.iterate_rdatas())
324 l.sort()
325 exl = [(dns.name.from_text('@', None),
326 3600,
327 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
328 'ns1')),
329 (dns.name.from_text('@', None),
330 3600,
331 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
332 'ns2')),
333 (dns.name.from_text('@', None),
334 3600,
335 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
336 'foo bar 1 2 3 4 5')),
337 (dns.name.from_text('bar.foo', None),
338 300,
339 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
340 '0 blaz.foo')),
341 (dns.name.from_text('ns1', None),
342 3600,
343 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
344 '10.0.0.1')),
345 (dns.name.from_text('ns2', None),
346 3600,
347 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
348 '10.0.0.2'))]
349 self.failUnless(l == exl)
350
351 def testTTLs(self):
352 z = dns.zone.from_text(ttl_example_text, 'example.', relativize=True)
353 n = z['@']
354 rds = n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
355 self.failUnless(rds.ttl == 3600)
356 n = z['ns1']
357 rds = n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A)
358 self.failUnless(rds.ttl == 86401)
359 n = z['ns2']
360 rds = n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A)
361 self.failUnless(rds.ttl == 694861)
362
363 def testNoSOA(self):
364 def bad():
365 z = dns.zone.from_text(no_soa_text, 'example.',
366 relativize=True)
367 self.failUnlessRaises(dns.zone.NoSOA, bad)
368
369 def testNoNS(self):
370 def bad():
371 z = dns.zone.from_text(no_ns_text, 'example.',
372 relativize=True)
373 self.failUnlessRaises(dns.zone.NoNS, bad)
374
375 def testInclude(self):
376 z1 = dns.zone.from_text(include_text, 'example.', relativize=True,
377 allow_include=True)
378 z2 = dns.zone.from_file('example', 'example.', relativize=True)
379 self.failUnless(z1 == z2)
380
381 def testBadDirective(self):
382 def bad():
383 z = dns.zone.from_text(bad_directive_text, 'example.',
384 relativize=True)
385 self.failUnlessRaises(dns.exception.SyntaxError, bad)
386
387 if __name__ == '__main__':
388 unittest.main()