4 from dnsdisttests
import DNSDistTest
6 class TestCaching(DNSDistTest
):
9 pc = newPacketCache(5, 86400, 1)
10 getPool(""):setCache(pc)
11 addAction(makeRule("nocache.cache.tests.powerdns.com."), SkipCacheAction())
12 newServer{address="127.0.0.1:%s"}
16 Cache: Served from cache
18 dnsdist is configured to cache entries, we are sending several
19 identical requests and checking that the backend only receive
23 name
= 'cached.cache.tests.powerdns.com.'
24 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
25 response
= dns
.message
.make_response(query
)
26 rrset
= dns
.rrset
.from_text(name
,
31 response
.answer
.append(rrset
)
33 # first query to fill the cache
34 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
35 self
.assertTrue(receivedQuery
)
36 self
.assertTrue(receivedResponse
)
37 receivedQuery
.id = query
.id
38 self
.assertEquals(query
, receivedQuery
)
39 self
.assertEquals(receivedResponse
, response
)
41 for _
in range(numberOfQueries
):
42 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
43 self
.assertEquals(receivedResponse
, response
)
46 for key
in TestCaching
._responsesCounter
:
47 total
+= TestCaching
._responsesCounter
[key
]
48 TestCaching
._responsesCounter
[key
] = 0
50 self
.assertEquals(total
, 1)
52 # TCP should not be cached
53 # first query to fill the cache
54 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
55 self
.assertTrue(receivedQuery
)
56 self
.assertTrue(receivedResponse
)
57 receivedQuery
.id = query
.id
58 self
.assertEquals(query
, receivedQuery
)
59 self
.assertEquals(receivedResponse
, response
)
61 for _
in range(numberOfQueries
):
62 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
63 self
.assertEquals(receivedResponse
, response
)
66 for key
in TestCaching
._responsesCounter
:
67 total
+= TestCaching
._responsesCounter
[key
]
68 TestCaching
._responsesCounter
[key
] = 0
70 self
.assertEquals(total
, 1)
72 def testSkipCache(self
):
74 Cache: SkipCacheAction
76 dnsdist is configured to not cache entries for nocache.cache.tests.powerdns.com.
77 we are sending several requests and checking that the backend get them all.
79 name
= 'nocache.cache.tests.powerdns.com.'
81 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
82 response
= dns
.message
.make_response(query
)
83 rrset
= dns
.rrset
.from_text(name
,
88 response
.answer
.append(rrset
)
90 for _
in range(numberOfQueries
):
91 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
92 self
.assertTrue(receivedQuery
)
93 self
.assertTrue(receivedResponse
)
94 receivedQuery
.id = query
.id
95 self
.assertEquals(query
, receivedQuery
)
96 self
.assertEquals(receivedResponse
, response
)
98 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(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
)
105 for key
in TestCaching
._responsesCounter
:
106 value
= TestCaching
._responsesCounter
[key
]
107 self
.assertEquals(value
, numberOfQueries
)
109 def testCacheExpiration(self
):
111 Cache: Cache expiration
113 dnsdist is configured to cache entries, we are sending one request
114 (cache miss) with a very short TTL, checking that the next requests
115 are cached. Then we wait for the TTL to expire, check that the
116 next request is a miss but the following one a hit.
120 name
= 'cacheexpiration.cache.tests.powerdns.com.'
121 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
122 response
= dns
.message
.make_response(query
)
123 rrset
= dns
.rrset
.from_text(name
,
128 response
.answer
.append(rrset
)
130 # first query to fill the cache
131 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
132 self
.assertTrue(receivedQuery
)
133 self
.assertTrue(receivedResponse
)
134 receivedQuery
.id = query
.id
135 self
.assertEquals(query
, receivedQuery
)
136 self
.assertEquals(receivedResponse
, response
)
139 # next queries should hit the cache
140 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
141 self
.assertEquals(receivedResponse
, response
)
143 # now we wait a bit for the cache entry to expire
146 # next query should be a miss, fill the cache again
147 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
148 self
.assertTrue(receivedQuery
)
149 self
.assertTrue(receivedResponse
)
150 receivedQuery
.id = query
.id
151 self
.assertEquals(query
, receivedQuery
)
152 self
.assertEquals(receivedResponse
, response
)
155 # following queries should hit the cache again
156 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
157 self
.assertEquals(receivedResponse
, response
)
160 for key
in TestCaching
._responsesCounter
:
161 total
+= TestCaching
._responsesCounter
[key
]
163 self
.assertEquals(total
, misses
)
165 def testCacheExpirationDifferentSets(self
):
167 Cache: Cache expiration with different sets
169 dnsdist is configured to cache entries, we are sending one request
170 (cache miss) whose response has a long and a very short TTL,
171 checking that the next requests are cached. Then we wait for the
172 short TTL to expire, check that the
173 next request is a miss but the following one a hit.
177 name
= 'cacheexpirationdifferentsets.cache.tests.powerdns.com.'
178 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
179 response
= dns
.message
.make_response(query
)
180 rrset
= dns
.rrset
.from_text(name
,
184 'cname.cacheexpirationdifferentsets.cache.tests.powerdns.com.')
185 response
.answer
.append(rrset
)
186 rrset
= dns
.rrset
.from_text('cname.cacheexpirationdifferentsets.cache.tests.powerdns.com.',
191 response
.additional
.append(rrset
)
193 # first query to fill the cache
194 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
195 self
.assertTrue(receivedQuery
)
196 self
.assertTrue(receivedResponse
)
197 receivedQuery
.id = query
.id
198 self
.assertEquals(query
, receivedQuery
)
199 self
.assertEquals(receivedResponse
, response
)
202 # next queries should hit the cache
203 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
204 self
.assertEquals(receivedResponse
, response
)
206 # now we wait a bit for the cache entry to expire
209 # next query should be a miss, fill the cache again
210 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
211 self
.assertTrue(receivedQuery
)
212 self
.assertTrue(receivedResponse
)
213 receivedQuery
.id = query
.id
214 self
.assertEquals(query
, receivedQuery
)
215 self
.assertEquals(receivedResponse
, response
)
218 # following queries should hit the cache again
219 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
220 self
.assertEquals(receivedResponse
, response
)
223 for key
in TestCaching
._responsesCounter
:
224 total
+= TestCaching
._responsesCounter
[key
]
226 self
.assertEquals(total
, misses
)
228 def testCacheDecreaseTTL(self
):
230 Cache: Cache decreases TTL
232 dnsdist is configured to cache entries, we are sending one request
233 (cache miss) and verify that the cache hits have a decreasing TTL.
237 name
= 'cachedecreasettl.cache.tests.powerdns.com.'
238 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
239 response
= dns
.message
.make_response(query
)
240 rrset
= dns
.rrset
.from_text(name
,
245 response
.answer
.append(rrset
)
247 # first query to fill the cache
248 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
249 self
.assertTrue(receivedQuery
)
250 self
.assertTrue(receivedResponse
)
251 receivedQuery
.id = query
.id
252 self
.assertEquals(query
, receivedQuery
)
253 self
.assertEquals(receivedResponse
, response
)
256 # next queries should hit the cache
257 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
258 self
.assertEquals(receivedResponse
, response
)
259 for an
in receivedResponse
.answer
:
260 self
.assertTrue(an
.ttl
<= ttl
)
262 # now we wait a bit for the TTL to decrease
265 # next queries should hit the cache
266 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
267 self
.assertEquals(receivedResponse
, response
)
268 for an
in receivedResponse
.answer
:
269 self
.assertTrue(an
.ttl
< ttl
)
272 for key
in TestCaching
._responsesCounter
:
273 total
+= TestCaching
._responsesCounter
[key
]
275 self
.assertEquals(total
, misses
)
277 def testCacheDifferentCase(self
):
279 Cache: Cache matches different case
281 dnsdist is configured to cache entries, we are sending one request
282 (cache miss) and verify that the same one with a different case
286 name
= 'cachedifferentcase.cache.tests.powerdns.com.'
287 differentCaseName
= 'CacheDifferentCASE.cache.tests.powerdns.com.'
288 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
289 differentCaseQuery
= dns
.message
.make_query(differentCaseName
, 'AAAA', 'IN')
290 response
= dns
.message
.make_response(query
)
291 differentCaseResponse
= dns
.message
.make_response(differentCaseQuery
)
292 rrset
= dns
.rrset
.from_text(name
,
297 response
.answer
.append(rrset
)
298 differentCaseResponse
.answer
.append(rrset
)
300 # first query to fill the cache
301 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
302 self
.assertTrue(receivedQuery
)
303 self
.assertTrue(receivedResponse
)
304 receivedQuery
.id = query
.id
305 self
.assertEquals(query
, receivedQuery
)
306 self
.assertEquals(receivedResponse
, response
)
308 # different case query should still hit the cache
309 (_
, receivedResponse
) = self
.sendUDPQuery(differentCaseQuery
, response
=None, useQueue
=False)
310 self
.assertEquals(receivedResponse
, differentCaseResponse
)
313 class TestCachingWithExistingEDNS(DNSDistTest
):
315 _config_template
= """
316 pc = newPacketCache(5, 86400, 1)
317 getPool(""):setCache(pc)
318 newServer{address="127.0.0.1:%s"}
320 def testCacheWithEDNS(self
):
322 Cache: Cache should not match different EDNS value
324 dnsdist is configured to cache entries, we are sending one request
325 (cache miss) and verify that the same one with a different EDNS UDP
326 Payload size is not served from the cache.
329 name
= 'cachedifferentedns.cache.tests.powerdns.com.'
330 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=True, payload
=512)
331 response
= dns
.message
.make_response(query
)
332 rrset
= dns
.rrset
.from_text(name
,
337 response
.answer
.append(rrset
)
339 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
340 self
.assertTrue(receivedQuery
)
341 self
.assertTrue(receivedResponse
)
342 receivedQuery
.id = query
.id
343 self
.assertEquals(query
, receivedQuery
)
344 self
.assertEquals(response
, receivedResponse
)
347 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=True, payload
=4096)
348 response
= dns
.message
.make_response(query
)
349 rrset
= dns
.rrset
.from_text(name
,
354 response
.answer
.append(rrset
)
356 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
357 self
.assertTrue(receivedQuery
)
358 self
.assertTrue(receivedResponse
)
359 receivedQuery
.id = query
.id
360 self
.assertEquals(query
, receivedQuery
)
361 self
.assertEquals(response
, receivedResponse
)
365 for key
in TestCachingWithExistingEDNS
._responsesCounter
:
366 total
+= TestCachingWithExistingEDNS
._responsesCounter
[key
]
368 self
.assertEquals(total
, misses
)