xref: /minix3/external/bsd/bind/dist/bin/tests/system/nsupdate/update_test.pl (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek#!/usr/bin/perl
2*00b67f09SDavid van Moolenbroek#
3*00b67f09SDavid van Moolenbroek# Copyright (C) 2004, 2007, 2012  Internet Systems Consortium, Inc. ("ISC")
4*00b67f09SDavid van Moolenbroek# Copyright (C) 2000, 2001  Internet Software Consortium.
5*00b67f09SDavid van Moolenbroek#
6*00b67f09SDavid van Moolenbroek# Permission to use, copy, modify, and/or distribute this software for any
7*00b67f09SDavid van Moolenbroek# purpose with or without fee is hereby granted, provided that the above
8*00b67f09SDavid van Moolenbroek# copyright notice and this permission notice appear in all copies.
9*00b67f09SDavid van Moolenbroek#
10*00b67f09SDavid van Moolenbroek# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11*00b67f09SDavid van Moolenbroek# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12*00b67f09SDavid van Moolenbroek# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13*00b67f09SDavid van Moolenbroek# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14*00b67f09SDavid van Moolenbroek# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15*00b67f09SDavid van Moolenbroek# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*00b67f09SDavid van Moolenbroek# PERFORMANCE OF THIS SOFTWARE.
17*00b67f09SDavid van Moolenbroek
18*00b67f09SDavid van Moolenbroek#
19*00b67f09SDavid van Moolenbroek# Dynamic update test suite.
20*00b67f09SDavid van Moolenbroek#
21*00b67f09SDavid van Moolenbroek# Usage:
22*00b67f09SDavid van Moolenbroek#
23*00b67f09SDavid van Moolenbroek#   perl update_test.pl [-s server] [-p port] zone
24*00b67f09SDavid van Moolenbroek#
25*00b67f09SDavid van Moolenbroek# The server defaults to 127.0.0.1.
26*00b67f09SDavid van Moolenbroek# The port defaults to 53.
27*00b67f09SDavid van Moolenbroek#
28*00b67f09SDavid van Moolenbroek# The "Special NS rules" tests will only work correctly if the
29*00b67f09SDavid van Moolenbroek# zone has no NS records to begin with, or alternatively has a
30*00b67f09SDavid van Moolenbroek# single NS record pointing at the name "ns1" (relative to
31*00b67f09SDavid van Moolenbroek# the zone name).
32*00b67f09SDavid van Moolenbroek#
33*00b67f09SDavid van Moolenbroek# Installation notes:
34*00b67f09SDavid van Moolenbroek#
35*00b67f09SDavid van Moolenbroek# This program uses the Net::DNS::Resolver module.
36*00b67f09SDavid van Moolenbroek# You can install it by saying
37*00b67f09SDavid van Moolenbroek#
38*00b67f09SDavid van Moolenbroek#    perl -MCPAN -e "install Net::DNS"
39*00b67f09SDavid van Moolenbroek#
40*00b67f09SDavid van Moolenbroek# Id: update_test.pl,v 1.10 2007/06/19 23:47:04 tbox Exp
41*00b67f09SDavid van Moolenbroek#
42*00b67f09SDavid van Moolenbroek
43*00b67f09SDavid van Moolenbroekuse Getopt::Std;
44*00b67f09SDavid van Moolenbroekuse Net::DNS;
45*00b67f09SDavid van Moolenbroekuse Net::DNS::Update;
46*00b67f09SDavid van Moolenbroekuse Net::DNS::Resolver;
47*00b67f09SDavid van Moolenbroek
48*00b67f09SDavid van Moolenbroek$opt_s = "127.0.0.1";
49*00b67f09SDavid van Moolenbroek$opt_p = 53;
50*00b67f09SDavid van Moolenbroek
51*00b67f09SDavid van Moolenbroekgetopt('s:p:');
52*00b67f09SDavid van Moolenbroek
53*00b67f09SDavid van Moolenbroek$res = new Net::DNS::Resolver;
54*00b67f09SDavid van Moolenbroek$res->nameservers($opt_s);
55*00b67f09SDavid van Moolenbroek$res->port($opt_p);
56*00b67f09SDavid van Moolenbroek$res->defnames(0); # Do not append default domain.
57*00b67f09SDavid van Moolenbroek
58*00b67f09SDavid van Moolenbroek@ARGV == 1 or die
59*00b67f09SDavid van Moolenbroek    "usage: perl update_test.pl [-s server] [-p port] zone\n";
60*00b67f09SDavid van Moolenbroek
61*00b67f09SDavid van Moolenbroek$zone = shift @ARGV;
62*00b67f09SDavid van Moolenbroek
63*00b67f09SDavid van Moolenbroekmy $failures = 0;
64*00b67f09SDavid van Moolenbroek
65*00b67f09SDavid van Moolenbroeksub assert {
66*00b67f09SDavid van Moolenbroek    my ($cond, $explanation) = @_;
67*00b67f09SDavid van Moolenbroek    if (!$cond) {
68*00b67f09SDavid van Moolenbroek	print "I:Test Failed: $explanation ***\n";
69*00b67f09SDavid van Moolenbroek	$failures++
70*00b67f09SDavid van Moolenbroek    }
71*00b67f09SDavid van Moolenbroek}
72*00b67f09SDavid van Moolenbroek
73*00b67f09SDavid van Moolenbroeksub test {
74*00b67f09SDavid van Moolenbroek    my ($expected, @records) = @_;
75*00b67f09SDavid van Moolenbroek
76*00b67f09SDavid van Moolenbroek    my $update = new Net::DNS::Update("$zone");
77*00b67f09SDavid van Moolenbroek
78*00b67f09SDavid van Moolenbroek    foreach $rec (@records) {
79*00b67f09SDavid van Moolenbroek	$update->push(@$rec);
80*00b67f09SDavid van Moolenbroek    }
81*00b67f09SDavid van Moolenbroek
82*00b67f09SDavid van Moolenbroek    $reply = $res->send($update);
83*00b67f09SDavid van Moolenbroek
84*00b67f09SDavid van Moolenbroek    # Did it work?
85*00b67f09SDavid van Moolenbroek    if (defined $reply) {
86*00b67f09SDavid van Moolenbroek	my $rcode = $reply->header->rcode;
87*00b67f09SDavid van Moolenbroek        assert($rcode eq $expected, "expected $expected, got $rcode");
88*00b67f09SDavid van Moolenbroek    } else {
89*00b67f09SDavid van Moolenbroek	print "I:Update failed: ", $res->errorstring, "\n";
90*00b67f09SDavid van Moolenbroek    }
91*00b67f09SDavid van Moolenbroek}
92*00b67f09SDavid van Moolenbroek
93*00b67f09SDavid van Moolenbroeksub section {
94*00b67f09SDavid van Moolenbroek    my ($msg) = @_;
95*00b67f09SDavid van Moolenbroek    print "I:$msg\n";
96*00b67f09SDavid van Moolenbroek}
97*00b67f09SDavid van Moolenbroek
98*00b67f09SDavid van Moolenbroeksection("Delete any leftovers from previous tests");
99*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("a.$zone")]);
100*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("b.$zone")]);
101*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("c.$zone")]);
102*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("d.$zone")]);
103*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("e.$zone")]);
104*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("f.$zone")]);
105*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("ns.s.$zone")]);
106*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("s.$zone")]);
107*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("t.$zone")]);
108*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("*.$zone")]);
109*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("u.$zone")]);
110*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("a.u.$zone")]);
111*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("b.u.$zone")]);
112*00b67f09SDavid van Moolenbroek
113*00b67f09SDavid van Moolenbroeksection("Simple prerequisites in the absence of data");
114*00b67f09SDavid van Moolenbroek# Name is in Use
115*00b67f09SDavid van Moolenbroektest("NXDOMAIN", ["pre", yxdomain("a.$zone")]);
116*00b67f09SDavid van Moolenbroek# RRset exists (value independent)
117*00b67f09SDavid van Moolenbroektest("NXRRSET", ["pre", yxrrset("a.$zone A")]);
118*00b67f09SDavid van Moolenbroek# Name is not in use
119*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxdomain("a.$zone")]);
120*00b67f09SDavid van Moolenbroek# RRset does not exist
121*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxrrset("a.$zone A")]);
122*00b67f09SDavid van Moolenbroek# RRset exists (value dependent)
123*00b67f09SDavid van Moolenbroektest("NXRRSET", ["pre", yxrrset("a.$zone A 73.80.65.49")]);
124*00b67f09SDavid van Moolenbroek
125*00b67f09SDavid van Moolenbroek
126*00b67f09SDavid van Moolenbroeksection ("Simple creation of data");
127*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("a.$zone 300 A 73.80.65.49")]);
128*00b67f09SDavid van Moolenbroek
129*00b67f09SDavid van Moolenbroeksection ("Simple prerequisites in the presence of data");
130*00b67f09SDavid van Moolenbroek# Name is in use
131*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", yxdomain("a.$zone")]);
132*00b67f09SDavid van Moolenbroek# RRset exists (value independent)
133*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", yxrrset("a.$zone A")]);
134*00b67f09SDavid van Moolenbroek# Name is not in use
135*00b67f09SDavid van Moolenbroektest("YXDOMAIN", ["pre", nxdomain("a.$zone")]);
136*00b67f09SDavid van Moolenbroek# RRset does not exist
137*00b67f09SDavid van Moolenbroektest("YXRRSET", ["pre", nxrrset("a.$zone A")]);
138*00b67f09SDavid van Moolenbroek# RRset exists (value dependent)
139*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", yxrrset("a.$zone A 73.80.65.49")]);
140*00b67f09SDavid van Moolenbroek
141*00b67f09SDavid van Moolenbroek#
142*00b67f09SDavid van Moolenbroek# Merging of RRsets
143*00b67f09SDavid van Moolenbroek#
144*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("a.$zone 300 A 73.80.65.50")]);
145*00b67f09SDavid van Moolenbroek
146*00b67f09SDavid van Moolenbroeksection("Detailed tests of \"RRset exists (value dependent)\" prerequisites");
147*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre",
148*00b67f09SDavid van Moolenbroek		 yxrrset("a.$zone A 73.80.65.49"),
149*00b67f09SDavid van Moolenbroek		 yxrrset("a.$zone A 73.80.65.50")]);
150*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre",
151*00b67f09SDavid van Moolenbroek		 yxrrset("a.$zone A 73.80.65.50"),
152*00b67f09SDavid van Moolenbroek		 yxrrset("a.$zone A 73.80.65.49")]);
153*00b67f09SDavid van Moolenbroektest("NXRRSET", ["pre", yxrrset("a.$zone A 73.80.65.49")]);
154*00b67f09SDavid van Moolenbroektest("NXRRSET", ["pre", yxrrset("a.$zone A 73.80.65.50")]);
155*00b67f09SDavid van Moolenbroektest("NXRRSET", ["pre",
156*00b67f09SDavid van Moolenbroek		 yxrrset("a.$zone A 73.80.65.49"),
157*00b67f09SDavid van Moolenbroek		 yxrrset("a.$zone A 73.80.65.50"),
158*00b67f09SDavid van Moolenbroek		 yxrrset("a.$zone A 73.80.65.51")]);
159*00b67f09SDavid van Moolenbroek
160*00b67f09SDavid van Moolenbroek
161*00b67f09SDavid van Moolenbroeksection("Torture test of \"RRset exists (value dependent)\" prerequisites.");
162*00b67f09SDavid van Moolenbroek
163*00b67f09SDavid van Moolenbroektest("NOERROR", ["update",
164*00b67f09SDavid van Moolenbroek		 rr_add("e.$zone 300 A 73.80.65.49"),
165*00b67f09SDavid van Moolenbroek		 rr_add("e.$zone 300 TXT 'one'"),
166*00b67f09SDavid van Moolenbroek		 rr_add("e.$zone 300 A 73.80.65.50")]);
167*00b67f09SDavid van Moolenbroektest("NOERROR", ["update",
168*00b67f09SDavid van Moolenbroek		 rr_add("e.$zone 300 A 73.80.65.52"),
169*00b67f09SDavid van Moolenbroek		 rr_add("f.$zone 300 A 73.80.65.52"),
170*00b67f09SDavid van Moolenbroek		 rr_add("e.$zone 300 A 73.80.65.51")]);
171*00b67f09SDavid van Moolenbroektest("NOERROR", ["update",
172*00b67f09SDavid van Moolenbroek		 rr_add("e.$zone 300 TXT 'three'"),
173*00b67f09SDavid van Moolenbroek		 rr_add("e.$zone 300 TXT 'two'")]);
174*00b67f09SDavid van Moolenbroektest("NOERROR", ["update",
175*00b67f09SDavid van Moolenbroek		 rr_add("e.$zone 300 MX 10 mail.$zone")]);
176*00b67f09SDavid van Moolenbroek
177*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre",
178*00b67f09SDavid van Moolenbroek		 yxrrset("e.$zone A 73.80.65.52"),
179*00b67f09SDavid van Moolenbroek		 yxrrset("e.$zone TXT 'two'"),
180*00b67f09SDavid van Moolenbroek		 yxrrset("e.$zone A 73.80.65.51"),
181*00b67f09SDavid van Moolenbroek		 yxrrset("e.$zone TXT 'three'"),
182*00b67f09SDavid van Moolenbroek		 yxrrset("e.$zone A 73.80.65.50"),
183*00b67f09SDavid van Moolenbroek		 yxrrset("f.$zone A 73.80.65.52"),
184*00b67f09SDavid van Moolenbroek		 yxrrset("e.$zone A 73.80.65.49"),
185*00b67f09SDavid van Moolenbroek		 yxrrset("e.$zone TXT 'one'")]);
186*00b67f09SDavid van Moolenbroek
187*00b67f09SDavid van Moolenbroek
188*00b67f09SDavid van Moolenbroeksection("Subtraction of RRsets");
189*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("a.$zone A 73.80.65.49")]);
190*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre",
191*00b67f09SDavid van Moolenbroek		 yxrrset("a.$zone A 73.80.65.50")]);
192*00b67f09SDavid van Moolenbroek
193*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("a.$zone A 73.80.65.50")]);
194*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxrrset("a.$zone A")]);
195*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxdomain("a.$zone")]);
196*00b67f09SDavid van Moolenbroek
197*00b67f09SDavid van Moolenbroeksection("Other forms of deletion");
198*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("a.$zone 300 A 73.80.65.49")]);
199*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("a.$zone 300 A 73.80.65.50")]);
200*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("a.$zone 300 MX 10 mail.$zone")]);
201*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("a.$zone A")]);
202*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxrrset("a.$zone A")]);
203*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("a.$zone 300 A 73.80.65.49")]);
204*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("a.$zone 300 A 73.80.65.50")]);
205*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("a.$zone")]);
206*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxdomain("a.$zone")]);
207*00b67f09SDavid van Moolenbroek
208*00b67f09SDavid van Moolenbroeksection("Case insensitivity");
209*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("a.$zone 300 PTR foo.net.")]);
210*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", yxrrset("A.$zone PTR fOo.NeT.")]);
211*00b67f09SDavid van Moolenbroek
212*00b67f09SDavid van Moolenbroeksection("Special CNAME rules");
213*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("b.$zone 300 CNAME foo.net.")]);
214*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("b.$zone 300 A 73.80.65.49")]);
215*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", yxrrset("b.$zone CNAME foo.net.")]);
216*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxrrset("b.$zone A")]);
217*00b67f09SDavid van Moolenbroek
218*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("c.$zone 300 A 73.80.65.49")]);
219*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("c.$zone 300 CNAME foo.net.")]);
220*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", yxrrset("c.$zone A")]);
221*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxrrset("c.$zone CNAME")]);
222*00b67f09SDavid van Moolenbroek
223*00b67f09SDavid van Moolenbroek# XXX should test with SIG, KEY, NXT, too.
224*00b67f09SDavid van Moolenbroek
225*00b67f09SDavid van Moolenbroek#
226*00b67f09SDavid van Moolenbroek# Currently commented out because Net::DNS does not properly
227*00b67f09SDavid van Moolenbroek# support WKS records.
228*00b67f09SDavid van Moolenbroek#
229*00b67f09SDavid van Moolenbroek#section("Special WKS rules");
230*00b67f09SDavid van Moolenbroek#test("NOERROR", ["update", rr_add("c.$zone 300 WKS 73.80.65.49 TCP telnet ftp")]);
231*00b67f09SDavid van Moolenbroek#test("NOERROR", ["update", rr_add("c.$zone 300 WKS 73.80.65.49 UDP telnet ftp")]);
232*00b67f09SDavid van Moolenbroek#test("NOERROR", ["update", rr_add("c.$zone 300 WKS 73.80.65.50 TCP telnet ftp")]);
233*00b67f09SDavid van Moolenbroek#test("NOERROR", ["update", rr_add("c.$zone 300 WKS 73.80.65.49 TCP smtp")]);
234*00b67f09SDavid van Moolenbroek#test("NOERROR", ["pre",
235*00b67f09SDavid van Moolenbroek#		 yxrrset("c.$zone WKS 73.80.65.49 TCP smtp"),
236*00b67f09SDavid van Moolenbroek#		 yxrrset("c.$zone WKS 73.80.65.49 UDP telnet ftp"),
237*00b67f09SDavid van Moolenbroek#		 yxrrset("c.$zone WKS 73.80.65.50 TCP telnet ftp")]);
238*00b67f09SDavid van Moolenbroek
239*00b67f09SDavid van Moolenbroek
240*00b67f09SDavid van Moolenbroeksection("Special NS rules");
241*00b67f09SDavid van Moolenbroek
242*00b67f09SDavid van Moolenbroek# Deleting the last NS record using "Delete an RR from an RRset"
243*00b67f09SDavid van Moolenbroek# should fail at the zone apex and work elsewhere.  The pseudocode
244*00b67f09SDavid van Moolenbroek# in RFC2136 says it should fail everywhere, but this is in conflict
245*00b67f09SDavid van Moolenbroek# with the actual text.
246*00b67f09SDavid van Moolenbroek
247*00b67f09SDavid van Moolenbroek# Apex
248*00b67f09SDavid van Moolenbroektest("NOERROR", ["update",
249*00b67f09SDavid van Moolenbroek		 rr_add("$zone 300 NS ns1.$zone"),
250*00b67f09SDavid van Moolenbroek		 rr_add("$zone 300 NS ns2.$zone")]);
251*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("$zone NS ns1.$zone")]);
252*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("$zone NS ns2.$zone")]);
253*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre",
254*00b67f09SDavid van Moolenbroek		 yxrrset("$zone NS ns2.$zone")]);
255*00b67f09SDavid van Moolenbroek
256*00b67f09SDavid van Moolenbroek# Non-apex
257*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("n.$zone 300 NS ns1.$zone")]);
258*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("n.$zone NS ns1.$zone")]);
259*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxrrset("n.$zone NS")]);
260*00b67f09SDavid van Moolenbroek
261*00b67f09SDavid van Moolenbroek# Other ways of deleting NS records should also fail at the apex
262*00b67f09SDavid van Moolenbroek# and work elsewhere.
263*00b67f09SDavid van Moolenbroek
264*00b67f09SDavid van Moolenbroek# Non-apex
265*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("n.$zone 300 NS ns1.$zone")]);
266*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("n.$zone NS")]);
267*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxrrset("n.$zone NS")]);
268*00b67f09SDavid van Moolenbroek
269*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("n.$zone 300 NS ns1.$zone")]);
270*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", yxrrset("n.$zone NS")]);
271*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("n.$zone")]);
272*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxrrset("n.$zone NS")]);
273*00b67f09SDavid van Moolenbroek
274*00b67f09SDavid van Moolenbroek# Apex
275*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("$zone NS")]);
276*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre",
277*00b67f09SDavid van Moolenbroek		 yxrrset("$zone NS ns2.$zone")]);
278*00b67f09SDavid van Moolenbroek
279*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("$zone")]);
280*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre",
281*00b67f09SDavid van Moolenbroek		 yxrrset("$zone NS ns2.$zone")]);
282*00b67f09SDavid van Moolenbroek
283*00b67f09SDavid van Moolenbroek# They should not touch the SOA, either.
284*00b67f09SDavid van Moolenbroek
285*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("$zone SOA")]);
286*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", yxrrset("$zone SOA")]);
287*00b67f09SDavid van Moolenbroek
288*00b67f09SDavid van Moolenbroek
289*00b67f09SDavid van Moolenbroeksection("Idempotency");
290*00b67f09SDavid van Moolenbroek
291*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("d.$zone 300 A 73.80.65.49")]);
292*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", yxrrset("d.$zone A 73.80.65.49")]);
293*00b67f09SDavid van Moolenbroektest("NOERROR", ["update",
294*00b67f09SDavid van Moolenbroek		 rr_add("d.$zone 300 A 73.80.65.49"),
295*00b67f09SDavid van Moolenbroek		 rr_del("d.$zone A")]);
296*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxrrset("d.$zone A")]);
297*00b67f09SDavid van Moolenbroek
298*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("d.$zone A 73.80.65.49")]);
299*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxrrset("d.$zone A")]);
300*00b67f09SDavid van Moolenbroektest("NOERROR", ["update",
301*00b67f09SDavid van Moolenbroek		   rr_del("d.$zone A"),
302*00b67f09SDavid van Moolenbroek		   rr_add("d.$zone 300 A 73.80.65.49")]);
303*00b67f09SDavid van Moolenbroek
304*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", yxrrset("d.$zone A")]);
305*00b67f09SDavid van Moolenbroek
306*00b67f09SDavid van Moolenbroeksection("Out-of-zone prerequisites and updates");
307*00b67f09SDavid van Moolenbroektest("NOTZONE", ["pre", yxrrset("a.somewhere.else. A 73.80.65.49")]);
308*00b67f09SDavid van Moolenbroektest("NOTZONE", ["update", rr_add("a.somewhere.else. 300 A 73.80.65.49")]);
309*00b67f09SDavid van Moolenbroek
310*00b67f09SDavid van Moolenbroek
311*00b67f09SDavid van Moolenbroeksection("Glue");
312*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("s.$zone 300 NS ns.s.$zone")]);
313*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("ns.s.$zone 300 A 73.80.65.49")]);
314*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", yxrrset("ns.s.$zone A 73.80.65.49")]);
315*00b67f09SDavid van Moolenbroek
316*00b67f09SDavid van Moolenbroeksection("Wildcards");
317*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("*.$zone 300 MX 10 mail.$zone")]);
318*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", yxrrset("*.$zone MX 10 mail.$zone")]);
319*00b67f09SDavid van Moolenbroektest("NXRRSET", ["pre", yxrrset("w.$zone MX 10 mail.$zone")]);
320*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxrrset("w.$zone MX")]);
321*00b67f09SDavid van Moolenbroektest("NOERROR", ["pre", nxdomain("w.$zone")]);
322*00b67f09SDavid van Moolenbroek
323*00b67f09SDavid van Moolenbroek
324*00b67f09SDavid van Moolenbroeksection("SOA serial handling");
325*00b67f09SDavid van Moolenbroek
326*00b67f09SDavid van Moolenbroekmy $soatimers = "20 20 1814400 3600";
327*00b67f09SDavid van Moolenbroek
328*00b67f09SDavid van Moolenbroek# Get the current SOA serial number.
329*00b67f09SDavid van Moolenbroekmy $query = $res->query($zone, "SOA");
330*00b67f09SDavid van Moolenbroekmy ($old_soa) = $query->answer;
331*00b67f09SDavid van Moolenbroek
332*00b67f09SDavid van Moolenbroekmy $old_serial = $old_soa->serial;
333*00b67f09SDavid van Moolenbroek
334*00b67f09SDavid van Moolenbroek# Increment it by 10.
335*00b67f09SDavid van Moolenbroekmy $new_serial = $old_serial + 10;
336*00b67f09SDavid van Moolenbroekif ($new_serial > 0xFFFFFFFF) {
337*00b67f09SDavid van Moolenbroek    $new_serial -= 0x80000000;
338*00b67f09SDavid van Moolenbroek    $new_serial -= 0x80000000;
339*00b67f09SDavid van Moolenbroek}
340*00b67f09SDavid van Moolenbroek
341*00b67f09SDavid van Moolenbroek# Replace the SOA with a new one.
342*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("$zone 300 SOA mname1. . $new_serial $soatimers")]);
343*00b67f09SDavid van Moolenbroek
344*00b67f09SDavid van Moolenbroek# Check that the SOA really got replaced.
345*00b67f09SDavid van Moolenbroek($db_soa) = $res->query($zone, "SOA")->answer;
346*00b67f09SDavid van Moolenbroekassert($db_soa->mname eq "mname1");
347*00b67f09SDavid van Moolenbroek
348*00b67f09SDavid van Moolenbroek# Check that attempts to decrement the serial number are ignored.
349*00b67f09SDavid van Moolenbroek$new_serial = $old_serial - 10;
350*00b67f09SDavid van Moolenbroekif ($new_serial < 0) {
351*00b67f09SDavid van Moolenbroek    $new_serial += 0x80000000;
352*00b67f09SDavid van Moolenbroek    $new_serial += 0x80000000;
353*00b67f09SDavid van Moolenbroek}
354*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("$zone 300 SOA mname2. . $new_serial $soatimers")]);
355*00b67f09SDavid van Moolenbroekassert($db_soa->mname eq "mname1");
356*00b67f09SDavid van Moolenbroek
357*00b67f09SDavid van Moolenbroek# Check that attempts to leave the serial number unchanged are ignored.
358*00b67f09SDavid van Moolenbroek($old_soa) = $res->query($zone, "SOA")->answer;
359*00b67f09SDavid van Moolenbroek$old_serial = $old_soa->serial;
360*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("$zone 300 SOA mname3. . $old_serial " .
361*00b67f09SDavid van Moolenbroek				  $soatimers)]);
362*00b67f09SDavid van Moolenbroek($db_soa) = $res->query($zone, "SOA")->answer;
363*00b67f09SDavid van Moolenbroekassert($db_soa->mname eq "mname1");
364*00b67f09SDavid van Moolenbroek
365*00b67f09SDavid van Moolenbroek#
366*00b67f09SDavid van Moolenbroek# Currently commented out because Net::DNS does not properly
367*00b67f09SDavid van Moolenbroek# support multiple strings in TXT records.
368*00b67f09SDavid van Moolenbroek#
369*00b67f09SDavid van Moolenbroek#section("Big data");
370*00b67f09SDavid van Moolenbroek#test("NOERROR", ["update", rr_add("a.$zone 300 TXT aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc")]);
371*00b67f09SDavid van Moolenbroek#test("NOERROR", ["update", rr_del("a.$zone TXT aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc")]);
372*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("a.$zone 300 TXT " . ("foo " x 3))]);
373*00b67f09SDavid van Moolenbroek
374*00b67f09SDavid van Moolenbroeksection("Updating TTLs only");
375*00b67f09SDavid van Moolenbroek
376*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("t.$zone 300 A 73.80.65.49")]);
377*00b67f09SDavid van Moolenbroek($a) = $res->query("t.$zone", "A")->answer;
378*00b67f09SDavid van Moolenbroek$ttl = $a->ttl;
379*00b67f09SDavid van Moolenbroekassert($ttl == 300, "incorrect TTL value $ttl != 300");
380*00b67f09SDavid van Moolenbroektest("NOERROR", ["update",
381*00b67f09SDavid van Moolenbroek		 rr_del("t.$zone A 73.80.65.49"),
382*00b67f09SDavid van Moolenbroek		 rr_add("t.$zone 301 A 73.80.65.49")]);
383*00b67f09SDavid van Moolenbroek($a) = $res->query("t.$zone", "A")->answer;
384*00b67f09SDavid van Moolenbroek$ttl = $a->ttl;
385*00b67f09SDavid van Moolenbroekassert($ttl == 301, "incorrect TTL value $ttl != 301");
386*00b67f09SDavid van Moolenbroek
387*00b67f09SDavid van Moolenbroek# Add an RR that is identical to an existing one except for the TTL.
388*00b67f09SDavid van Moolenbroek# RFC2136 is not clear about what this should do; it says "duplicate RRs
389*00b67f09SDavid van Moolenbroek# will be silently ignored" but is an RR differing only in TTL
390*00b67f09SDavid van Moolenbroek# to be considered a duplicate or not?  The test assumes that it
391*00b67f09SDavid van Moolenbroek# should not be considered a duplicate.
392*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("t.$zone 302 A 73.80.65.50")]);
393*00b67f09SDavid van Moolenbroek($a) = $res->query("t.$zone", "A")->answer;
394*00b67f09SDavid van Moolenbroek$ttl = $a->ttl;
395*00b67f09SDavid van Moolenbroekassert($ttl == 302, "incorrect TTL value $ttl != 302");
396*00b67f09SDavid van Moolenbroek
397*00b67f09SDavid van Moolenbroeksection("TTL normalization");
398*00b67f09SDavid van Moolenbroek
399*00b67f09SDavid van Moolenbroek# The desired behaviour is that the old RRs get their TTL
400*00b67f09SDavid van Moolenbroek# changed to match the new one.  RFC2136 does not explicitly
401*00b67f09SDavid van Moolenbroek# specify this, but I think it makes more sense than the
402*00b67f09SDavid van Moolenbroek# alternatives.
403*00b67f09SDavid van Moolenbroek
404*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("t.$zone 303 A 73.80.65.51")]);
405*00b67f09SDavid van Moolenbroek(@answers) = $res->query("t.$zone", "A")->answer;
406*00b67f09SDavid van Moolenbroek$nanswers = scalar @answers;
407*00b67f09SDavid van Moolenbroekassert($nanswers == 3, "wrong number of answers $nanswers != 3");
408*00b67f09SDavid van Moolenbroekforeach $a (@answers) {
409*00b67f09SDavid van Moolenbroek    $ttl = $a->ttl;
410*00b67f09SDavid van Moolenbroek    assert($ttl == 303, "incorrect TTL value $ttl != 303");
411*00b67f09SDavid van Moolenbroek}
412*00b67f09SDavid van Moolenbroek
413*00b67f09SDavid van Moolenbroeksection("Obscuring existing data by zone cut");
414*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("a.u.$zone 300 A 73.80.65.49")]);
415*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("b.u.$zone 300 A 73.80.65.49")]);
416*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("u.$zone 300 TXT txt-not-in-nxt")]);
417*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_add("u.$zone 300 NS ns.u.$zone")]);
418*00b67f09SDavid van Moolenbroek
419*00b67f09SDavid van Moolenbroektest("NOERROR", ["update", rr_del("u.$zone NS ns.u.$zone")]);
420*00b67f09SDavid van Moolenbroek
421*00b67f09SDavid van Moolenbroekif ($failures) {
422*00b67f09SDavid van Moolenbroek    print "I:$failures tests failed.\n";
423*00b67f09SDavid van Moolenbroek} else {
424*00b67f09SDavid van Moolenbroek    print "I:All tests successful.\n";
425*00b67f09SDavid van Moolenbroek}
426*00b67f09SDavid van Moolenbroekexit $failures;
427