]> git.ipfire.org Git - thirdparty/pdns.git/blame - regression-tests.dnsdist/test_Caching.py
dnsdist tests: make py3k compatible and pick py3k if available
[thirdparty/pdns.git] / regression-tests.dnsdist / test_Caching.py
CommitLineData
903853f4 1#!/usr/bin/env python
1ea747c0 2import base64
903853f4
RG
3import time
4import dns
5from dnsdisttests import DNSDistTest
6
7class TestCaching(DNSDistTest):
8
9 _config_template = """
fe1c60f2 10 pc = newPacketCache(100, 86400, 1)
903853f4
RG
11 getPool(""):setCache(pc)
12 addAction(makeRule("nocache.cache.tests.powerdns.com."), SkipCacheAction())
816dff3d
RG
13 function skipViaLua(dq)
14 dq.skipCache = true
15 return DNSAction.None, ""
16 end
a2ff35e3 17 addAction("nocachevialua.cache.tests.powerdns.com.", LuaAction(skipViaLua))
903853f4
RG
18 newServer{address="127.0.0.1:%s"}
19 """
fe1c60f2 20
903853f4
RG
21 def testCached(self):
22 """
23 Cache: Served from cache
24
25 dnsdist is configured to cache entries, we are sending several
26 identical requests and checking that the backend only receive
27 the first one.
28 """
29 numberOfQueries = 10
30 name = 'cached.cache.tests.powerdns.com.'
31 query = dns.message.make_query(name, 'AAAA', 'IN')
32 response = dns.message.make_response(query)
33 rrset = dns.rrset.from_text(name,
34 3600,
35 dns.rdataclass.IN,
36 dns.rdatatype.AAAA,
37 '::1')
38 response.answer.append(rrset)
39
40 # first query to fill the cache
41 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
42 self.assertTrue(receivedQuery)
43 self.assertTrue(receivedResponse)
44 receivedQuery.id = query.id
45 self.assertEquals(query, receivedQuery)
46 self.assertEquals(receivedResponse, response)
47
48 for _ in range(numberOfQueries):
49 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
50 self.assertEquals(receivedResponse, response)
51
52 total = 0
02bbf9eb
RG
53 for key in self._responsesCounter:
54 total += self._responsesCounter[key]
903853f4
RG
55 TestCaching._responsesCounter[key] = 0
56
57 self.assertEquals(total, 1)
58
59 # TCP should not be cached
60 # first query to fill the cache
61 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
62 self.assertTrue(receivedQuery)
63 self.assertTrue(receivedResponse)
64 receivedQuery.id = query.id
65 self.assertEquals(query, receivedQuery)
66 self.assertEquals(receivedResponse, response)
67
68 for _ in range(numberOfQueries):
69 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
70 self.assertEquals(receivedResponse, response)
71
72 total = 0
02bbf9eb
RG
73 for key in self._responsesCounter:
74 total += self._responsesCounter[key]
903853f4
RG
75 TestCaching._responsesCounter[key] = 0
76
77 self.assertEquals(total, 1)
78
79 def testSkipCache(self):
80 """
81 Cache: SkipCacheAction
82
83 dnsdist is configured to not cache entries for nocache.cache.tests.powerdns.com.
84 we are sending several requests and checking that the backend get them all.
85 """
86 name = 'nocache.cache.tests.powerdns.com.'
87 numberOfQueries = 10
88 query = dns.message.make_query(name, 'AAAA', 'IN')
89 response = dns.message.make_response(query)
816dff3d
RG
90 rrset = dns.rrset.from_text(name,
91 3600,
92 dns.rdataclass.IN,
93 dns.rdatatype.AAAA,
94 '::1')
95 response.answer.append(rrset)
96
97 for _ in range(numberOfQueries):
98 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
99 self.assertTrue(receivedQuery)
100 self.assertTrue(receivedResponse)
101 receivedQuery.id = query.id
102 self.assertEquals(query, receivedQuery)
103 self.assertEquals(receivedResponse, response)
104
105 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
106 self.assertTrue(receivedQuery)
107 self.assertTrue(receivedResponse)
108 receivedQuery.id = query.id
109 self.assertEquals(query, receivedQuery)
110 self.assertEquals(receivedResponse, response)
111
02bbf9eb
RG
112 for key in self._responsesCounter:
113 value = self._responsesCounter[key]
816dff3d
RG
114 self.assertEquals(value, numberOfQueries)
115
116 def testSkipCacheViaLua(self):
117 """
118 Cache: SkipCache via Lua
119
120 dnsdist is configured to not cache entries for nocachevialua.cache.tests.powerdns.com.
121 we are sending several requests and checking that the backend get them all.
122 """
123 name = 'nocachevialua.cache.tests.powerdns.com.'
124 numberOfQueries = 10
125 query = dns.message.make_query(name, 'AAAA', 'IN')
126 response = dns.message.make_response(query)
903853f4
RG
127 rrset = dns.rrset.from_text(name,
128 3600,
129 dns.rdataclass.IN,
130 dns.rdatatype.AAAA,
131 '::1')
132 response.answer.append(rrset)
133
134 for _ in range(numberOfQueries):
135 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
136 self.assertTrue(receivedQuery)
137 self.assertTrue(receivedResponse)
138 receivedQuery.id = query.id
139 self.assertEquals(query, receivedQuery)
140 self.assertEquals(receivedResponse, response)
141
142 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
143 self.assertTrue(receivedQuery)
144 self.assertTrue(receivedResponse)
145 receivedQuery.id = query.id
146 self.assertEquals(query, receivedQuery)
147 self.assertEquals(receivedResponse, response)
148
02bbf9eb
RG
149 for key in self._responsesCounter:
150 value = self._responsesCounter[key]
903853f4
RG
151 self.assertEquals(value, numberOfQueries)
152
153 def testCacheExpiration(self):
154 """
155 Cache: Cache expiration
156
157 dnsdist is configured to cache entries, we are sending one request
158 (cache miss) with a very short TTL, checking that the next requests
159 are cached. Then we wait for the TTL to expire, check that the
160 next request is a miss but the following one a hit.
161 """
162 ttl = 2
163 misses = 0
164 name = 'cacheexpiration.cache.tests.powerdns.com.'
165 query = dns.message.make_query(name, 'AAAA', 'IN')
166 response = dns.message.make_response(query)
167 rrset = dns.rrset.from_text(name,
168 ttl,
169 dns.rdataclass.IN,
170 dns.rdatatype.AAAA,
171 '::1')
172 response.answer.append(rrset)
173
174 # first query to fill the cache
175 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
176 self.assertTrue(receivedQuery)
177 self.assertTrue(receivedResponse)
178 receivedQuery.id = query.id
179 self.assertEquals(query, receivedQuery)
180 self.assertEquals(receivedResponse, response)
181 misses += 1
182
183 # next queries should hit the cache
184 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
185 self.assertEquals(receivedResponse, response)
186
187 # now we wait a bit for the cache entry to expire
188 time.sleep(ttl + 1)
189
190 # next query should be a miss, fill the cache again
191 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
192 self.assertTrue(receivedQuery)
193 self.assertTrue(receivedResponse)
194 receivedQuery.id = query.id
195 self.assertEquals(query, receivedQuery)
196 self.assertEquals(receivedResponse, response)
197 misses += 1
198
199 # following queries should hit the cache again
200 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
201 self.assertEquals(receivedResponse, response)
202
203 total = 0
02bbf9eb
RG
204 for key in self._responsesCounter:
205 total += self._responsesCounter[key]
903853f4
RG
206
207 self.assertEquals(total, misses)
208
209 def testCacheExpirationDifferentSets(self):
210 """
211 Cache: Cache expiration with different sets
212
213 dnsdist is configured to cache entries, we are sending one request
214 (cache miss) whose response has a long and a very short TTL,
215 checking that the next requests are cached. Then we wait for the
216 short TTL to expire, check that the
217 next request is a miss but the following one a hit.
218 """
219 ttl = 2
220 misses = 0
221 name = 'cacheexpirationdifferentsets.cache.tests.powerdns.com.'
222 query = dns.message.make_query(name, 'AAAA', 'IN')
223 response = dns.message.make_response(query)
224 rrset = dns.rrset.from_text(name,
225 ttl,
226 dns.rdataclass.IN,
227 dns.rdatatype.CNAME,
228 'cname.cacheexpirationdifferentsets.cache.tests.powerdns.com.')
229 response.answer.append(rrset)
230 rrset = dns.rrset.from_text('cname.cacheexpirationdifferentsets.cache.tests.powerdns.com.',
231 ttl + 3600,
232 dns.rdataclass.IN,
233 dns.rdatatype.A,
234 '192.2.0.1')
235 response.additional.append(rrset)
236
237 # first query to fill the cache
238 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
239 self.assertTrue(receivedQuery)
240 self.assertTrue(receivedResponse)
241 receivedQuery.id = query.id
242 self.assertEquals(query, receivedQuery)
243 self.assertEquals(receivedResponse, response)
244 misses += 1
245
246 # next queries should hit the cache
247 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
248 self.assertEquals(receivedResponse, response)
249
250 # now we wait a bit for the cache entry to expire
251 time.sleep(ttl + 1)
252
253 # next query should be a miss, fill the cache again
254 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
255 self.assertTrue(receivedQuery)
256 self.assertTrue(receivedResponse)
257 receivedQuery.id = query.id
258 self.assertEquals(query, receivedQuery)
259 self.assertEquals(receivedResponse, response)
260 misses += 1
261
262 # following queries should hit the cache again
263 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
264 self.assertEquals(receivedResponse, response)
265
266 total = 0
02bbf9eb
RG
267 for key in self._responsesCounter:
268 total += self._responsesCounter[key]
903853f4
RG
269
270 self.assertEquals(total, misses)
271
272 def testCacheDecreaseTTL(self):
273 """
274 Cache: Cache decreases TTL
275
276 dnsdist is configured to cache entries, we are sending one request
277 (cache miss) and verify that the cache hits have a decreasing TTL.
278 """
279 ttl = 600
280 misses = 0
281 name = 'cachedecreasettl.cache.tests.powerdns.com.'
282 query = dns.message.make_query(name, 'AAAA', 'IN')
283 response = dns.message.make_response(query)
284 rrset = dns.rrset.from_text(name,
285 ttl,
286 dns.rdataclass.IN,
287 dns.rdatatype.AAAA,
288 '::1')
289 response.answer.append(rrset)
290
291 # first query to fill the cache
292 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
293 self.assertTrue(receivedQuery)
294 self.assertTrue(receivedResponse)
295 receivedQuery.id = query.id
296 self.assertEquals(query, receivedQuery)
297 self.assertEquals(receivedResponse, response)
298 misses += 1
299
300 # next queries should hit the cache
301 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
302 self.assertEquals(receivedResponse, response)
303 for an in receivedResponse.answer:
304 self.assertTrue(an.ttl <= ttl)
305
306 # now we wait a bit for the TTL to decrease
307 time.sleep(1)
308
309 # next queries should hit the cache
310 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
311 self.assertEquals(receivedResponse, response)
312 for an in receivedResponse.answer:
313 self.assertTrue(an.ttl < ttl)
314
315 total = 0
02bbf9eb
RG
316 for key in self._responsesCounter:
317 total += self._responsesCounter[key]
903853f4
RG
318
319 self.assertEquals(total, misses)
320
321 def testCacheDifferentCase(self):
322 """
323 Cache: Cache matches different case
324
325 dnsdist is configured to cache entries, we are sending one request
326 (cache miss) and verify that the same one with a different case
327 matches.
328 """
329 ttl = 600
330 name = 'cachedifferentcase.cache.tests.powerdns.com.'
331 differentCaseName = 'CacheDifferentCASE.cache.tests.powerdns.com.'
332 query = dns.message.make_query(name, 'AAAA', 'IN')
333 differentCaseQuery = dns.message.make_query(differentCaseName, 'AAAA', 'IN')
334 response = dns.message.make_response(query)
335 differentCaseResponse = dns.message.make_response(differentCaseQuery)
336 rrset = dns.rrset.from_text(name,
337 ttl,
338 dns.rdataclass.IN,
339 dns.rdatatype.AAAA,
340 '::1')
341 response.answer.append(rrset)
342 differentCaseResponse.answer.append(rrset)
343
344 # first query to fill the cache
345 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
346 self.assertTrue(receivedQuery)
347 self.assertTrue(receivedResponse)
348 receivedQuery.id = query.id
349 self.assertEquals(query, receivedQuery)
350 self.assertEquals(receivedResponse, response)
351
352 # different case query should still hit the cache
353 (_, receivedResponse) = self.sendUDPQuery(differentCaseQuery, response=None, useQueue=False)
354 self.assertEquals(receivedResponse, differentCaseResponse)
355
356
a2c4a339
CH
357class TestTempFailureCacheTTLAction(DNSDistTest):
358
359 _config_template = """
360 pc = newPacketCache(100, 86400, 1)
361 getPool(""):setCache(pc)
362 addAction("servfail.cache.tests.powerdns.com.", TempFailureCacheTTLAction(1))
363 newServer{address="127.0.0.1:%s"}
364 """
365
366 def testTempFailureCacheTTLAction(self):
367 """
368 Cache: When a TempFailure TTL is set, it should be honored
369
370 dnsdist is configured to cache packets, plus a specific qname is
371 set up with a lower TempFailure Cache TTL. we are sending one request
372 (cache miss) and verify that the cache is hit for the following query,
373 but the TTL then expires before the larger "good" packetcache TTL.
374 """
375 name = 'servfail.cache.tests.powerdns.com.'
376 query = dns.message.make_query(name, 'AAAA', 'IN')
377 response = dns.message.make_response(query)
378 response.set_rcode(dns.rcode.SERVFAIL)
379
380 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
381 self.assertTrue(receivedQuery)
382 self.assertTrue(receivedResponse)
383 receivedQuery.id = query.id
384 self.assertEquals(query, receivedQuery)
385 self.assertEquals(receivedResponse, response)
386
387 # next query should hit the cache
45fc7a50 388 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
a2c4a339
CH
389 self.assertFalse(receivedQuery)
390 self.assertTrue(receivedResponse)
391 self.assertEquals(receivedResponse, response)
392
393 # now we wait a bit for the Failure-Cache TTL to expire
394 time.sleep(2)
395
396 # next query should NOT hit the cache
397 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
398 self.assertTrue(receivedQuery)
399 self.assertTrue(receivedResponse)
400 self.assertEquals(receivedResponse, response)
401
402
903853f4
RG
403class TestCachingWithExistingEDNS(DNSDistTest):
404
405 _config_template = """
406 pc = newPacketCache(5, 86400, 1)
407 getPool(""):setCache(pc)
408 newServer{address="127.0.0.1:%s"}
409 """
410 def testCacheWithEDNS(self):
411 """
412 Cache: Cache should not match different EDNS value
413
414 dnsdist is configured to cache entries, we are sending one request
415 (cache miss) and verify that the same one with a different EDNS UDP
416 Payload size is not served from the cache.
417 """
418 misses = 0
419 name = 'cachedifferentedns.cache.tests.powerdns.com.'
420 query = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=512)
421 response = dns.message.make_response(query)
422 rrset = dns.rrset.from_text(name,
423 3600,
424 dns.rdataclass.IN,
425 dns.rdatatype.A,
426 '127.0.0.1')
427 response.answer.append(rrset)
428
429 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
430 self.assertTrue(receivedQuery)
431 self.assertTrue(receivedResponse)
432 receivedQuery.id = query.id
433 self.assertEquals(query, receivedQuery)
434 self.assertEquals(response, receivedResponse)
435 misses += 1
436
437 query = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096)
438 response = dns.message.make_response(query)
439 rrset = dns.rrset.from_text(name,
440 3600,
441 dns.rdataclass.IN,
442 dns.rdatatype.A,
443 '127.0.0.1')
444 response.answer.append(rrset)
445
446 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
447 self.assertTrue(receivedQuery)
448 self.assertTrue(receivedResponse)
449 receivedQuery.id = query.id
450 self.assertEquals(query, receivedQuery)
451 self.assertEquals(response, receivedResponse)
452 misses += 1
453
454 total = 0
02bbf9eb
RG
455 for key in self._responsesCounter:
456 total += self._responsesCounter[key]
903853f4
RG
457
458 self.assertEquals(total, misses)
fe1c60f2
RG
459
460class TestCachingCacheFull(DNSDistTest):
461
462 _config_template = """
463 pc = newPacketCache(1, 86400, 1)
464 getPool(""):setCache(pc)
465 newServer{address="127.0.0.1:%s"}
466 """
467 def testCacheFull(self):
468 """
469 Cache: No new entries are cached when the cache is full
470
471 """
472 misses = 0
473 name = 'cachenotfullyet.cache.tests.powerdns.com.'
474 query = dns.message.make_query(name, 'A', 'IN')
475 response = dns.message.make_response(query)
476 rrset = dns.rrset.from_text(name,
477 3600,
478 dns.rdataclass.IN,
479 dns.rdatatype.A,
480 '127.0.0.1')
481 response.answer.append(rrset)
482
483 # Miss
484 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
485 self.assertTrue(receivedQuery)
486 self.assertTrue(receivedResponse)
487 receivedQuery.id = query.id
488 self.assertEquals(query, receivedQuery)
489 self.assertEquals(response, receivedResponse)
490 misses += 1
491
492 # next queries should hit the cache
493 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
494 self.assertEquals(receivedResponse, response)
495
496 # ok, now the cache is full, send another query
497 name = 'cachefull.cache.tests.powerdns.com.'
498 query = dns.message.make_query(name, 'AAAA', 'IN')
499 response = dns.message.make_response(query)
500 rrset = dns.rrset.from_text(name,
501 3600,
502 dns.rdataclass.IN,
503 dns.rdatatype.AAAA,
504 '::1')
505 response.answer.append(rrset)
506
507 # Miss
508 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
509 self.assertTrue(receivedQuery)
510 self.assertTrue(receivedResponse)
511 receivedQuery.id = query.id
512 self.assertEquals(query, receivedQuery)
513 self.assertEquals(response, receivedResponse)
514 misses += 1
515
516 # next queries should NOT hit the cache
517 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
518 self.assertTrue(receivedQuery)
519 self.assertTrue(receivedResponse)
520 receivedQuery.id = query.id
521 self.assertEquals(query, receivedQuery)
522 self.assertEquals(response, receivedResponse)
523 misses += 1
524
525 total = 0
02bbf9eb
RG
526 for key in self._responsesCounter:
527 total += self._responsesCounter[key]
fe1c60f2
RG
528
529 self.assertEquals(total, misses)
1ea747c0
RG
530
531class TestCachingNoStale(DNSDistTest):
532
533 _consoleKey = DNSDistTest.generateConsoleKey()
b4f23783 534 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
1ea747c0
RG
535 _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort']
536 _config_template = """
537 pc = newPacketCache(100, 86400, 1)
538 getPool(""):setCache(pc)
539 setKey("%s")
540 controlSocket("127.0.0.1:%s")
541 newServer{address="127.0.0.1:%s"}
542 """
543 def testCacheNoStale(self):
544 """
545 Cache: Cache entry, set backend down, we should not get a stale entry
546
547 """
548 ttl = 1
549 name = 'nostale.cache.tests.powerdns.com.'
550 query = dns.message.make_query(name, 'A', 'IN')
551 response = dns.message.make_response(query)
552 rrset = dns.rrset.from_text(name,
553 1,
554 dns.rdataclass.IN,
555 dns.rdatatype.A,
556 '127.0.0.1')
557 response.answer.append(rrset)
558
559 # Miss
560 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
561 self.assertTrue(receivedQuery)
562 self.assertTrue(receivedResponse)
563 receivedQuery.id = query.id
564 self.assertEquals(query, receivedQuery)
565 self.assertEquals(response, receivedResponse)
566
567 # next queries should hit the cache
568 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
569 self.assertEquals(receivedResponse, response)
570
571 # ok, we mark the backend as down
572 self.sendConsoleCommand("getServer(0):setDown()")
573 # and we wait for the entry to expire
574 time.sleep(ttl + 1)
575
576 # we should NOT get a cached, stale, entry
577 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
578 self.assertEquals(receivedResponse, None)
579
580
581class TestCachingStale(DNSDistTest):
582
583 _consoleKey = DNSDistTest.generateConsoleKey()
b4f23783 584 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
1ea747c0
RG
585 _staleCacheTTL = 60
586 _config_params = ['_staleCacheTTL', '_consoleKeyB64', '_consolePort', '_testServerPort']
587 _config_template = """
588 pc = newPacketCache(100, 86400, 1, %s)
589 getPool(""):setCache(pc)
590 setStaleCacheEntriesTTL(600)
591 setKey("%s")
592 controlSocket("127.0.0.1:%s")
593 newServer{address="127.0.0.1:%s"}
594 """
595 def testCacheStale(self):
596 """
597 Cache: Cache entry, set backend down, get stale entry
598
599 """
600 misses = 0
601 ttl = 1
602 name = 'stale.cache.tests.powerdns.com.'
603 query = dns.message.make_query(name, 'A', 'IN')
604 response = dns.message.make_response(query)
605 rrset = dns.rrset.from_text(name,
606 ttl,
607 dns.rdataclass.IN,
608 dns.rdatatype.A,
609 '127.0.0.1')
610 response.answer.append(rrset)
611
612 # Miss
613 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
614 self.assertTrue(receivedQuery)
615 self.assertTrue(receivedResponse)
616 receivedQuery.id = query.id
617 self.assertEquals(query, receivedQuery)
618 self.assertEquals(response, receivedResponse)
619 misses += 1
620
621 # next queries should hit the cache
622 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
623 self.assertEquals(receivedResponse, response)
624
625 # ok, we mark the backend as down
626 self.sendConsoleCommand("getServer(0):setDown()")
627 # and we wait for the entry to expire
628 time.sleep(ttl + 1)
629
630 # we should get a cached, stale, entry
631 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
632 self.assertEquals(receivedResponse, response)
633 for an in receivedResponse.answer:
634 self.assertEquals(an.ttl, self._staleCacheTTL)
635
636 total = 0
02bbf9eb
RG
637 for key in self._responsesCounter:
638 total += self._responsesCounter[key]
1ea747c0
RG
639
640 self.assertEquals(total, misses)
641
642class TestCacheManagement(DNSDistTest):
643
644 _consoleKey = DNSDistTest.generateConsoleKey()
b4f23783 645 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
1ea747c0
RG
646 _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort']
647 _config_template = """
648 pc = newPacketCache(100, 86400, 1)
649 getPool(""):setCache(pc)
650 setKey("%s")
651 controlSocket("127.0.0.1:%s")
652 newServer{address="127.0.0.1:%s"}
653 """
654 def testCacheExpunge(self):
655 """
656 Cache: Expunge
657
658 """
659 misses = 0
660 ttl = 600
661 name = 'expunge.cache.tests.powerdns.com.'
662 query = dns.message.make_query(name, 'A', 'IN')
663 response = dns.message.make_response(query)
664 rrset = dns.rrset.from_text(name,
665 ttl,
666 dns.rdataclass.IN,
667 dns.rdatatype.A,
668 '127.0.0.1')
669 response.answer.append(rrset)
670
671 # Miss
672 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
673 self.assertTrue(receivedQuery)
674 self.assertTrue(receivedResponse)
675 receivedQuery.id = query.id
676 self.assertEquals(query, receivedQuery)
677 self.assertEquals(response, receivedResponse)
678 misses += 1
679
680 # next queries should hit the cache
681 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
682 self.assertEquals(receivedResponse, response)
683
684 # remove cached entries
685 self.sendConsoleCommand("getPool(\"\"):getCache():expunge(0)")
686
687 # Miss
688 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
689 self.assertTrue(receivedQuery)
690 self.assertTrue(receivedResponse)
691 receivedQuery.id = query.id
692 self.assertEquals(query, receivedQuery)
693 self.assertEquals(response, receivedResponse)
694 misses += 1
695
696 # next queries should hit the cache again
697 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
698 self.assertEquals(receivedResponse, response)
699
700 total = 0
02bbf9eb
RG
701 for key in self._responsesCounter:
702 total += self._responsesCounter[key]
1ea747c0
RG
703
704 self.assertEquals(total, misses)
705
706 def testCacheExpungeByName(self):
707 """
708 Cache: Expunge by name
709
710 """
711 misses = 0
712 ttl = 600
713 name = 'expungebyname.cache.tests.powerdns.com.'
714 query = dns.message.make_query(name, 'A', 'IN')
715 response = dns.message.make_response(query)
716 rrset = dns.rrset.from_text(name,
717 ttl,
718 dns.rdataclass.IN,
719 dns.rdatatype.A,
720 '127.0.0.1')
721 response.answer.append(rrset)
722
723 name2 = 'expungebynameother.cache.tests.powerdns.com.'
724 query2 = dns.message.make_query(name2, 'A', 'IN')
725 response2 = dns.message.make_response(query2)
726 rrset2 = dns.rrset.from_text(name2,
727 ttl,
728 dns.rdataclass.IN,
729 dns.rdatatype.A,
730 '127.0.0.1')
731 response2.answer.append(rrset2)
732
733 # Miss
734 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
735 self.assertTrue(receivedQuery)
736 self.assertTrue(receivedResponse)
737 receivedQuery.id = query.id
738 self.assertEquals(query, receivedQuery)
739 self.assertEquals(response, receivedResponse)
740 misses += 1
741
742 # next queries should hit the cache
743 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
744 self.assertEquals(receivedResponse, response)
745
746 # cache another entry
747 (receivedQuery, receivedResponse) = self.sendUDPQuery(query2, response2)
748 self.assertTrue(receivedQuery)
749 self.assertTrue(receivedResponse)
750 receivedQuery.id = query2.id
751 self.assertEquals(query2, receivedQuery)
752 self.assertEquals(response2, receivedResponse)
753 misses += 1
754
755 # queries for name and name 2 should hit the cache
756 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
757 self.assertEquals(receivedResponse, response)
758
759 (_, receivedResponse) = self.sendUDPQuery(query2, response=None, useQueue=False)
760 self.assertEquals(receivedResponse, response2)
761
762 # remove cached entries from name
763 self.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"" + name + "\"))")
764
765 # Miss for name
766 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
767 self.assertTrue(receivedQuery)
768 self.assertTrue(receivedResponse)
769 receivedQuery.id = query.id
770 self.assertEquals(query, receivedQuery)
771 self.assertEquals(response, receivedResponse)
772 misses += 1
773
774 # next queries for name should hit the cache again
775 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
776 self.assertEquals(receivedResponse, response)
777
778 # queries for name2 should still hit the cache
779 (_, receivedResponse) = self.sendUDPQuery(query2, response=None, useQueue=False)
780 self.assertEquals(receivedResponse, response2)
781
782 total = 0
02bbf9eb
RG
783 for key in self._responsesCounter:
784 total += self._responsesCounter[key]
1ea747c0
RG
785
786 self.assertEquals(total, misses)
787
788 def testCacheExpungeByNameAndType(self):
789 """
790 Cache: Expunge by name and type
791
792 """
793 misses = 0
794 ttl = 600
795 name = 'expungebynameandtype.cache.tests.powerdns.com.'
796 query = dns.message.make_query(name, 'A', 'IN')
797 response = dns.message.make_response(query)
798 rrset = dns.rrset.from_text(name,
799 ttl,
800 dns.rdataclass.IN,
801 dns.rdatatype.A,
802 '127.0.0.1')
803 response.answer.append(rrset)
804
805 query2 = dns.message.make_query(name, 'AAAA', 'IN')
806 response2 = dns.message.make_response(query2)
807 rrset2 = dns.rrset.from_text(name,
808 ttl,
809 dns.rdataclass.IN,
810 dns.rdatatype.AAAA,
811 '::1')
812 response2.answer.append(rrset2)
813
814 # Miss
815 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
816 self.assertTrue(receivedQuery)
817 self.assertTrue(receivedResponse)
818 receivedQuery.id = query.id
819 self.assertEquals(query, receivedQuery)
820 self.assertEquals(response, receivedResponse)
821 misses += 1
822
823 # next queries should hit the cache
824 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
825 self.assertEquals(receivedResponse, response)
826
827 # cache another entry
828 (receivedQuery, receivedResponse) = self.sendUDPQuery(query2, response2)
829 self.assertTrue(receivedQuery)
830 self.assertTrue(receivedResponse)
831 receivedQuery.id = query2.id
832 self.assertEquals(query2, receivedQuery)
833 self.assertEquals(response2, receivedResponse)
834 misses += 1
835
836 # queries for name A and AAAA should hit the cache
837 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
838 self.assertEquals(receivedResponse, response)
839
840 (_, receivedResponse) = self.sendUDPQuery(query2, response=None, useQueue=False)
841 self.assertEquals(receivedResponse, response2)
842
843 # remove cached entries from name A
844 self.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"" + name + "\"), dnsdist.A)")
845
846 # Miss for name A
847 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
848 self.assertTrue(receivedQuery)
849 self.assertTrue(receivedResponse)
850 receivedQuery.id = query.id
851 self.assertEquals(query, receivedQuery)
852 self.assertEquals(response, receivedResponse)
853 misses += 1
854
855 # next queries for name A should hit the cache again
856 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
857 self.assertEquals(receivedResponse, response)
858
859 # queries for name AAAA should still hit the cache
860 (_, receivedResponse) = self.sendUDPQuery(query2, response=None, useQueue=False)
490dc586
RG
861 self.assertEquals(receivedResponse, response2)
862
863 total = 0
864 for key in self._responsesCounter:
865 total += self._responsesCounter[key]
866 self.assertEquals(total, misses)
867
868 def testCacheExpungeByNameAndSuffix(self):
869 """
870 Cache: Expunge by name
871
872 """
873 misses = 0
874 ttl = 600
875 name = 'expungebyname.suffix.cache.tests.powerdns.com.'
876 query = dns.message.make_query(name, 'A', 'IN')
877 response = dns.message.make_response(query)
878 rrset = dns.rrset.from_text(name,
879 ttl,
880 dns.rdataclass.IN,
881 dns.rdatatype.A,
882 '127.0.0.1')
883 response.answer.append(rrset)
884
885 name2 = 'expungebyname.suffixother.cache.tests.powerdns.com.'
886 query2 = dns.message.make_query(name2, 'A', 'IN')
887 response2 = dns.message.make_response(query2)
888 rrset2 = dns.rrset.from_text(name2,
889 ttl,
890 dns.rdataclass.IN,
891 dns.rdatatype.A,
892 '127.0.0.1')
893 response2.answer.append(rrset2)
894
895 # Miss
896 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
897 self.assertTrue(receivedQuery)
898 self.assertTrue(receivedResponse)
899 receivedQuery.id = query.id
900 self.assertEquals(query, receivedQuery)
901 self.assertEquals(response, receivedResponse)
902 misses += 1
903
904 # next queries should hit the cache
905 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
906 self.assertEquals(receivedResponse, response)
907
908 # cache another entry
909 (receivedQuery, receivedResponse) = self.sendUDPQuery(query2, response2)
910 self.assertTrue(receivedQuery)
911 self.assertTrue(receivedResponse)
912 receivedQuery.id = query2.id
913 self.assertEquals(query2, receivedQuery)
914 self.assertEquals(response2, receivedResponse)
915 misses += 1
916
917 # queries for name and name 2 should hit the cache
918 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
919 self.assertEquals(receivedResponse, response)
920
921 (_, receivedResponse) = self.sendUDPQuery(query2, response=None, useQueue=False)
922 self.assertEquals(receivedResponse, response2)
923
924 # remove cached entries from name
925 self.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"suffix.cache.tests.powerdns.com.\"), dnsdist.ANY, true)")
926
927 # Miss for name
928 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
929 self.assertTrue(receivedQuery)
930 self.assertTrue(receivedResponse)
931 receivedQuery.id = query.id
932 self.assertEquals(query, receivedQuery)
933 self.assertEquals(response, receivedResponse)
934 misses += 1
935
936 # next queries for name should hit the cache again
937 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
938 self.assertEquals(receivedResponse, response)
939
940 # queries for name2 should still hit the cache
941 (_, receivedResponse) = self.sendUDPQuery(query2, response=None, useQueue=False)
942 self.assertEquals(receivedResponse, response2)
943
944 total = 0
945 for key in self._responsesCounter:
946 total += self._responsesCounter[key]
947
948 self.assertEquals(total, misses)
949
950 def testCacheExpungeByNameAndTypeAndSuffix(self):
951 """
952 Cache: Expunge by name and type
953
954 """
955 misses = 0
956 ttl = 600
957 name = 'expungebynameandtype.suffixtype.cache.tests.powerdns.com.'
958 query = dns.message.make_query(name, 'A', 'IN')
959 response = dns.message.make_response(query)
960 rrset = dns.rrset.from_text(name,
961 ttl,
962 dns.rdataclass.IN,
963 dns.rdatatype.A,
964 '127.0.0.1')
965 response.answer.append(rrset)
966
967 query2 = dns.message.make_query(name, 'AAAA', 'IN')
968 response2 = dns.message.make_response(query2)
969 rrset2 = dns.rrset.from_text(name,
970 ttl,
971 dns.rdataclass.IN,
972 dns.rdatatype.AAAA,
973 '::1')
974 response2.answer.append(rrset2)
975
976 # Miss
977 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
978 self.assertTrue(receivedQuery)
979 self.assertTrue(receivedResponse)
980 receivedQuery.id = query.id
981 self.assertEquals(query, receivedQuery)
982 self.assertEquals(response, receivedResponse)
983 misses += 1
984
985 # next queries should hit the cache
986 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
987 self.assertEquals(receivedResponse, response)
988
989 # cache another entry
990 (receivedQuery, receivedResponse) = self.sendUDPQuery(query2, response2)
991 self.assertTrue(receivedQuery)
992 self.assertTrue(receivedResponse)
993 receivedQuery.id = query2.id
994 self.assertEquals(query2, receivedQuery)
995 self.assertEquals(response2, receivedResponse)
996 misses += 1
997
998 # queries for name A and AAAA should hit the cache
999 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1000 self.assertEquals(receivedResponse, response)
1001
1002 (_, receivedResponse) = self.sendUDPQuery(query2, response=None, useQueue=False)
1003 self.assertEquals(receivedResponse, response2)
1004
1005 # remove cached entries from name A
1006 self.sendConsoleCommand("getPool(\"\"):getCache():expungeByName(newDNSName(\"suffixtype.cache.tests.powerdns.com.\"), dnsdist.A, true)")
1007
1008 # Miss for name A
1009 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1010 self.assertTrue(receivedQuery)
1011 self.assertTrue(receivedResponse)
1012 receivedQuery.id = query.id
1013 self.assertEquals(query, receivedQuery)
1014 self.assertEquals(response, receivedResponse)
1015 misses += 1
1016
1017 # next queries for name A should hit the cache again
1018 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1019 self.assertEquals(receivedResponse, response)
1020
1021 # queries for name AAAA should still hit the cache
1022 (_, receivedResponse) = self.sendUDPQuery(query2, response=None, useQueue=False)
1ea747c0
RG
1023 self.assertEquals(receivedResponse, response2)
1024
1025 total = 0
02bbf9eb
RG
1026 for key in self._responsesCounter:
1027 total += self._responsesCounter[key]
1ea747c0 1028 self.assertEquals(total, misses)
cc8cefe1
RG
1029
1030class TestCachingTTL(DNSDistTest):
1031
1032 _maxCacheTTL = 86400
1033 _minCacheTTL = 600
1034 _config_params = ['_maxCacheTTL', '_minCacheTTL', '_testServerPort']
1035 _config_template = """
1036 pc = newPacketCache(1000, %s, %s)
1037 getPool(""):setCache(pc)
1038 newServer{address="127.0.0.1:%s"}
1039 """
1040 def testCacheShortTTL(self):
1041 """
1042 Cache: Entries with a TTL shorter than minTTL
1043
1044 """
1045 misses = 0
1046 ttl = 60
1047 name = 'ttltooshort.cache.tests.powerdns.com.'
1048 query = dns.message.make_query(name, 'A', 'IN')
1049 response = dns.message.make_response(query)
1050 rrset = dns.rrset.from_text(name,
1051 ttl,
1052 dns.rdataclass.IN,
1053 dns.rdatatype.A,
1054 '127.0.0.1')
1055 response.answer.append(rrset)
1056
1057 # Miss
1058 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1059 self.assertTrue(receivedQuery)
1060 self.assertTrue(receivedResponse)
1061 receivedQuery.id = query.id
1062 self.assertEquals(query, receivedQuery)
1063 self.assertEquals(response, receivedResponse)
1064 for an in receivedResponse.answer:
1065 self.assertEquals(an.ttl, ttl)
1066 misses += 1
1067
1068 # We should not have been cached
1069 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1070 self.assertTrue(receivedQuery)
1071 self.assertTrue(receivedResponse)
1072 receivedQuery.id = query.id
1073 self.assertEquals(query, receivedQuery)
1074 self.assertEquals(response, receivedResponse)
1075 for an in receivedResponse.answer:
1076 self.assertEquals(an.ttl, ttl)
1077 misses += 1
1078
1079 total = 0
1080 for key in self._responsesCounter:
1081 total += self._responsesCounter[key]
1082
1083 self.assertEquals(total, misses)
1084
a3824e43
RG
1085 def testCacheNXWithNoRR(self):
1086 """
1087 Cache: NX with no RR
1088
1089 """
1090 misses = 0
1091 name = 'nxwithnorr.cache.tests.powerdns.com.'
1092 query = dns.message.make_query(name, 'A', 'IN')
1093 response = dns.message.make_response(query)
1094 response.set_rcode(dns.rcode.NXDOMAIN)
1095
1096 # Miss
1097 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1098 self.assertTrue(receivedQuery)
1099 self.assertTrue(receivedResponse)
1100 receivedQuery.id = query.id
1101 self.assertEquals(query, receivedQuery)
1102 self.assertEquals(response, receivedResponse)
1103 misses += 1
1104
1105 # We should not have been cached
1106 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1107 self.assertTrue(receivedQuery)
1108 self.assertTrue(receivedResponse)
1109 receivedQuery.id = query.id
1110 self.assertEquals(query, receivedQuery)
1111 self.assertEquals(response, receivedResponse)
1112 misses += 1
1113
1114 total = 0
1115 for key in self._responsesCounter:
1116 total += self._responsesCounter[key]
1117
1118 self.assertEquals(total, misses)
1119
cc8cefe1
RG
1120class TestCachingLongTTL(DNSDistTest):
1121
1122 _maxCacheTTL = 2
1123 _config_params = ['_maxCacheTTL', '_testServerPort']
1124 _config_template = """
1125 pc = newPacketCache(1000, %s)
1126 getPool(""):setCache(pc)
1127 newServer{address="127.0.0.1:%s"}
1128 """
1129 def testCacheLongTTL(self):
1130 """
1131 Cache: Entries with a longer TTL than the maximum
1132
1133 """
1134 misses = 0
1135 ttl = 172800
1136 name = 'longttl.cache.tests.powerdns.com.'
1137 query = dns.message.make_query(name, 'A', 'IN')
1138 response = dns.message.make_response(query)
1139 rrset = dns.rrset.from_text(name,
1140 ttl,
1141 dns.rdataclass.IN,
1142 dns.rdatatype.A,
1143 '127.0.0.1')
1144 response.answer.append(rrset)
1145
1146 # Miss
1147 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1148 self.assertTrue(receivedQuery)
1149 self.assertTrue(receivedResponse)
1150 receivedQuery.id = query.id
1151 self.assertEquals(query, receivedQuery)
1152 self.assertEquals(response, receivedResponse)
1153 for an in receivedResponse.answer:
1154 self.assertEquals(an.ttl, ttl)
1155 misses += 1
1156
1157 # next queries should hit the cache
1158 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1159 self.assertEquals(receivedResponse, response)
1160 for an in receivedResponse.answer:
1161 self.assertTrue(an.ttl <= ttl)
1162
1163 time.sleep(self._maxCacheTTL + 1)
1164
1165 # we should not have cached for longer than max cache
1166 # so it should be a miss
1167 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1168 self.assertTrue(receivedQuery)
1169 self.assertTrue(receivedResponse)
1170 receivedQuery.id = query.id
1171 self.assertEquals(query, receivedQuery)
1172 self.assertEquals(response, receivedResponse)
1173 for an in receivedResponse.answer:
1174 self.assertEquals(an.ttl, ttl)
1175 misses += 1
1176
1177 total = 0
1178 for key in self._responsesCounter:
1179 total += self._responsesCounter[key]
1180
1181 self.assertEquals(total, misses)
2714396e
RG
1182
1183class TestCachingFailureTTL(DNSDistTest):
1184
1185 _failureCacheTTL = 2
1186 _config_params = ['_failureCacheTTL', '_testServerPort']
1187 _config_template = """
1188 pc = newPacketCache(1000, 86400, 0, %d, 60)
1189 getPool(""):setCache(pc)
1190 newServer{address="127.0.0.1:%s"}
1191 """
1192 def testCacheServFailTTL(self):
1193 """
1194 Cache: ServFail TTL
1195
1196 """
1197 misses = 0
1198 name = 'servfail.failure.cache.tests.powerdns.com.'
1199 query = dns.message.make_query(name, 'A', 'IN')
1200 response = dns.message.make_response(query)
1201 response.set_rcode(dns.rcode.SERVFAIL)
1202
1203 # Miss
1204 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1205 self.assertTrue(receivedQuery)
1206 self.assertTrue(receivedResponse)
1207 receivedQuery.id = query.id
1208 self.assertEquals(query, receivedQuery)
1209 self.assertEquals(response, receivedResponse)
1210 misses += 1
1211
1212 # next queries should hit the cache
1213 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1214 self.assertEquals(receivedResponse, response)
1215
1216 time.sleep(self._failureCacheTTL + 1)
1217
1218 # we should not have cached for longer than failure cache
1219 # so it should be a miss
1220 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1221 self.assertTrue(receivedQuery)
1222 self.assertTrue(receivedResponse)
1223 receivedQuery.id = query.id
1224 self.assertEquals(query, receivedQuery)
1225 self.assertEquals(response, receivedResponse)
1226 misses += 1
1227
1228 total = 0
1229 for key in self._responsesCounter:
1230 total += self._responsesCounter[key]
1231
1232 self.assertEquals(total, misses)
1233
1234 def testCacheRefusedTTL(self):
1235 """
1236 Cache: Refused TTL
1237
1238 """
1239 misses = 0
1240 name = 'refused.failure.cache.tests.powerdns.com.'
1241 query = dns.message.make_query(name, 'A', 'IN')
1242 response = dns.message.make_response(query)
1243 response.set_rcode(dns.rcode.REFUSED)
1244
1245 # Miss
1246 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1247 self.assertTrue(receivedQuery)
1248 self.assertTrue(receivedResponse)
1249 receivedQuery.id = query.id
1250 self.assertEquals(query, receivedQuery)
1251 self.assertEquals(response, receivedResponse)
1252 misses += 1
1253
1254 # next queries should hit the cache
1255 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1256 self.assertEquals(receivedResponse, response)
1257
1258 time.sleep(self._failureCacheTTL + 1)
1259
1260 # we should not have cached for longer than failure cache
1261 # so it should be a miss
1262 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1263 self.assertTrue(receivedQuery)
1264 self.assertTrue(receivedResponse)
1265 receivedQuery.id = query.id
1266 self.assertEquals(query, receivedQuery)
1267 self.assertEquals(response, receivedResponse)
1268 misses += 1
1269
1270 total = 0
1271 for key in self._responsesCounter:
1272 total += self._responsesCounter[key]
1273
1274 self.assertEquals(total, misses)
1275
1276 def testCacheHeaderOnlyRefusedTTL(self):
1277 """
1278 Cache: Header-Only Refused TTL
1279
1280 """
1281 misses = 0
1282 name = 'header-only-refused.failure.cache.tests.powerdns.com.'
1283 query = dns.message.make_query(name, 'A', 'IN')
1284 response = dns.message.make_response(query)
1285 response.set_rcode(dns.rcode.REFUSED)
1286 response.question = []
1287
1288 # Miss
1289 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1290 self.assertTrue(receivedQuery)
1291 self.assertTrue(receivedResponse)
1292 receivedQuery.id = query.id
1293 self.assertEquals(query, receivedQuery)
1294 self.assertEquals(response, receivedResponse)
1295 misses += 1
1296
1297 # next queries should hit the cache
1298 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1299 self.assertEquals(receivedResponse, response)
1300
1301 time.sleep(self._failureCacheTTL + 1)
1302
1303 # we should not have cached for longer than failure cache
1304 # so it should be a miss
1305 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1306 self.assertTrue(receivedQuery)
1307 self.assertTrue(receivedResponse)
1308 receivedQuery.id = query.id
1309 self.assertEquals(query, receivedQuery)
1310 self.assertEquals(response, receivedResponse)
1311 misses += 1
1312
1313 total = 0
1314 for key in self._responsesCounter:
1315 total += self._responsesCounter[key]
1316
1317 self.assertEquals(total, misses)
2b67180c
RG
1318
1319class TestCachingDontAge(DNSDistTest):
1320
1321 _config_template = """
1322 pc = newPacketCache(100, 86400, 0, 60, 60, true)
1323 getPool(""):setCache(pc)
1324 newServer{address="127.0.0.1:%s"}
1325 """
1326 def testCacheDoesntDecreaseTTL(self):
1327 """
1328 Cache: Cache doesn't decrease TTL with 'don't age' set
1329
1330 dnsdist is configured to cache entries but without aging the TTL,
1331 we are sending one request (cache miss) and verify that the cache
1332 hits don't have a decreasing TTL.
1333 """
1334 ttl = 600
1335 misses = 0
1336 name = 'cachedoesntdecreasettl.cache-dont-age.tests.powerdns.com.'
1337 query = dns.message.make_query(name, 'AAAA', 'IN')
1338 response = dns.message.make_response(query)
1339 rrset = dns.rrset.from_text(name,
1340 ttl,
1341 dns.rdataclass.IN,
1342 dns.rdatatype.AAAA,
1343 '::1')
1344 response.answer.append(rrset)
1345
1346 # first query to fill the cache
1347 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1348 self.assertTrue(receivedQuery)
1349 self.assertTrue(receivedResponse)
1350 receivedQuery.id = query.id
1351 self.assertEquals(query, receivedQuery)
1352 self.assertEquals(receivedResponse, response)
1353 misses += 1
1354
1355 # next queries should hit the cache
1356 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1357 self.assertEquals(receivedResponse, response)
1358 for an in receivedResponse.answer:
1359 self.assertTrue(an.ttl == ttl)
1360
1361 # now we wait a bit for the TTL to decrease
1362 time.sleep(1)
1363
1364 # next queries should hit the cache
1365 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1366 self.assertEquals(receivedResponse, response)
1367 for an in receivedResponse.answer:
1368 self.assertTrue(an.ttl == ttl)
1369
1370 total = 0
1371 for key in self._responsesCounter:
1372 total += self._responsesCounter[key]
1373
1374 self.assertEquals(total, misses)