]>
git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.dnsdist/test_Routing.py
5 from dnsdisttests
import DNSDistTest
7 class TestRoutingPoolRouting(DNSDistTest
):
10 newServer{address="127.0.0.1:%s", pool="real"}
11 addPoolRule("pool.routing.tests.powerdns.com", "real")
12 addAction(makeRule("poolaction.routing.tests.powerdns.com"), PoolAction("real"))
13 addQPSPoolRule("qpspool.routing.tests.powerdns.com", 10, "abuse")
14 addAction(makeRule("qpspoolaction.routing.tests.powerdns.com"), QPSPoolAction(10, "abuse"))
17 def testPolicyPool(self
):
19 Routing: Set pool by qname
21 Send an A query to "pool.routing.tests.powerdns.com.",
22 check that dnsdist routes the query to the "real" pool.
24 name
= 'pool.routing.tests.powerdns.com.'
25 query
= dns
.message
.make_query(name
, 'A', 'IN')
26 response
= dns
.message
.make_response(query
)
27 rrset
= dns
.rrset
.from_text(name
,
32 response
.answer
.append(rrset
)
34 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
35 receivedQuery
.id = query
.id
36 self
.assertEquals(query
, receivedQuery
)
37 self
.assertEquals(response
, receivedResponse
)
39 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
40 receivedQuery
.id = query
.id
41 self
.assertEquals(query
, receivedQuery
)
42 self
.assertEquals(response
, receivedResponse
)
44 def testPolicyPoolAction(self
):
46 Routing: Set pool by qname via PoolAction
48 Send an A query to "poolaction.routing.tests.powerdns.com.",
49 check that dnsdist routes the query to the "real" pool.
51 name
= 'pool.routing.tests.powerdns.com.'
52 query
= dns
.message
.make_query(name
, 'A', 'IN')
53 response
= dns
.message
.make_response(query
)
54 rrset
= dns
.rrset
.from_text(name
,
59 response
.answer
.append(rrset
)
61 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
62 receivedQuery
.id = query
.id
63 self
.assertEquals(query
, receivedQuery
)
64 self
.assertEquals(response
, receivedResponse
)
66 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
67 receivedQuery
.id = query
.id
68 self
.assertEquals(query
, receivedQuery
)
69 self
.assertEquals(response
, receivedResponse
)
71 def testDefaultPool(self
):
73 Routing: Set pool by qname canary
75 Send an A query to "notpool.routing.tests.powerdns.com.",
76 check that dnsdist sends no response (no servers
79 name
= 'notpool.routing.tests.powerdns.com.'
80 query
= dns
.message
.make_query(name
, 'A', 'IN')
82 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
83 self
.assertEquals(receivedResponse
, None)
85 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
86 self
.assertEquals(receivedResponse
, None)
88 class TestRoutingQPSPoolRouting(DNSDistTest
):
89 _config_template
= """
90 newServer{address="127.0.0.1:%s", pool="regular"}
91 addQPSPoolRule("qpspool.routing.tests.powerdns.com", 10, "regular")
92 addAction(makeRule("qpspoolaction.routing.tests.powerdns.com"), QPSPoolAction(10, "regular"))
95 def testQPSPool(self
):
97 Routing: Set pool by QPS
99 Send queries to "qpspool.routing.tests.powerdns.com."
100 check that dnsdist does not route the query to the "regular" pool
101 when the max QPS has been reached.
104 name
= 'qpspool.routing.tests.powerdns.com.'
105 query
= dns
.message
.make_query(name
, 'A', 'IN')
106 response
= dns
.message
.make_response(query
)
107 rrset
= dns
.rrset
.from_text(name
,
112 response
.answer
.append(rrset
)
114 for _
in range(maxQPS
):
115 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
116 receivedQuery
.id = query
.id
117 self
.assertEquals(query
, receivedQuery
)
118 self
.assertEquals(response
, receivedResponse
)
120 # we should now be sent to the "abuse" pool which is empty,
121 # so the queries should be dropped
122 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
123 self
.assertEquals(receivedResponse
, None)
127 # again, over TCP this time
128 for _
in range(maxQPS
):
129 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
130 receivedQuery
.id = query
.id
131 self
.assertEquals(query
, receivedQuery
)
132 self
.assertEquals(response
, receivedResponse
)
135 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
136 self
.assertEquals(receivedResponse
, None)
138 def testQPSPoolAction(self
):
140 Routing: Set pool by QPS via action
142 Send queries to "qpspoolaction.routing.tests.powerdns.com."
143 check that dnsdist does not route the query to the "regular" pool
144 when the max QPS has been reached.
147 name
= 'qpspoolaction.routing.tests.powerdns.com.'
148 query
= dns
.message
.make_query(name
, 'A', 'IN')
149 response
= dns
.message
.make_response(query
)
150 rrset
= dns
.rrset
.from_text(name
,
155 response
.answer
.append(rrset
)
157 for _
in range(maxQPS
):
158 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
159 receivedQuery
.id = query
.id
160 self
.assertEquals(query
, receivedQuery
)
161 self
.assertEquals(response
, receivedResponse
)
163 # we should now be sent to the "abuse" pool which is empty,
164 # so the queries should be dropped
165 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
166 self
.assertEquals(receivedResponse
, None)
170 # again, over TCP this time
171 for _
in range(maxQPS
):
172 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
173 receivedQuery
.id = query
.id
174 self
.assertEquals(query
, receivedQuery
)
175 self
.assertEquals(response
, receivedResponse
)
178 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
179 self
.assertEquals(receivedResponse
, None)
182 class TestRoutingRoundRobinLB(DNSDistTest
):
184 _testServer2Port
= 5351
185 _config_params
= ['_testServerPort', '_testServer2Port']
186 _config_template
= """
187 setServerPolicy(roundrobin)
188 s1 = newServer{address="127.0.0.1:%s"}
190 s2 = newServer{address="127.0.0.1:%s"}
195 def startResponders(cls
):
196 print("Launching responders..")
197 cls
._UDPResponder
= threading
.Thread(name
='UDP Responder', target
=cls
.UDPResponder
, args
=[cls
._testServerPort
, cls
._toResponderQueue
, cls
._fromResponderQueue
])
198 cls
._UDPResponder
.setDaemon(True)
199 cls
._UDPResponder
.start()
200 cls
._UDPResponder
2 = threading
.Thread(name
='UDP Responder 2', target
=cls
.UDPResponder
, args
=[cls
._testServer
2Port
, cls
._toResponderQueue
, cls
._fromResponderQueue
])
201 cls
._UDPResponder
2.setDaemon(True)
202 cls
._UDPResponder
2.start()
204 cls
._TCPResponder
= threading
.Thread(name
='TCP Responder', target
=cls
.TCPResponder
, args
=[cls
._testServerPort
, cls
._toResponderQueue
, cls
._fromResponderQueue
])
205 cls
._TCPResponder
.setDaemon(True)
206 cls
._TCPResponder
.start()
208 cls
._TCPResponder
2 = threading
.Thread(name
='TCP Responder 2', target
=cls
.TCPResponder
, args
=[cls
._testServer
2Port
, cls
._toResponderQueue
, cls
._fromResponderQueue
])
209 cls
._TCPResponder
2.setDaemon(True)
210 cls
._TCPResponder
2.start()
216 Send 100 A queries to "rr.routing.tests.powerdns.com.",
217 check that dnsdist routes half of it to each backend.
220 name
= 'rr.routing.tests.powerdns.com.'
221 query
= dns
.message
.make_query(name
, 'A', 'IN')
222 response
= dns
.message
.make_response(query
)
223 rrset
= dns
.rrset
.from_text(name
,
228 response
.answer
.append(rrset
)
230 # the round robin counter is shared for UDP and TCP,
231 # so we need to do UDP then TCP to have a clean count
232 for _
in range(numberOfQueries
):
233 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
234 receivedQuery
.id = query
.id
235 self
.assertEquals(query
, receivedQuery
)
236 self
.assertEquals(response
, receivedResponse
)
238 for _
in range(numberOfQueries
):
239 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
240 receivedQuery
.id = query
.id
241 self
.assertEquals(query
, receivedQuery
)
242 self
.assertEquals(response
, receivedResponse
)
244 for key
in self
._responsesCounter
:
245 value
= self
._responsesCounter
[key
]
246 self
.assertEquals(value
, numberOfQueries
/ 2)
248 class TestRoutingRoundRobinLBOneDown(DNSDistTest
):
250 _testServer2Port
= 5351
251 _config_params
= ['_testServerPort', '_testServer2Port']
252 _config_template
= """
253 setServerPolicy(roundrobin)
254 s1 = newServer{address="127.0.0.1:%s"}
256 s2 = newServer{address="127.0.0.1:%s"}
260 def testRRWithOneDown(self
):
262 Routing: Round Robin with one server down
264 Send 100 A queries to "rr.routing.tests.powerdns.com.",
265 check that dnsdist routes all of it to the only backend up.
268 name
= 'rr.routing.tests.powerdns.com.'
269 query
= dns
.message
.make_query(name
, 'A', 'IN')
270 response
= dns
.message
.make_response(query
)
271 rrset
= dns
.rrset
.from_text(name
,
276 response
.answer
.append(rrset
)
278 # the round robin counter is shared for UDP and TCP,
279 # so we need to do UDP then TCP to have a clean count
280 for _
in range(numberOfQueries
):
281 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
282 receivedQuery
.id = query
.id
283 self
.assertEquals(query
, receivedQuery
)
284 self
.assertEquals(response
, receivedResponse
)
286 for _
in range(numberOfQueries
):
287 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
288 receivedQuery
.id = query
.id
289 self
.assertEquals(query
, receivedQuery
)
290 self
.assertEquals(response
, receivedResponse
)
293 for key
in self
._responsesCounter
:
294 value
= self
._responsesCounter
[key
]
295 self
.assertTrue(value
== numberOfQueries
or value
== 0)
298 self
.assertEquals(total
, numberOfQueries
* 2)
300 class TestRoutingOrder(DNSDistTest
):
302 _testServer2Port
= 5351
303 _config_params
= ['_testServerPort', '_testServer2Port']
304 _config_template
= """
305 setServerPolicy(firstAvailable)
306 s1 = newServer{address="127.0.0.1:%s", order=2}
308 s2 = newServer{address="127.0.0.1:%s", order=1}
313 def startResponders(cls
):
314 print("Launching responders..")
315 cls
._UDPResponder
= threading
.Thread(name
='UDP Responder', target
=cls
.UDPResponder
, args
=[cls
._testServerPort
, cls
._toResponderQueue
, cls
._fromResponderQueue
])
316 cls
._UDPResponder
.setDaemon(True)
317 cls
._UDPResponder
.start()
318 cls
._UDPResponder
2 = threading
.Thread(name
='UDP Responder 2', target
=cls
.UDPResponder
, args
=[cls
._testServer
2Port
, cls
._toResponderQueue
, cls
._fromResponderQueue
])
319 cls
._UDPResponder
2.setDaemon(True)
320 cls
._UDPResponder
2.start()
322 cls
._TCPResponder
= threading
.Thread(name
='TCP Responder', target
=cls
.TCPResponder
, args
=[cls
._testServerPort
, cls
._toResponderQueue
, cls
._fromResponderQueue
])
323 cls
._TCPResponder
.setDaemon(True)
324 cls
._TCPResponder
.start()
326 cls
._TCPResponder
2 = threading
.Thread(name
='TCP Responder 2', target
=cls
.TCPResponder
, args
=[cls
._testServer
2Port
, cls
._toResponderQueue
, cls
._fromResponderQueue
])
327 cls
._TCPResponder
2.setDaemon(True)
328 cls
._TCPResponder
2.start()
332 Routing: firstAvailable policy based on 'order'
334 Send 50 A queries to "order.routing.tests.powerdns.com.",
335 check that dnsdist routes all of it to the second backend
336 because it has the lower order value.
339 name
= 'order.routing.tests.powerdns.com.'
340 query
= dns
.message
.make_query(name
, 'A', 'IN')
341 response
= dns
.message
.make_response(query
)
342 rrset
= dns
.rrset
.from_text(name
,
347 response
.answer
.append(rrset
)
349 for _
in range(numberOfQueries
):
350 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
351 receivedQuery
.id = query
.id
352 self
.assertEquals(query
, receivedQuery
)
353 self
.assertEquals(response
, receivedResponse
)
354 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
355 receivedQuery
.id = query
.id
356 self
.assertEquals(query
, receivedQuery
)
357 self
.assertEquals(response
, receivedResponse
)
360 if 'UDP Responder' in self
._responsesCounter
:
361 self
.assertEquals(self
._responsesCounter
['UDP Responder'], 0)
362 self
.assertEquals(self
._responsesCounter
['UDP Responder 2'], numberOfQueries
)
363 if 'TCP Responder' in self
._responsesCounter
:
364 self
.assertEquals(self
._responsesCounter
['TCP Responder'], 0)
365 self
.assertEquals(self
._responsesCounter
['TCP Responder 2'], numberOfQueries
)
367 class TestRoutingNoServer(DNSDistTest
):
369 _config_template
= """
370 newServer{address="127.0.0.1:%s", pool="real"}
371 setServFailWhenNoServer(true)
374 def testPolicyPoolNoServer(self
):
376 Routing: No server should return ServFail
378 name
= 'noserver.routing.tests.powerdns.com.'
379 query
= dns
.message
.make_query(name
, 'A', 'IN')
380 expectedResponse
= dns
.message
.make_response(query
)
381 expectedResponse
.set_rcode(dns
.rcode
.SERVFAIL
)
383 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
384 self
.assertEquals(receivedResponse
, expectedResponse
)
386 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
387 self
.assertEquals(receivedResponse
, expectedResponse
)