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__':