source: branches/cname-collision/t/cname.t@ 993

Last change on this file since 993 was 993, checked in by Kris Deugau, 5 days ago

/branches/cname-collision

Add inexplicably missed 'use strict; use warnings;', declare a couple of
variables, and fix a comparison using the wrong operator.

File size: 15.2 KB
Line 
1# -*- Perl -*-
2# Tests for CNAME records
3# Note that not all possible cases are caught!
4# Template records mean not all published records are natively present in the DB
5
6use strict;
7use warnings;
8
9use Test::More;
10use Data::Dumper;
11
12use lib 't';
13
14use DNSTest;
15my $dtest = DNSTest::new;
16
17my ($code,$msg);
18my $rectype = 5;
19my $newname;
20my $newval;
21my $expirystamp;
22my $rcount;
23
24
25## Domain tests
26subtest 'Domain tests' => sub {
27
28 subtest 'CNAME add - new name' => sub {
29 $newname = 'newname.example.com';
30 $newval = 'fredshosting.example.net';
31 ($code, $msg) = $dnsdb->addRec('n', 'n', 1, \$newname, \$rectype, \$newval, 900);
32 ok( $code eq 'OK', "addRec() claimed succeess" );
33 if ($code eq 'OK') {
34 # crosscheck in the DB
35 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname'");
36 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
37 } else {
38 print "not ok: $msg";
39 }
40 };
41
42 subtest 'CNAME add - existing/colliding non-CNAME' => sub {
43 $newname = 'mx1.example.com';
44 ($code, $msg) = $dnsdb->addRec('n', 'n', 1, \$newname, \$rectype, \$newval, 900);
45 ok( $code eq 'FAIL', "addRec() claimed failure" );
46 if ($code eq 'FAIL') {
47 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname' AND type <> 5");
48 ok( $rcount == 2, " ... [$rcount] record(s) with $newname already exist" );
49 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
50 }
51 };
52
53 subtest 'CNAME add - existing/colliding CNAME' => sub {
54 $newname = 'www.example.com';
55 ($code, $msg) = $dnsdb->addRec('n', 'n', 1, \$newname, \$rectype, \$newval, 900);
56 ok( $code eq 'FAIL', "addRec() claimed failure" );
57 if ($code eq 'FAIL') {
58 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname' AND type = 5");
59 ok( $rcount == 1, " ... [$rcount] CNAME already exists" );
60 like( $msg, qr/already a CNAME present/, " ... returned matching error" );
61 }
62 };
63
64 subtest 'CNAME update - non-CNAME to CNAME, non-colliding' => sub {
65 $newname = 'smtp.example.com';
66 $newval = 'example.com';
67 ($code, $msg) = $dnsdb->updateRec('n', 'n', 39, 1, \$newname, \$rectype, \$newval, 900);
68 ok( $code eq 'OK', "updateRec() claimed success" );
69 if ($code eq 'OK') {
70 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname'");
71 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
72 } else {
73 print "not ok: $msg";
74 }
75 };
76
77 subtest 'CNAME update - non-CNAME to CNAME, colliding' => sub {
78 $newname = 'mx1.example.com';
79 ($code, $msg) = $dnsdb->updateRec('n', 'n', 39, 1, \$newname, \$rectype, \$newval, 900);
80 ok( $code eq 'FAIL', "updateRec() claimed failure" );
81 if ($code eq 'FAIL') {
82 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname' AND type <> 5");
83 ok( $rcount == 2, " ... [$rcount] record(s) with $newname already exist" );
84 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
85 }
86 };
87
88 subtest 'CNAME update - name to non-colliding name' => sub {
89 $newname = 'imap.example.com';
90 ($code, $msg) = $dnsdb->updateRec('n', 'n', 37, 1, \$newname, \$rectype, \$newval, 900);
91 ok( $code eq 'OK', "updateRec() claimed success" );
92 if ($code eq 'OK') {
93 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname'");
94 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
95 } else {
96 print "not ok: $msg";
97 }
98 };
99
100 subtest 'CNAME update - name to colliding name' => sub {
101 $newname = 'mx1.example.com';
102 ($code, $msg) = $dnsdb->updateRec('n', 'n', 41, 1, \$newname, \$rectype, \$newval, 900);
103 ok( $code eq 'FAIL', "updateRec() claimed failure" );
104 if ($code eq 'FAIL') {
105 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname' AND type <> 5");
106 ok( $rcount == 2, " ... [$rcount] record(s) with $newname already exist" );
107 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
108 }
109 };
110
111}; # domain tests
112
113
114## Reverse zone tests
115subtest 'Reverse zone tests' => sub {
116
117 subtest 'CNAME add - new reverse name' => sub {
118 $newval = '192.168.2.12';
119 $newname = '12.8-29.2.168.192.in-addr.arpa';
120 ($code, $msg) = $dnsdb->addRec('n', 'y', 1, \$newname, \$rectype, \$newval, 900);
121 ok( $code eq 'OK', "addRec() claimed succeess" );
122 if ($code eq 'OK') {
123 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval'");
124 ok( $rcount == 1, " ... [$rcount] yep, IP only occurs once" );
125 } else {
126 print "not ok: $msg\n";
127 }
128 };
129
130 subtest 'CNAME add - existing/colliding non-CNAME' => sub {
131 $newval = '192.168.2.14';
132 $newname = '14.8-29.2.168.192.in-addr.arpa';
133 ($code, $msg) = $dnsdb->addRec('n', 'y', 1, \$newname, \$rectype, \$newval, 900);
134 ok( $code eq 'FAIL', "addRec() claimed failure" );
135 if ($code eq 'FAIL') {
136 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval' AND type <> 5");
137 ok( $rcount == 2, " ... [$rcount] record(s) with $newname already exist" );
138 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
139 }
140 };
141
142 subtest 'CNAME add - existing/colliding CNAME' => sub {
143 $newval = '192.168.2.13';
144 $newname = '13.8-29.2.168.192.in-addr.arpa';
145 ($code, $msg) = $dnsdb->addRec('n', 'y', 1, \$newname, \$rectype, \$newval, 900);
146 ok( $code eq 'FAIL', "addRec() claimed failure" );
147 if ($code eq 'FAIL') {
148 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval' AND type = 5");
149 ok( $rcount == 1, " ... [$rcount] CNAME already exists" );
150 like( $msg, qr/already a CNAME present/, " ... returned matching error" );
151 }
152 };
153
154 subtest 'CNAME update - non-CNAME to CNAME, non-colliding' => sub {
155 $newval = '192.168.2.15';
156 $newname = '15-29.arpa.example.net';
157 ($code, $msg) = $dnsdb->updateRec('n', 'y', 43, 1, \$newname, \$rectype, \$newval, 900);
158 ok( $code eq 'OK', "updateRec() claimed success" );
159 if ($code eq 'OK') {
160 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval'");
161 ok( $rcount == 1, " ... [$rcount] yep, IP only occurs once" );
162 } else {
163 print "not ok: $msg\n";
164 }
165 };
166
167 subtest 'CNAME update - non-CNAME to CNAME, colliding' => sub {
168 $newval = '192.168.2.14';
169 $newname = 'arpa14.rev.example.net';
170 ($code, $msg) = $dnsdb->updateRec('n', 'y', 42, 1, \$newname, \$rectype, \$newval, 900);
171 ok( $code eq 'FAIL', "updateRec() claimed failure updating revzone record type to CNAME" );
172 if ($code eq 'FAIL') {
173 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval' AND type <> 5");
174 ok( $rcount == 2, " ... [$rcount] record(s) with $newval already exist" );
175 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
176 }
177 };
178
179 subtest 'CNAME update - name to non-colliding name' => sub {
180 $newval = '192.168.2.11';
181 ($code, $msg) = $dnsdb->updateRec('n', 'y', 34, 1, \$newname, \$rectype, \$newval, 900);
182 ok( $code eq 'OK', "updateRec() claimed success updating revzone CNAME \"hostname\" (non-colliding)" );
183 if ($code eq 'OK') {
184 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval'");
185 ok( $rcount == 1, " ... [$rcount] yep, IP only occurs once" );
186 } else {
187 print "not ok: $msg";
188 }
189 };
190
191 subtest 'CNAME update - name to colliding name' => sub {
192 $newval = '192.168.2.17';
193 ($code, $msg) = $dnsdb->updateRec('n', 'y', 46, 1, \$newname, \$rectype, \$newval, 900);
194 ok( $code eq 'FAIL', "updateRec() claimed failure" );
195 if ($code eq 'FAIL') {
196 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval' AND type <> 5");
197 ok( $rcount == 1, " ... [$rcount] record(s) with $newval already exist" );
198 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
199 }
200 };
201
202}; # reverse zone tests
203
204
205## Record expiry/valid-after cases
206subtest 'Record expiry/valid-after' => sub {
207
208 subtest 'CNAME add - nonexpiring' => sub {
209 subtest ' - collision with expired record' => sub {
210 $newname = 'expired1.expiry1.test';
211 $newval = 'target.example.com';
212 ($code, $msg) = $dnsdb->addRec('n', 'n', 4, \$newname, \$rectype, \$newval, 900);
213 ok( $code eq 'OK', "addRec() claimed success" );
214 if ($code eq 'OK') {
215 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 4 AND host = '$newname' AND stampactive = 'f'");
216 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
217 } else {
218 print "not ok: $msg";
219 }
220 };
221# this test arguably overkill, subsumed by earlier test for nonexpiring collision
222 subtest ' - collision with soon to expire record' => sub {
223 $newname = 'expired2.expiry1.test';
224 ($code, $msg) = $dnsdb->addRec('n', 'n', 4, \$newname, \$rectype, \$newval, 900);
225 ok( $code eq 'FAIL', "addRec() claimed failure" );
226 if ($code eq 'FAIL') {
227 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 4 AND host = '$newname' AND type <> 5 AND stampactive = 't'");
228 ok( $rcount == 1, " ... [$rcount] record(s) with $newname already exist" );
229# somewhat less overkill if we try to target a unique return based around the expiry bit
230 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
231 }
232 };
233 subtest ' - collision with pending active-after record' => sub {
234 $newname = 'active-after1.expiry1.test';
235 ($code, $msg) = $dnsdb->addRec('n', 'n', 4, \$newname, \$rectype, \$newval, 900);
236 ok( $code eq 'WARN', "addRec() claimed success with warning" );
237 if ($code eq 'WARN') {
238 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 4 AND host = '$newname'");
239 ok( $rcount == 2, " ... [$rcount] correct number of records for $newname" );
240 like( $msg, qr/added with expiry time; conflicting valid-after record found/, " ... returned appropriate warning message" );
241 my ($newstamp) = $dbh->selectrow_array("SELECT stamp FROM records WHERE domain_id = 4 AND host = '$newname' ".
242 "AND stampactive = 't' AND expires = 't'");
243 my ($oldstamp) = $dbh->selectrow_array("SELECT stamp FROM records WHERE domain_id = 4 AND host = '$newname' ".
244 "AND stampactive = 't' AND expires = 'f'");
245 ok( $newstamp eq $oldstamp, " ... coerced timestamp matches existing active-after timestamp" );
246 } else {
247 print "not ok: $msg";
248 }
249 };
250 subtest ' - collision with active active-after record' => sub {
251 $newname = 'active-after2.expiry1.test';
252 ($code, $msg) = $dnsdb->addRec('n', 'n', 4, \$newname, \$rectype, \$newval, 900);
253 ok( $code eq 'FAIL', "addRec() claimed failure" );
254 if ($code eq 'FAIL') {
255 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 4 AND host = '$newname' AND type <> 5");
256 ok( $rcount == 1, " ... [$rcount] record(s) with $newname already exist" );
257 like( $msg, qr/record with a valid-after time in the past/, " ... returned matching error" );
258 }
259 };
260 }; # add non-timestamp CNAME
261
262 subtest 'CNAME add - expires soon' => sub {
263 my @ltime = localtime;
264 $expirystamp = sprintf "%i-%i-%i %i:%i", $ltime[5] + 1900, $ltime[4] + 1, $ltime[3] + 3, 15, $ltime[1];
265 $newval = 'target.example.com';
266 subtest 'collision with nonexpiring record' => sub {
267 $newname = 'expires-at1.expiry2.test';
268 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
269 ok($code eq 'FAIL', "addRec() claimed failure");
270 if ($code eq 'FAIL') {
271 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname'");
272 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
273 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
274 }
275 };
276 subtest 'collision with expiring record' => sub {
277 $newname = 'expires-at2.expiry2.test';
278 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
279 ok( $code eq 'FAIL', "addRec() claimed failure");
280 if ($code eq 'FAIL') {
281 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname' AND type <> 5");
282 ok( $rcount == 1, " ... [$rcount] record(s) with $newname already exist" );
283 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
284 }
285 };
286 subtest 'expire before valid-after record' => sub {
287 $newname = 'expires-at3.expiry2.test';
288 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
289 ok( $code eq 'OK', "addRec() claimed success" );
290 if ($code eq 'OK') {
291 # crosscheck in the DB
292 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname'");
293 ok( $rcount == 2, " ... [$rcount] correct number of records for $newname" );
294 my ($newstamp) = $dbh->selectrow_array("SELECT extract(epoch from stamp) FROM records WHERE domain_id = 5 AND host = '$newname' ".
295 "AND stampactive = 't' AND expires = 't'");
296 my ($oldstamp) = $dbh->selectrow_array("SELECT extract(epoch from stamp) FROM records WHERE domain_id = 5 AND host = '$newname' ".
297 "AND stampactive = 't' AND expires = 'f'");
298 ok( $newstamp <= $oldstamp, " ... added record expires before existing active-after record goes active" );
299 } else {
300 print "not ok: $msg";
301 }
302 };
303 subtest 'expire after valid-after record' => sub {
304 $newname = 'expires-at4.expiry2.test';
305 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
306 ok( $code eq 'WARN', "addRec() claimed success with warning" );
307 if ($code eq 'WARN') {
308 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname'");
309 ok( $rcount == 2, " ... [$rcount] correct number of records for $newname" );
310 like( $msg, qr/added with modified expiry time; conflicting valid-after record found/, " ... returned appropriate warning message" );
311 my ($newstamp) = $dbh->selectrow_array("SELECT stamp FROM records WHERE domain_id = 5 AND host = '$newname' ".
312 "AND stampactive = 't' AND expires = 't'");
313 my ($oldstamp) = $dbh->selectrow_array("SELECT stamp FROM records WHERE domain_id = 5 AND host = '$newname' ".
314 "AND stampactive = 't' AND expires = 'f'");
315 ok( $newstamp eq $oldstamp, " ... coerced timestamp matches existing active-after timestamp" );
316 } else {
317 print "not ok: $msg";
318 }
319 };
320 }; # add expiring CNAME
321
322}; # record expiry/valid-after
323
324
325done_testing();
Note: See TracBrowser for help on using the repository browser.