1 # Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
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.
8 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM 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.
28 example_text
= """$TTL 3600
30 @ soa foo bar 1 2 3 4 5
40 example_text_output
= """@ 3600 IN SOA foo bar 1 2 3 4 5
43 bar.foo 300 IN MX 0 blaz.foo
44 ns1 3600 IN A 10.0.0.1
45 ns2 3600 IN A 10.0.0.2
48 something_quite_similar
= """@ 3600 IN SOA foo bar 1 2 3 4 5
51 bar.foo 300 IN MX 0 blaz.foo
52 ns1 3600 IN A 10.0.0.1
53 ns2 3600 IN A 10.0.0.3
56 something_different
= """@ 3600 IN SOA fooa bar 1 2 3 4 5
59 bar.fooa 300 IN MX 0 blaz.fooa
60 ns11 3600 IN A 10.0.0.11
61 ns21 3600 IN A 10.0.0.21
64 ttl_example_text
= """$TTL 1h
66 @ soa foo bar 1 2 3 4 5
70 ns2 1w1D1h1m1S a 10.0.0.2
73 no_soa_text
= """$TTL 1h
78 ns2 1w1D1h1m1S a 10.0.0.2
81 no_ns_text
= """$TTL 1h
83 @ soa foo bar 1 2 3 4 5
86 include_text
= """$INCLUDE "example"
89 bad_directive_text
= """$FOO bar
91 @ soa foo bar 1 2 3 4 5
95 ns2 1w1D1h1m1S a 10.0.0.2
100 class ZoneTestCase(unittest
.TestCase
):
102 def testFromFile1(self
):
103 z
= dns
.zone
.from_file('example', 'example')
106 z
.to_file('example1.out', nl
='\x0a')
107 ok
= filecmp
.cmp('example1.out', 'example1.good')
110 os
.unlink('example1.out')
113 def testFromFile2(self
):
114 z
= dns
.zone
.from_file('example', 'example', relativize
=False)
117 z
.to_file('example2.out', relativize
=False, nl
='\x0a')
118 ok
= filecmp
.cmp('example2.out', 'example2.good')
121 os
.unlink('example2.out')
124 def testFromText(self
):
125 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
126 f
= cStringIO
.StringIO()
127 names
= z
.nodes
.keys()
130 print >> f
, z
[n
].to_text(n
)
131 self
.failUnless(f
.getvalue() == example_text_output
)
133 def testTorture1(self
):
135 # Read a zone containing all our supported RR types, and
136 # for each RR in the zone, convert the rdata into wire format
137 # and then back out, and see if we get equal rdatas.
139 f
= cStringIO
.StringIO()
140 o
= dns
.name
.from_text('example.')
141 z
= dns
.zone
.from_file('example', o
)
142 for (name
, node
) in z
.iteritems():
147 rd
.to_wire(f
, origin
=o
)
149 rd2
= dns
.rdata
.from_wire(rds
.rdclass
, rds
.rdtype
,
152 self
.failUnless(rd
== rd2
)
155 z1
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
156 z2
= dns
.zone
.from_text(example_text_output
, 'example.',
158 self
.failUnless(z1
== z2
)
160 def testNotEqual1(self
):
161 z1
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
162 z2
= dns
.zone
.from_text(something_quite_similar
, 'example.',
164 self
.failUnless(z1
!= z2
)
166 def testNotEqual2(self
):
167 z1
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
168 z2
= dns
.zone
.from_text(something_different
, 'example.',
170 self
.failUnless(z1
!= z2
)
172 def testNotEqual3(self
):
173 z1
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
174 z2
= dns
.zone
.from_text(something_different
, 'example2.',
176 self
.failUnless(z1
!= z2
)
178 def testFindRdataset1(self
):
179 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
180 rds
= z
.find_rdataset('@', 'soa')
181 exrds
= dns
.rdataset
.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
182 self
.failUnless(rds
== exrds
)
184 def testFindRdataset2(self
):
186 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
187 rds
= z
.find_rdataset('@', 'loc')
188 self
.failUnlessRaises(KeyError, bad
)
190 def testFindRRset1(self
):
191 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
192 rrs
= z
.find_rrset('@', 'soa')
193 exrrs
= dns
.rrset
.from_text('@', 300, 'IN', 'SOA', 'foo bar 1 2 3 4 5')
194 self
.failUnless(rrs
== exrrs
)
196 def testFindRRset2(self
):
198 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
199 rrs
= z
.find_rrset('@', 'loc')
200 self
.failUnlessRaises(KeyError, bad
)
202 def testGetRdataset1(self
):
203 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
204 rds
= z
.get_rdataset('@', 'soa')
205 exrds
= dns
.rdataset
.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
206 self
.failUnless(rds
== exrds
)
208 def testGetRdataset2(self
):
209 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
210 rds
= z
.get_rdataset('@', 'loc')
211 self
.failUnless(rds
== None)
213 def testGetRRset1(self
):
214 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
215 rrs
= z
.get_rrset('@', 'soa')
216 exrrs
= dns
.rrset
.from_text('@', 300, 'IN', 'SOA', 'foo bar 1 2 3 4 5')
217 self
.failUnless(rrs
== exrrs
)
219 def testGetRRset2(self
):
220 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
221 rrs
= z
.get_rrset('@', 'loc')
222 self
.failUnless(rrs
== None)
224 def testReplaceRdataset1(self
):
225 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
226 rdataset
= dns
.rdataset
.from_text('in', 'ns', 300, 'ns3', 'ns4')
227 z
.replace_rdataset('@', rdataset
)
228 rds
= z
.get_rdataset('@', 'ns')
229 self
.failUnless(rds
is rdataset
)
231 def testReplaceRdataset2(self
):
232 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
233 rdataset
= dns
.rdataset
.from_text('in', 'txt', 300, '"foo"')
234 z
.replace_rdataset('@', rdataset
)
235 rds
= z
.get_rdataset('@', 'txt')
236 self
.failUnless(rds
is rdataset
)
238 def testDeleteRdataset1(self
):
239 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
240 z
.delete_rdataset('@', 'ns')
241 rds
= z
.get_rdataset('@', 'ns')
242 self
.failUnless(rds
is None)
244 def testDeleteRdataset2(self
):
245 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
246 z
.delete_rdataset('ns1', 'a')
247 node
= z
.get_node('ns1')
248 self
.failUnless(node
is None)
250 def testNodeFindRdataset1(self
):
251 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
253 rds
= node
.find_rdataset(dns
.rdataclass
.IN
, dns
.rdatatype
.SOA
)
254 exrds
= dns
.rdataset
.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
255 self
.failUnless(rds
== exrds
)
257 def testNodeFindRdataset2(self
):
259 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
261 rds
= node
.find_rdataset(dns
.rdataclass
.IN
, dns
.rdatatype
.LOC
)
262 self
.failUnlessRaises(KeyError, bad
)
264 def testNodeGetRdataset1(self
):
265 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
267 rds
= node
.get_rdataset(dns
.rdataclass
.IN
, dns
.rdatatype
.SOA
)
268 exrds
= dns
.rdataset
.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
269 self
.failUnless(rds
== exrds
)
271 def testNodeGetRdataset2(self
):
272 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
274 rds
= node
.get_rdataset(dns
.rdataclass
.IN
, dns
.rdatatype
.LOC
)
275 self
.failUnless(rds
== None)
277 def testNodeDeleteRdataset1(self
):
278 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
280 rds
= node
.delete_rdataset(dns
.rdataclass
.IN
, dns
.rdatatype
.SOA
)
281 rds
= node
.get_rdataset(dns
.rdataclass
.IN
, dns
.rdatatype
.SOA
)
282 self
.failUnless(rds
== None)
284 def testNodeDeleteRdataset2(self
):
285 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
287 rds
= node
.delete_rdataset(dns
.rdataclass
.IN
, dns
.rdatatype
.LOC
)
288 rds
= node
.get_rdataset(dns
.rdataclass
.IN
, dns
.rdatatype
.LOC
)
289 self
.failUnless(rds
== None)
291 def testIterateRdatasets(self
):
292 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
293 ns
= [n
for n
, r
in z
.iterate_rdatasets('A')]
295 self
.failUnless(ns
== [dns
.name
.from_text('ns1', None),
296 dns
.name
.from_text('ns2', None)])
298 def testIterateAllRdatasets(self
):
299 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
300 ns
= [n
for n
, r
in z
.iterate_rdatasets()]
302 self
.failUnless(ns
== [dns
.name
.from_text('@', None),
303 dns
.name
.from_text('@', None),
304 dns
.name
.from_text('bar.foo', None),
305 dns
.name
.from_text('ns1', None),
306 dns
.name
.from_text('ns2', None)])
308 def testIterateRdatas(self
):
309 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
310 l
= list(z
.iterate_rdatas('A'))
312 exl
= [(dns
.name
.from_text('ns1', None),
314 dns
.rdata
.from_text(dns
.rdataclass
.IN
, dns
.rdatatype
.A
,
316 (dns
.name
.from_text('ns2', None),
318 dns
.rdata
.from_text(dns
.rdataclass
.IN
, dns
.rdatatype
.A
,
320 self
.failUnless(l
== exl
)
322 def testIterateAllRdatas(self
):
323 z
= dns
.zone
.from_text(example_text
, 'example.', relativize
=True)
324 l
= list(z
.iterate_rdatas())
326 exl
= [(dns
.name
.from_text('@', None),
328 dns
.rdata
.from_text(dns
.rdataclass
.IN
, dns
.rdatatype
.NS
,
330 (dns
.name
.from_text('@', None),
332 dns
.rdata
.from_text(dns
.rdataclass
.IN
, dns
.rdatatype
.NS
,
334 (dns
.name
.from_text('@', None),
336 dns
.rdata
.from_text(dns
.rdataclass
.IN
, dns
.rdatatype
.SOA
,
337 'foo bar 1 2 3 4 5')),
338 (dns
.name
.from_text('bar.foo', None),
340 dns
.rdata
.from_text(dns
.rdataclass
.IN
, dns
.rdatatype
.MX
,
342 (dns
.name
.from_text('ns1', None),
344 dns
.rdata
.from_text(dns
.rdataclass
.IN
, dns
.rdatatype
.A
,
346 (dns
.name
.from_text('ns2', None),
348 dns
.rdata
.from_text(dns
.rdataclass
.IN
, dns
.rdatatype
.A
,
350 self
.failUnless(l
== exl
)
353 z
= dns
.zone
.from_text(ttl_example_text
, 'example.', relativize
=True)
355 rds
= n
.get_rdataset(dns
.rdataclass
.IN
, dns
.rdatatype
.SOA
)
356 self
.failUnless(rds
.ttl
== 3600)
358 rds
= n
.get_rdataset(dns
.rdataclass
.IN
, dns
.rdatatype
.A
)
359 self
.failUnless(rds
.ttl
== 86401)
361 rds
= n
.get_rdataset(dns
.rdataclass
.IN
, dns
.rdatatype
.A
)
362 self
.failUnless(rds
.ttl
== 694861)
366 z
= dns
.zone
.from_text(no_soa_text
, 'example.',
368 self
.failUnlessRaises(dns
.zone
.NoSOA
, bad
)
372 z
= dns
.zone
.from_text(no_ns_text
, 'example.',
374 self
.failUnlessRaises(dns
.zone
.NoNS
, bad
)
376 def testInclude(self
):
377 z1
= dns
.zone
.from_text(include_text
, 'example.', relativize
=True,
379 z2
= dns
.zone
.from_file('example', 'example.', relativize
=True)
380 self
.failUnless(z1
== z2
)
382 def testBadDirective(self
):
384 z
= dns
.zone
.from_text(bad_directive_text
, 'example.',
386 self
.failUnlessRaises(dns
.exception
.SyntaxError, bad
)
388 if __name__
== '__main__':