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

Last change on this file since 1043 was 1043, checked in by Kris Deugau, 4 hours ago

/branches/cname-collision

Remove some excessive docucomments from test file, refine/add a few others
Clean up test calls for consistency and improved clarity on fail
See #88

File size: 34.0 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 cmp_ok( $code, 'eq', 'OK', "addRec() claimed succeess" );
33 if ($code eq 'OK') {
34 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname'");
35 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
36 } else {
37 print "not ok: $msg";
38 }
39 };
40
41 subtest 'CNAME add - existing/colliding non-CNAME' => sub {
42 $newname = 'mx1.example.com';
43 ($code, $msg) = $dnsdb->addRec('n', 'n', 1, \$newname, \$rectype, \$newval, 900);
44 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
45 if ($code eq 'FAIL') {
46 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname' AND type <> 5");
47 ok( $rcount == 2, " ... [$rcount] record(s) with $newname already exist" );
48 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
49 }
50 };
51
52 subtest 'CNAME add - existing/colliding CNAME' => sub {
53 $newname = 'www.example.com';
54 ($code, $msg) = $dnsdb->addRec('n', 'n', 1, \$newname, \$rectype, \$newval, 900);
55 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
56 if ($code eq 'FAIL') {
57 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname' AND type = 5");
58 ok( $rcount == 1, " ... [$rcount] CNAME already exists" );
59 like( $msg, qr/already a CNAME present/, " ... returned matching error" );
60 }
61 };
62
63 subtest 'CNAME update - non-CNAME to CNAME, non-colliding' => sub {
64 $newname = 'smtp.example.com';
65 $newval = 'example.com';
66 ($code, $msg) = $dnsdb->updateRec('n', 'n', 39, 1, \$newname, \$rectype, \$newval, 900);
67 cmp_ok( $code, 'eq', 'OK', "updateRec() claimed success" );
68 if ($code eq 'OK') {
69 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname'");
70 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
71 } else {
72 print "not ok: $msg";
73 }
74 };
75
76 subtest 'CNAME update - non-CNAME to CNAME, colliding' => sub {
77 $newname = 'mx1.example.com';
78 ($code, $msg) = $dnsdb->updateRec('n', 'n', 39, 1, \$newname, \$rectype, \$newval, 900);
79 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure" );
80 if ($code eq 'FAIL') {
81 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname' AND type <> 5");
82 ok( $rcount == 2, " ... [$rcount] record(s) with $newname already exist" );
83 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
84 }
85 };
86
87 subtest 'CNAME update - name to non-colliding name' => sub {
88 $newname = 'imap.example.com';
89 ($code, $msg) = $dnsdb->updateRec('n', 'n', 37, 1, \$newname, \$rectype, \$newval, 900);
90 cmp_ok( $code, 'eq', 'OK', "updateRec() claimed success" );
91 if ($code eq 'OK') {
92 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname'");
93 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
94 } else {
95 print "not ok: $msg";
96 }
97 };
98
99 subtest 'CNAME update - name to colliding name' => sub {
100 $newname = 'mx1.example.com';
101 ($code, $msg) = $dnsdb->updateRec('n', 'n', 41, 1, \$newname, \$rectype, \$newval, 900);
102 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure" );
103 if ($code eq 'FAIL') {
104 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 1 AND host = '$newname' AND type <> 5");
105 ok( $rcount == 2, " ... [$rcount] record(s) with $newname already exist" );
106 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
107 }
108 };
109
110}; # domain tests
111
112
113## Reverse zone tests
114subtest 'Reverse zone tests' => sub {
115
116 subtest 'CNAME add - new reverse name' => sub {
117 $newval = '192.168.2.12';
118 $newname = '12.8-29.2.168.192.in-addr.arpa';
119 ($code, $msg) = $dnsdb->addRec('n', 'y', 1, \$newname, \$rectype, \$newval, 900);
120 cmp_ok( $code, 'eq', 'OK', "addRec() claimed succeess" );
121 if ($code eq 'OK') {
122 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval'");
123 ok( $rcount == 1, " ... [$rcount] yep, IP only occurs once" );
124 } else {
125 print "not ok: $msg\n";
126 }
127 };
128
129 subtest 'CNAME add - existing/colliding non-CNAME' => sub {
130 $newval = '192.168.2.14';
131 $newname = '14.8-29.2.168.192.in-addr.arpa';
132 ($code, $msg) = $dnsdb->addRec('n', 'y', 1, \$newname, \$rectype, \$newval, 900);
133 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
134 if ($code eq 'FAIL') {
135 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval' AND type <> 5");
136 ok( $rcount == 2, " ... [$rcount] record(s) with $newname already exist" );
137 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
138 }
139 };
140
141 subtest 'CNAME add - existing/colliding CNAME' => sub {
142 $newval = '192.168.2.13';
143 $newname = '13.8-29.2.168.192.in-addr.arpa';
144 ($code, $msg) = $dnsdb->addRec('n', 'y', 1, \$newname, \$rectype, \$newval, 900);
145 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
146 if ($code eq 'FAIL') {
147 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval' AND type = 5");
148 ok( $rcount == 1, " ... [$rcount] CNAME already exists" );
149 like( $msg, qr/already a CNAME present/, " ... returned matching error" );
150 }
151 };
152
153 subtest 'CNAME update - non-CNAME to CNAME, non-colliding' => sub {
154 $newval = '192.168.2.15';
155 $newname = '15-29.arpa.example.net';
156 ($code, $msg) = $dnsdb->updateRec('n', 'y', 43, 1, \$newname, \$rectype, \$newval, 900);
157 cmp_ok( $code, 'eq', 'OK', "updateRec() claimed success" );
158 if ($code eq 'OK') {
159 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval'");
160 ok( $rcount == 1, " ... [$rcount] yep, IP only occurs once" );
161 } else {
162 print "not ok: $msg\n";
163 }
164 };
165
166 subtest 'CNAME update - non-CNAME to CNAME, colliding' => sub {
167 $newval = '192.168.2.14';
168 $newname = 'arpa14.rev.example.net';
169 ($code, $msg) = $dnsdb->updateRec('n', 'y', 42, 1, \$newname, \$rectype, \$newval, 900);
170 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure updating revzone record type to CNAME" );
171 if ($code eq 'FAIL') {
172 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval' AND type <> 5");
173 ok( $rcount == 2, " ... [$rcount] record(s) with $newval already exist" );
174 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
175 }
176 };
177
178 subtest 'CNAME update - name to non-colliding name' => sub {
179 $newval = '192.168.2.11';
180 ($code, $msg) = $dnsdb->updateRec('n', 'y', 34, 1, \$newname, \$rectype, \$newval, 900);
181 cmp_ok( $code, 'eq', 'OK', "updateRec() claimed success updating revzone CNAME \"hostname\" (non-colliding)" );
182 if ($code eq 'OK') {
183 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval'");
184 ok( $rcount == 1, " ... [$rcount] yep, IP only occurs once" );
185 } else {
186 print "not ok: $msg";
187 }
188 };
189
190 subtest 'CNAME update - name to colliding name' => sub {
191 $newval = '192.168.2.17';
192 ($code, $msg) = $dnsdb->updateRec('n', 'y', 46, 1, \$newname, \$rectype, \$newval, 900);
193 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure" );
194 if ($code eq 'FAIL') {
195 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE rdns_id = 1 AND val = '$newval' AND type <> 5");
196 ok( $rcount == 1, " ... [$rcount] record(s) with $newval already exist" );
197 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
198 }
199 };
200
201}; # reverse zone tests
202
203
204## Record expiry/valid-after cases
205subtest 'Record expiry/valid-after' => sub {
206
207 ## Add new CNAME with no timestamp
208 subtest 'CNAME add - nonexpiring' => sub {
209 $newval = 'target.example.com';
210 subtest 'collision with expired record' => sub {
211 $newname = 'expired1.expiry1.test';
212 ($code, $msg) = $dnsdb->addRec('n', 'n', 4, \$newname, \$rectype, \$newval, 900);
213 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
214 if ($code eq 'FAIL') {
215 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 4 AND host = '$newname'");
216 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
217 like( $msg, qr/non-CNAME records with timestamps already exist/, " ... returned matching error" );
218 }
219 };
220# this test arguably overkill, subsumed by earlier test for nonexpiring collision
221 subtest 'collision with soon to expire record' => sub {
222 $newname = 'expired2.expiry1.test';
223 ($code, $msg) = $dnsdb->addRec('n', 'n', 4, \$newname, \$rectype, \$newval, 900);
224 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
225 if ($code eq 'FAIL') {
226 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 4 AND host = '$newname' AND type <> 5 AND stampactive = 't'");
227 ok( $rcount == 1, " ... [$rcount] record(s) with $newname already exist" );
228# somewhat less overkill if we try to target a unique return based around the expiry bit
229 like( $msg, qr/non-CNAME records with timestamps already exist/, " ... returned matching error" );
230 }
231 };
232 subtest 'collision with pending active-after record' => sub {
233 $newname = 'active-after1.expiry1.test';
234 ($code, $msg) = $dnsdb->addRec('n', 'n', 4, \$newname, \$rectype, \$newval, 900);
235 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed success with warning" );
236 if ($code eq 'FAIL') {
237 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 4 AND host = '$newname'");
238 ok( $rcount == 1, " ... [$rcount] correct number of records for $newname" );
239 like( $msg, qr/non-CNAME records with timestamps already exist/, " ... returned matching error" );
240 }
241 };
242 subtest 'collision with active active-after record' => sub {
243 $newname = 'active-after2.expiry1.test';
244 ($code, $msg) = $dnsdb->addRec('n', 'n', 4, \$newname, \$rectype, \$newval, 900);
245 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
246 if ($code eq 'FAIL') {
247 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 4 AND host = '$newname' AND type <> 5");
248 ok( $rcount == 1, " ... [$rcount] record(s) with $newname already exist" );
249 like( $msg, qr/non-CNAME records with timestamps already exist/, " ... returned matching error" );
250 }
251 };
252 }; # add non-timestamp CNAME
253
254 ## Add expiring CNAME
255 subtest 'CNAME add - expires soon' => sub {
256 my @ltime = localtime(time + 86400 * 3);
257 $expirystamp = sprintf "%i-%i-%i %i:%i", $ltime[5] + 1900, ($ltime[4] + 1) % 12, $ltime[3], 15, $ltime[1];
258 $newval = 'target.example.com';
259 subtest 'collision with nonexpiring record' => sub {
260 $newname = 'expires-at1.expiry2.test';
261 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
262 ok($code eq 'FAIL', "addRec() claimed failure");
263 if ($code eq 'FAIL') {
264 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname'");
265 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
266 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
267 }
268 };
269 subtest 'collision with record with pending expiry' => sub {
270 $newname = 'expires-at2.expiry2.test';
271 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
272 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure");
273 if ($code eq 'FAIL') {
274 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname' AND type <> 5");
275 ok( $rcount == 1, " ... [$rcount] record(s) with $newname already exist" );
276 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
277 }
278 };
279 subtest 'expire before valid-after record' => sub {
280 $newname = 'expires-at3.expiry2.test';
281 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
282 cmp_ok( $code, 'eq', 'OK', "addRec() claimed success" );
283 if ($code eq 'OK') {
284 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname'");
285 ok( $rcount == 2, " ... [$rcount] correct number of records for $newname" );
286 my ($newstamp) = $dbh->selectrow_array("SELECT extract(epoch from stamp) FROM records WHERE domain_id = 5 AND host = '$newname' ".
287 "AND stampactive = 't' AND expires = 't'");
288 my ($oldstamp) = $dbh->selectrow_array("SELECT extract(epoch from stamp) FROM records WHERE domain_id = 5 AND host = '$newname' ".
289 "AND stampactive = 't' AND expires = 'f'");
290 ok( $newstamp <= $oldstamp, " ... added record expires before existing active-after record goes active" );
291 } else {
292 print "not ok: $msg";
293 }
294 };
295 subtest 'expire after valid-after record' => sub {
296 $newname = 'expires-at4.expiry2.test';
297 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
298 cmp_ok( $code, 'eq', 'WARN', "addRec() claimed success with warning" );
299 if ($code eq 'WARN') {
300 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname'");
301 ok( $rcount == 2, " ... [$rcount] correct number of records for $newname" );
302 like( $msg, qr/added with modified expiry time; conflicting valid-after record found/, " ... returned appropriate warning message" );
303 my ($newstamp) = $dbh->selectrow_array("SELECT stamp FROM records WHERE domain_id = 5 AND host = '$newname' ".
304 "AND stampactive = 't' AND expires = 't'");
305 my ($oldstamp) = $dbh->selectrow_array("SELECT stamp FROM records WHERE domain_id = 5 AND host = '$newname' ".
306 "AND stampactive = 't' AND expires = 'f'");
307 ok( $newstamp eq $oldstamp, " ... coerced timestamp matches existing active-after timestamp" );
308 } else {
309 print "not ok: $msg";
310 }
311 };
312 subtest 'collision with expired record' => sub {
313 $newname = 'expires-at5.expiry2.test';
314 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
315 ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
316 if ($code eq 'FAIL') {
317 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname'");
318 ok( $rcount == 1, " ... [$rcount] correct number of records for $newname" );
319 like( $msg, qr/non-CNAME records with timestamps already exist/, " ... returned matching error" );
320 }
321 };
322 }; # add expiring CNAME
323
324 ## Add valid-after CNAME
325 subtest 'CNAME add - valid after' => sub {
326 my @ltime = localtime(time + 86400 * 3);
327 $expirystamp = sprintf "%i-%i-%i %i:%i", $ltime[5] + 1900, ($ltime[4] + 1) % 12, $ltime[3], 15, $ltime[1];
328 $newval = 'target.example.com';
329 subtest 'collision with nonexpiring record' => sub {
330 $newname = 'valid-after1.expiry2.test';
331 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 'f', $expirystamp);
332 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
333 if ($code eq 'FAIL') {
334 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname'");
335 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
336 like( $msg, qr/One or more non-CNAME records already exist/, " ... returned matching error" );
337 }
338 };
339 subtest 'valid before expiring record' => sub {
340 $newname = 'valid-after2.expiry2.test';
341 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 'f', $expirystamp);
342 cmp_ok( $code, 'eq', 'WARN', "addRec() claimed failure" );
343 if ($code eq 'WARN') {
344 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname'");
345 ok( $rcount == 2, " ... [$rcount] record(s) with $newname found" );
346 like( $msg, qr/modified valid-after time; conflicting expiring record found/, " ... returned matching error" );
347 my ($newstamp) = $dbh->selectrow_array("SELECT extract(epoch from stamp) FROM records WHERE domain_id = 5 ".
348 "AND host = '$newname' AND stampactive = 't' AND expires = 't'");
349 my ($oldstamp) = $dbh->selectrow_array("SELECT extract(epoch from stamp) FROM records WHERE domain_id = 5 ".
350 "AND host = '$newname' AND stampactive = 't' AND expires = 'f'");
351 cmp_ok( $newstamp, '>=', $oldstamp, " ... coerced timestamp equal or later than existing expiry timestamp" );
352 } else {
353 print "not ok: $msg";
354 }
355 };
356 subtest 'valid after valid-after record' => sub {
357 $newname = 'valid-after3.expiry2.test';
358 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 'f', $expirystamp);
359 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
360 if ($code eq 'FAIL') {
361 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname'");
362 ok( $rcount == 1, " ... [$rcount] correct number of records for $newname" );
363 like( $msg, qr/non-CNAME records with timestamps already exist for/, " ... returned matching error" );
364 }
365 };
366 subtest 'valid before existing valid-after record' => sub {
367 $newname = 'valid-after4.expiry2.test';
368 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 'f', $expirystamp);
369 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
370 if ($code eq 'FAIL') {
371 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname'");
372 ok( $rcount == 1, " ... [$rcount] correct number of records for $newname" );
373 like( $msg, qr/non-CNAME records with timestamps already exist for/, " ... returned matching error" );
374 }
375 };
376 subtest 'valid after expiring record' => sub {
377 $newname = 'valid-after5.expiry2.test';
378 ($code, $msg) = $dnsdb->addRec('n', 'n', 5, \$newname, \$rectype, \$newval, 900, undef, 'f', $expirystamp);
379 cmp_ok( $code, 'eq', 'OK', "addRec() claimed success" );
380 if ($code eq 'OK') {
381 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 5 AND host = '$newname'");
382 ok( $rcount == 2, " ... [$rcount] correct number of records for $newname" );
383 } else {
384 print "not ok: $msg\n";
385 }
386 };
387 }; # add valid-after CNAME
388
389 ## Tests calling updateRec() instead of addRec()
390 subtest 'Update to CNAME - no timestamp' => sub {
391 $newval = 'target.example.com';
392 subtest 'collision with expired record' => sub {
393 $newname = 'nostamp1a.expiry3.test';
394 ($code, $msg) = $dnsdb->updateRec('n', 'n', 79, 6, \$newname, \$rectype, \$newval, 900);
395 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure" );
396 if ($code eq 'FAIL') {
397 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
398 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
399 like( $msg, qr/non-CNAME records with timestamps already exist/, " ... returned matching error" );
400 }
401 };
402 subtest 'collision with soon to expire record' => sub {
403 $newname = 'nostamp2a.expiry3.test';
404 ($code, $msg) = $dnsdb->updateRec('n', 'n', 80, 6, \$newname, \$rectype, \$newval, 900);
405 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure" );
406 if ($code eq 'FAIL') {
407 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
408 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
409 like( $msg, qr/non-CNAME records with timestamps already exist/, " ... returned matching error" );
410 }
411 };
412 subtest 'collision with pending active-after record' => sub {
413 $newname = 'nostamp3a.expiry3.test';
414 ($code, $msg) = $dnsdb->updateRec('n', 'n', 81, 6, \$newname, \$rectype, \$newval, 900);
415 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure" );
416 if ($code eq 'FAIL') {
417 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
418 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
419 like( $msg, qr/non-CNAME records with timestamps already exist/, " ... returned matching error" );
420 }
421 };
422 subtest 'collision with active active-after record' => sub {
423 $newname = 'nostamp4a.expiry3.test';
424 ($code, $msg) = $dnsdb->updateRec('n', 'n', 82, 6, \$newname, \$rectype, \$newval, 900);
425 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure" );
426 if ($code eq 'FAIL') {
427 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
428 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
429 like( $msg, qr/non-CNAME records with timestamps already exist/, " ... returned matching error" );
430 }
431 };
432 }; # update to CNAME with no timestamp
433
434 subtest 'CNAME update - expires soon' => sub {
435 my @ltime = localtime(time + 86400 * 3);
436 $expirystamp = sprintf "%i-%i-%i %i:%i", $ltime[5] + 1900, ($ltime[4] + 1) % 12, $ltime[3], 15, $ltime[1];
437 $newval = 'target.example.com';
438 subtest 'collision with nonexpiring record' => sub {
439 $newname = 'expires1a.expiry3.test';
440 ($code, $msg) = $dnsdb->updateRec('n', 'n', 89, 6, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
441 ok($code eq 'FAIL', "updateRec() claimed failure");
442 if ($code eq 'FAIL') {
443 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
444 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
445 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
446 }
447 };
448 subtest 'collision with expiring record' => sub {
449 $newname = 'expires2a.expiry3.test';
450 ($code, $msg) = $dnsdb->updateRec('n', 'n', 90, 6, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
451 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure");
452 if ($code eq 'FAIL') {
453 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname' AND type <> 5");
454 ok( $rcount == 1, " ... [$rcount] record(s) with $newname already exist" );
455 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
456 }
457 };
458 subtest 'collision with expired record' => sub {
459 $newname = 'expires3a.expiry3.test';
460 ($code, $msg) = $dnsdb->updateRec('n', 'n', 91, 6, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
461 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure" );
462 if ($code eq 'FAIL') {
463 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
464 ok( $rcount == 1, " ... [$rcount] correct number of records for $newname" );
465 like( $msg, qr/non-CNAME records with timestamps already exist/, " ... returned matching error" );
466 }
467 };
468 subtest 'expire after pending valid-after record' => sub {
469 $newname = 'expires4a.expiry3.test';
470 ($code, $msg) = $dnsdb->updateRec('n', 'n', 92, 6, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
471 cmp_ok( $code, 'eq', 'WARN', "updateRec() claimed success with warning" );
472 if ($code eq 'WARN') {
473 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
474 ok( $rcount == 2, " ... [$rcount] correct number of records for $newname" );
475 like( $msg, qr/updated with modified expiry time; conflicting valid-after record found/, " ... returned appropriate warning message" );
476 my ($newstamp) = $dbh->selectrow_array("SELECT stamp FROM records WHERE domain_id = 6 AND host = '$newname' ".
477 "AND stampactive = 't' AND expires = 't'");
478 my ($oldstamp) = $dbh->selectrow_array("SELECT stamp FROM records WHERE domain_id = 6 AND host = '$newname' ".
479 "AND stampactive = 't' AND expires = 'f'");
480 ok( $newstamp eq $oldstamp, " ... coerced timestamp matches existing active-after timestamp" );
481 } else {
482 print "not ok: $msg";
483 }
484 };
485 subtest 'expire after active valid-after record' => sub {
486 $newname = 'expires5a.expiry3.test';
487 ($code, $msg) = $dnsdb->updateRec('n', 'n', 93, 6, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
488 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure" );
489 if ($code eq 'FAIL') {
490 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
491 ok( $rcount == 1, " ... [$rcount] correct number of records for $newname" );
492 like( $msg, qr/existing valid-after record is already active for this name/, " ... returned matching error" );
493 }
494 };
495 subtest 'expire before valid-after record' => sub {
496 $newname = 'expires6a.expiry3.test';
497 ($code, $msg) = $dnsdb->updateRec('n', 'n', 94, 6, \$newname, \$rectype, \$newval, 900, undef, 't', $expirystamp);
498 cmp_ok( $code, 'eq', 'OK', "updateRec() claimed success" );
499 if ($code eq 'OK') {
500 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
501 ok( $rcount == 2, " ... [$rcount] correct number of records for $newname" );
502 my ($newstamp) = $dbh->selectrow_array("SELECT extract(epoch from stamp) FROM records WHERE domain_id = 6 AND host = '$newname' ".
503 "AND stampactive = 't' AND expires = 't'");
504 my ($oldstamp) = $dbh->selectrow_array("SELECT extract(epoch from stamp) FROM records WHERE domain_id = 6 AND host = '$newname' ".
505 "AND stampactive = 't' AND expires = 'f'");
506 ok( $newstamp <= $oldstamp, " ... added record expires before existing active-after record goes active" );
507 } else {
508 print "not ok: $msg";
509 }
510 };
511 }; # update to expiring CNAME
512
513 ## Update to valid-after CNAME
514 subtest 'CNAME update - valid after' => sub {
515 my @ltime = localtime(time + 86400 * 3);
516 $expirystamp = sprintf "%i-%i-%i %i:%i", $ltime[5] + 1900, ($ltime[4] + 1) % 12, $ltime[3], 15, $ltime[1];
517 $newval = 'target.example.com';
518 subtest 'collision with nonexpiring record' => sub {
519 $newname = 'validafter1a.expiry3.test';
520 ($code, $msg) = $dnsdb->updateRec('n', 'n', 100, 6, \$newname, \$rectype, \$newval, 900, undef, 'f', $expirystamp);
521 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure" );
522 if ($code eq 'FAIL') {
523 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
524 ok( $rcount == 1, " ... [$rcount] yep, hostname only occurs once" );
525 like( $msg, qr/One or more non-CNAME records/, " ... returned matching error" );
526 }
527 };
528 subtest 'collision with expiring record, overlapping timestamps' => sub {
529 $newname = 'validafter2a.expiry3.test';
530 ($code, $msg) = $dnsdb->updateRec('n', 'n', 101, 6, \$newname, \$rectype, \$newval, 900, undef, 'f', $expirystamp);
531 cmp_ok( $code, 'eq', 'WARN', "updateRec() claimed success with warning" );
532 if ($code eq 'WARN') {
533 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
534 ok( $rcount == 2, " ... [$rcount] correct number of records for $newname" );
535 like( $msg, qr/updated with modified valid-after time; conflicting expiring record found/, " ... returned appropriate warning message" );
536 my ($newstamp) = $dbh->selectrow_array("SELECT stamp FROM records WHERE domain_id = 6 AND host = '$newname' ".
537 "AND stampactive = 't' AND expires = 't'");
538 my ($oldstamp) = $dbh->selectrow_array("SELECT stamp FROM records WHERE domain_id = 6 AND host = '$newname' ".
539 "AND stampactive = 't' AND expires = 'f'");
540 ok( $newstamp eq $oldstamp, " ... coerced timestamp matches existing expiry timestamp" );
541 } else {
542 print "not ok: $msg";
543 }
544 };
545 subtest 'collision with expiring record, non-overlapping timestamps' => sub {
546 $newname = 'validafter3a.expiry3.test';
547 ($code, $msg) = $dnsdb->updateRec('n', 'n', 102, 6, \$newname, \$rectype, \$newval, 900, undef, 'f', $expirystamp);
548 cmp_ok( $code, 'eq', 'OK', "updateRec() claimed success" );
549 if ($code eq 'OK') {
550 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
551 ok( $rcount == 2, " ... [$rcount] correct number of records for $newname" );
552 my ($newstamp) = $dbh->selectrow_array("SELECT extract(epoch from stamp) FROM records WHERE domain_id = 6 AND host = '$newname' ".
553 "AND stampactive = 't' AND expires = 't'");
554 my ($oldstamp) = $dbh->selectrow_array("SELECT extract(epoch from stamp) FROM records WHERE domain_id = 6 AND host = '$newname' ".
555 "AND stampactive = 't' AND expires = 'f'");
556 ok( $newstamp <= $oldstamp, " ... added record becomes active after existing record expires" );
557 } else {
558 print "not ok: $msg";
559 }
560 };
561 subtest 'valid before pending valid-after record' => sub {
562 $newname = 'validafter4a.expiry3.test';
563 ($code, $msg) = $dnsdb->updateRec('n', 'n', 103, 6, \$newname, \$rectype, \$newval, 900, undef, 'f', $expirystamp);
564 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure" );
565 if ($code eq 'FAIL') {
566 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
567 ok( $rcount == 1, " ... [$rcount] correct number of records for $newname" );
568 like( $msg, qr/non-CNAME records with timestamps already exist/, " ... returned matching error" );
569 }
570 };
571 subtest 'valid after active valid-after record' => sub {
572 $newname = 'validafter5a.expiry3.test';
573 ($code, $msg) = $dnsdb->updateRec('n', 'n', 104, 6, \$newname, \$rectype, \$newval, 900, undef, 'f', $expirystamp);
574 cmp_ok( $code, 'eq', 'FAIL', "updateRec() claimed failure" );
575 if ($code eq 'FAIL') {
576 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 6 AND host = '$newname'");
577 ok( $rcount == 1, " ... [$rcount] correct number of records for $newname" );
578 like( $msg, qr/non-CNAME records with timestamps already exist/, " ... returned matching error" );
579 }
580 };
581 }; # update to valid-after CNAME
582
583}; # record expiry/valid-after
584
585
586## Double-check non-CNAMEs colliding with CNAMEs, and not each other
587subtest "New records colliding with CNAMEs" => sub {
588 $rectype = 1; # Any type will do, since all the checks based on type are "CNAME" and "not-CNAME"
589
590 subtest "Non-expiring new record" => sub {
591 subtest "New record vs non-CNAME" => sub {
592 $newname = 'blocker01.cname-blocks1.test';
593 $newval = '192.168.2.1';
594 ($code, $msg) = $dnsdb->addRec('n', 'n', 7, \$newname, \$rectype, \$newval, 900);
595 cmp_ok( $code, 'eq', 'OK', "addRec() claimed succeess" );
596 if ($code eq 'OK') {
597 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 7 AND host = '$newname'");
598 ok( $rcount == 2, " ... [$rcount] yep, hostname now occurs twice" );
599 } else {
600 print "not ok: $msg";
601 }
602 };
603 subtest "New record vs non-timestamped CNAME" => sub {
604 $newname = 'blocker02.cname-blocks1.test';
605 $newval = '192.168.2.2';
606 ($code, $msg) = $dnsdb->addRec('n', 'n', 7, \$newname, \$rectype, \$newval, 900);
607 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
608 if ($code eq 'FAIL') {
609 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 7 AND host = '$newname'");
610 cmp_ok( $rcount, '==', 1, " ... [$rcount] record(s) with $newname already exist" );
611 like( $msg, qr/There is already a CNAME present/, " ... returned matching error" );
612 }
613 };
614 subtest "New record vs expiring CNAME" => sub {
615 $newname = 'blocker03.cname-blocks1.test';
616 $newval = '192.168.2.3';
617 ($code, $msg) = $dnsdb->addRec('n', 'n', 7, \$newname, \$rectype, \$newval, 900);
618 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
619 if ($code eq 'FAIL') {
620 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 7 AND host = '$newname'");
621 cmp_ok( $rcount, '==', 1, " ... [$rcount] record(s) with $newname already exist" );
622 like( $msg, qr/There is already a CNAME with a timestamp present/, " ... returned matching error" );
623 }
624 };
625 subtest "New record vs valid-after CNAME" => sub {
626 $newname = 'blocker04.cname-blocks1.test';
627 $newval = '192.168.2.4';
628 ($code, $msg) = $dnsdb->addRec('n', 'n', 7, \$newname, \$rectype, \$newval, 900);
629 cmp_ok( $code, 'eq', 'FAIL', "addRec() claimed failure" );
630 if ($code eq 'FAIL') {
631 ($rcount) = $dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = 7 AND host = '$newname'");
632 cmp_ok( $rcount, '==', 1, " ... [$rcount] record(s) with $newname already exist" );
633 like( $msg, qr/There is already a CNAME with a timestamp present/, " ... returned matching error" );
634 }
635 };
636 }; # non-expiring non-CNAMEs
637
638}; # non-CNAMEs colliding with CNAMEs
639
640
641done_testing();
Note: See TracBrowser for help on using the repository browser.