1# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license 2 3# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 4# 5# Permission to use, copy, modify, and distribute this software and its 6# documentation for any purpose with or without fee is hereby granted, 7# provided that the above copyright notice and this permission notice 8# appear in all copies. 9# 10# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 16# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 18import sys 19sys.path.insert(0, '../') # Force the local project to be *the* dns 20 21import unittest 22 23import dns.exception 24import dns.rdata 25import dns.rdataclass 26import dns.rdatatype 27import dns.rrset 28import dns.zone 29from dns._compat import long 30 31import pprint 32 33 34pp = pprint.PrettyPrinter(indent=2) 35 36example_text = """$TTL 1h 37$ORIGIN 0.0.192.IN-ADDR.ARPA. 38$GENERATE 1-2 0 CNAME SERVER$.EXAMPLE. 39""" 40 41example_text1 = """$TTL 1h 42$ORIGIN 0.0.192.IN-ADDR.ARPA. 43$GENERATE 1-10 fooo$ CNAME $.0 44""" 45 46example_text2 = """$TTL 1h 47@ 3600 IN SOA foo bar 1 2 3 4 5 48@ 3600 IN NS ns1 49@ 3600 IN NS ns2 50bar.foo 300 IN MX 0 blaz.foo 51ns1 3600 IN A 10.0.0.1 52ns2 3600 IN A 10.0.0.2 53$GENERATE 3-5 foo$ A 10.0.0.$ 54""" 55 56example_text3 = """$TTL 1h 57@ 3600 IN SOA foo bar 1 2 3 4 5 58@ 3600 IN NS ns1 59@ 3600 IN NS ns2 60bar.foo 300 IN MX 0 blaz.foo 61ns1 3600 IN A 10.0.0.1 62ns2 3600 IN A 10.0.0.2 63$GENERATE 4-8/2 foo$ A 10.0.0.$ 64""" 65 66example_text4 = """$TTL 1h 67@ 3600 IN SOA foo bar 1 2 3 4 5 68@ 3600 IN NS ns1 69@ 3600 IN NS ns2 70bar.foo 300 IN MX 0 blaz.foo 71ns1 3600 IN A 10.0.0.1 72ns2 3600 IN A 10.0.0.2 73$GENERATE 11-13 wp-db${-10,2,d}.services.mozilla.com 0 CNAME SERVER.FOOBAR. 74""" 75 76example_text5 = """$TTL 1h 77@ 3600 IN SOA foo bar 1 2 3 4 5 78@ 3600 IN NS ns1 79@ 3600 IN NS ns2 80bar.foo 300 IN MX 0 blaz.foo 81ns1 3600 IN A 10.0.0.1 82ns2 3600 IN A 10.0.0.2 83$GENERATE 11-13 wp-db${10,2,d}.services.mozilla.com 0 CNAME SERVER.FOOBAR. 84""" 85 86example_text6 = """$TTL 1h 87@ 3600 IN SOA foo bar 1 2 3 4 5 88@ 3600 IN NS ns1 89@ 3600 IN NS ns2 90bar.foo 300 IN MX 0 blaz.foo 91ns1 3600 IN A 10.0.0.1 92ns2 3600 IN A 10.0.0.2 93$GENERATE 11-13 wp-db${+10,2,d}.services.mozilla.com 0 CNAME SERVER.FOOBAR. 94""" 95 96example_text7 = """$TTL 1h 97@ 3600 IN SOA foo bar 1 2 3 4 5 98@ 3600 IN NS ns1 99@ 3600 IN NS ns2 100bar.foo 300 IN MX 0 blaz.foo 101ns1 3600 IN A 10.0.0.1 102ns2 3600 IN A 10.0.0.2 103$GENERATE 11-13 sync${-10}.db IN A 10.10.16.0 104""" 105 106example_text8 = """$TTL 1h 107@ 3600 IN SOA foo bar 1 2 3 4 5 108@ 3600 IN NS ns1 109@ 3600 IN NS ns2 110bar.foo 300 IN MX 0 blaz.foo 111ns1 3600 IN A 10.0.0.1 112ns2 3600 IN A 10.0.0.2 113$GENERATE 11-12 wp-db${-10,2,d} IN A 10.10.16.0 114""" 115 116example_text9 = """$TTL 1h 117@ 3600 IN SOA foo bar 1 2 3 4 5 118@ 3600 IN NS ns1 119@ 3600 IN NS ns2 120bar.foo 300 IN MX 0 blaz.foo 121ns1 3600 IN A 10.0.0.1 122ns2 3600 IN A 10.0.0.2 123$GENERATE 11-12 wp-db${-10,2,d} IN A 10.10.16.0 124$GENERATE 11-13 sync${-10}.db IN A 10.10.16.0 125""" 126example_text10 = """$TTL 1h 127@ 3600 IN SOA foo bar 1 2 3 4 5 128@ 3600 IN NS ns1 129@ 3600 IN NS ns2 130bar.foo 300 IN MX 0 blaz.foo 131ns1 3600 IN A 10.0.0.1 132ns2 3600 IN A 10.0.0.2 133$GENERATE 27-28 $.2 PTR zlb${-26}.oob 134""" 135 136def _rdata_sort(a): 137 return (a[0], a[2].rdclass, a[2].to_text()) 138 139 140class GenerateTestCase(unittest.TestCase): 141 142 def testFromText(self): # type: () -> None 143 def bad(): # type: () -> None 144 dns.zone.from_text(example_text, 'example.', relativize=True) 145 self.failUnlessRaises(dns.zone.NoSOA, bad) 146 147 def testFromText1(self): # type: () -> None 148 def bad(): # type: () -> None 149 dns.zone.from_text(example_text1, 'example.', relativize=True) 150 self.failUnlessRaises(dns.zone.NoSOA, bad) 151 152 def testIterateAllRdatas2(self): # type: () -> None 153 z = dns.zone.from_text(example_text2, 'example.', relativize=True) 154 l = list(z.iterate_rdatas()) 155 l.sort(key=_rdata_sort) 156 exl = [(dns.name.from_text('@', None), 157 3600, 158 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 159 'ns1')), 160 (dns.name.from_text('@', None), 161 3600, 162 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 163 'ns2')), 164 (dns.name.from_text('@', None), 165 3600, 166 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 167 'foo bar 1 2 3 4 5')), 168 (dns.name.from_text('bar.foo', None), 169 300, 170 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, 171 '0 blaz.foo')), 172 (dns.name.from_text('ns1', None), 173 3600, 174 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 175 '10.0.0.1')), 176 (dns.name.from_text('ns2', None), 177 3600, 178 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 179 '10.0.0.2')), 180 (dns.name.from_text('foo3', None), 181 3600, 182 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 183 '10.0.0.3')), 184 (dns.name.from_text('foo4', None), 185 3600, 186 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 187 '10.0.0.4')), 188 (dns.name.from_text('foo5', None), 189 3600, 190 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 191 '10.0.0.5'))] 192 193 exl.sort(key=_rdata_sort) 194 self.failUnless(l == exl) 195 196 def testIterateAllRdatas3(self): # type: () -> None 197 z = dns.zone.from_text(example_text3, 'example.', relativize=True) 198 l = list(z.iterate_rdatas()) 199 l.sort(key=_rdata_sort) 200 exl = [(dns.name.from_text('@', None), 201 3600, 202 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 203 'ns1')), 204 (dns.name.from_text('@', None), 205 3600, 206 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 207 'ns2')), 208 (dns.name.from_text('@', None), 209 3600, 210 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 211 'foo bar 1 2 3 4 5')), 212 (dns.name.from_text('bar.foo', None), 213 300, 214 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, 215 '0 blaz.foo')), 216 (dns.name.from_text('ns1', None), 217 3600, 218 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 219 '10.0.0.1')), 220 (dns.name.from_text('ns2', None), 221 3600, 222 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 223 '10.0.0.2')), 224 (dns.name.from_text('foo4', None), 3600, 225 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 226 '10.0.0.4')), 227 (dns.name.from_text('foo6', None), 3600, 228 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 229 '10.0.0.6')), 230 (dns.name.from_text('foo8', None), 3600, 231 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 232 '10.0.0.8'))] 233 exl.sort(key=_rdata_sort) 234 self.failUnless(l == exl) 235 def testGenerate1(self): # type: () -> None 236 z = dns.zone.from_text(example_text4, 'example.', relativize=True) 237 l = list(z.iterate_rdatas()) 238 l.sort(key=_rdata_sort) 239 exl = [(dns.name.from_text('@', None), 240 long(3600), 241 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 242 'ns1')), 243 (dns.name.from_text('@', None), 244 long(3600), 245 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 246 'ns2')), 247 (dns.name.from_text('@', None), 248 long(3600), 249 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 250 'foo bar 1 2 3 4 5')), 251 (dns.name.from_text('bar.foo', None), 252 long(300), 253 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, 254 '0 blaz.foo')), 255 (dns.name.from_text('ns1', None), 256 long(3600), 257 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 258 '10.0.0.1')), 259 (dns.name.from_text('ns2', None), 260 long(3600), 261 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 262 '10.0.0.2')), 263 264 (dns.name.from_text('wp-db01.services.mozilla.com', None), 265 long(0), 266 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 267 'SERVER.FOOBAR.')), 268 269 (dns.name.from_text('wp-db02.services.mozilla.com', None), 270 long(0), 271 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 272 'SERVER.FOOBAR.')), 273 274 (dns.name.from_text('wp-db03.services.mozilla.com', None), 275 long(0), 276 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 277 'SERVER.FOOBAR.'))] 278 exl.sort(key=_rdata_sort) 279 self.assertEqual(l, exl) 280 281 def testGenerate2(self): # type: () -> None 282 z = dns.zone.from_text(example_text5, 'example.', relativize=True) 283 l = list(z.iterate_rdatas()) 284 l.sort(key=_rdata_sort) 285 exl = [(dns.name.from_text('@', None), 286 long(3600), 287 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 288 'ns1')), 289 (dns.name.from_text('@', None), 290 long(3600), 291 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 292 'ns2')), 293 (dns.name.from_text('@', None), 294 long(3600), 295 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 296 'foo bar 1 2 3 4 5')), 297 (dns.name.from_text('bar.foo', None), 298 long(300), 299 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, 300 '0 blaz.foo')), 301 (dns.name.from_text('ns1', None), 302 long(3600), 303 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 304 '10.0.0.1')), 305 (dns.name.from_text('ns2', None), 306 long(3600), 307 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 308 '10.0.0.2')), 309 310 (dns.name.from_text('wp-db21.services.mozilla.com', None), long(0), 311 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 312 'SERVER.FOOBAR.')), 313 314 (dns.name.from_text('wp-db22.services.mozilla.com', None), long(0), 315 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 316 'SERVER.FOOBAR.')), 317 318 (dns.name.from_text('wp-db23.services.mozilla.com', None), long(0), 319 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 320 'SERVER.FOOBAR.'))] 321 exl.sort(key=_rdata_sort) 322 self.failUnless(l == exl) 323 324 def testGenerate3(self): # type: () -> None 325 z = dns.zone.from_text(example_text6, 'example.', relativize=True) 326 l = list(z.iterate_rdatas()) 327 l.sort(key=_rdata_sort) 328 329 exl = [(dns.name.from_text('@', None), 330 long(3600), 331 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 332 'ns1')), 333 (dns.name.from_text('@', None), 334 long(3600), 335 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 336 'ns2')), 337 (dns.name.from_text('@', None), 338 long(3600), 339 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 340 'foo bar 1 2 3 4 5')), 341 (dns.name.from_text('bar.foo', None), 342 long(300), 343 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, 344 '0 blaz.foo')), 345 (dns.name.from_text('ns1', None), 346 long(3600), 347 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 348 '10.0.0.1')), 349 (dns.name.from_text('ns2', None), 350 long(3600), 351 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 352 '10.0.0.2')), 353 (dns.name.from_text('wp-db21.services.mozilla.com', None), long(0), 354 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 355 'SERVER.FOOBAR.')), 356 357 (dns.name.from_text('wp-db22.services.mozilla.com', None), long(0), 358 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 359 'SERVER.FOOBAR.')), 360 361 (dns.name.from_text('wp-db23.services.mozilla.com', None), long(0), 362 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 363 'SERVER.FOOBAR.'))] 364 exl.sort(key=_rdata_sort) 365 self.failUnless(l == exl) 366 367 def testGenerate4(self): # type: () -> None 368 z = dns.zone.from_text(example_text7, 'example.', relativize=True) 369 l = list(z.iterate_rdatas()) 370 l.sort(key=_rdata_sort) 371 exl = [(dns.name.from_text('@', None), 372 long(3600), 373 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 374 'ns1')), 375 (dns.name.from_text('@', None), 376 long(3600), 377 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 378 'ns2')), 379 (dns.name.from_text('@', None), 380 long(3600), 381 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 382 'foo bar 1 2 3 4 5')), 383 (dns.name.from_text('bar.foo', None), 384 long(300), 385 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, 386 '0 blaz.foo')), 387 (dns.name.from_text('ns1', None), 388 long(3600), 389 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 390 '10.0.0.1')), 391 (dns.name.from_text('ns2', None), 392 long(3600), 393 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 394 '10.0.0.2')), 395 396 (dns.name.from_text('sync1.db', None), long(3600), 397 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 398 '10.10.16.0')), 399 400 (dns.name.from_text('sync2.db', None), long(3600), 401 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 402 '10.10.16.0')), 403 404 (dns.name.from_text('sync3.db', None), long(3600), 405 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 406 '10.10.16.0'))] 407 exl.sort(key=_rdata_sort) 408 self.failUnless(l == exl) 409 410 def testGenerate6(self): # type: () -> None 411 z = dns.zone.from_text(example_text9, 'example.', relativize=True) 412 l = list(z.iterate_rdatas()) 413 l.sort(key=_rdata_sort) 414 exl = [(dns.name.from_text('@', None), 415 long(3600), 416 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 417 'ns1')), 418 (dns.name.from_text('@', None), 419 long(3600), 420 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 421 'ns2')), 422 (dns.name.from_text('@', None), 423 long(3600), 424 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 425 'foo bar 1 2 3 4 5')), 426 (dns.name.from_text('bar.foo', None), 427 long(300), 428 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, 429 '0 blaz.foo')), 430 (dns.name.from_text('ns1', None), 431 long(3600), 432 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 433 '10.0.0.1')), 434 (dns.name.from_text('ns2', None), 435 long(3600), 436 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 437 '10.0.0.2')), 438 439 (dns.name.from_text('wp-db01', None), long(3600), 440 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 441 '10.10.16.0')), 442 (dns.name.from_text('wp-db02', None), long(3600), 443 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 444 '10.10.16.0')), 445 446 (dns.name.from_text('sync1.db', None), long(3600), 447 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 448 '10.10.16.0')), 449 450 (dns.name.from_text('sync2.db', None), long(3600), 451 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 452 '10.10.16.0')), 453 454 (dns.name.from_text('sync3.db', None), long(3600), 455 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 456 '10.10.16.0'))] 457 exl.sort(key=_rdata_sort) 458 self.failUnless(l == exl) 459 460 def testGenerate7(self): # type: () -> None 461 z = dns.zone.from_text(example_text10, 'example.', relativize=True) 462 l = list(z.iterate_rdatas()) 463 l.sort(key=_rdata_sort) 464 exl = [(dns.name.from_text('@', None), 465 long(3600), 466 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 467 'ns1')), 468 (dns.name.from_text('@', None), 469 long(3600), 470 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 471 'ns2')), 472 (dns.name.from_text('@', None), 473 long(3600), 474 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 475 'foo bar 1 2 3 4 5')), 476 (dns.name.from_text('bar.foo', None), 477 long(300), 478 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, 479 '0 blaz.foo')), 480 (dns.name.from_text('ns1', None), 481 long(3600), 482 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 483 '10.0.0.1')), 484 (dns.name.from_text('ns2', None), 485 long(3600), 486 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, 487 '10.0.0.2')), 488 489 (dns.name.from_text('27.2', None), long(3600), 490 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.PTR, 491 'zlb1.oob')), 492 493 (dns.name.from_text('28.2', None), long(3600), 494 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.PTR, 495 'zlb2.oob'))] 496 497 exl.sort(key=_rdata_sort) 498 self.failUnless(l == exl) 499 500 501if __name__ == '__main__': 502 unittest.main() 503