]> git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.dnsdist/test_Routing.py
Merge pull request #9427 from mind04/pdns-2136-metadata
[thirdparty/pdns.git] / regression-tests.dnsdist / test_Routing.py
1 #!/usr/bin/env python
2 import base64
3 import threading
4 import time
5 import dns
6 from dnsdisttests import DNSDistTest
7
8 class TestRoutingPoolRouting(DNSDistTest):
9
10 _config_template = """
11 newServer{address="127.0.0.1:%s", pool="real"}
12 addAction(makeRule("poolaction.routing.tests.powerdns.com"), PoolAction("real"))
13 """
14
15 def testPolicyPoolAction(self):
16 """
17 Routing: Set pool by qname via PoolAction
18
19 Send an A query to "poolaction.routing.tests.powerdns.com.",
20 check that dnsdist routes the query to the "real" pool.
21 """
22 name = 'poolaction.routing.tests.powerdns.com.'
23 query = dns.message.make_query(name, 'A', 'IN')
24 response = dns.message.make_response(query)
25 rrset = dns.rrset.from_text(name,
26 60,
27 dns.rdataclass.IN,
28 dns.rdatatype.A,
29 '192.0.2.1')
30 response.answer.append(rrset)
31
32 for method in ("sendUDPQuery", "sendTCPQuery"):
33 sender = getattr(self, method)
34 (receivedQuery, receivedResponse) = sender(query, response)
35 receivedQuery.id = query.id
36 self.assertEquals(query, receivedQuery)
37 self.assertEquals(response, receivedResponse)
38
39 def testDefaultPool(self):
40 """
41 Routing: Set pool by qname canary
42
43 Send an A query to "notpool.routing.tests.powerdns.com.",
44 check that dnsdist sends no response (no servers
45 in the default pool).
46 """
47 name = 'notpool.routing.tests.powerdns.com.'
48 query = dns.message.make_query(name, 'A', 'IN')
49
50 for method in ("sendUDPQuery", "sendTCPQuery"):
51 sender = getattr(self, method)
52 (_, receivedResponse) = sender(query, response=None, useQueue=False)
53 self.assertEquals(receivedResponse, None)
54
55 class TestRoutingQPSPoolRouting(DNSDistTest):
56 _config_template = """
57 newServer{address="127.0.0.1:%s", pool="regular"}
58 addAction(makeRule("qpspoolaction.routing.tests.powerdns.com"), QPSPoolAction(10, "regular"))
59 """
60
61 def testQPSPoolAction(self):
62 """
63 Routing: Set pool by QPS via action
64
65 Send queries to "qpspoolaction.routing.tests.powerdns.com."
66 check that dnsdist does not route the query to the "regular" pool
67 when the max QPS has been reached.
68 """
69 maxQPS = 10
70 name = 'qpspoolaction.routing.tests.powerdns.com.'
71 query = dns.message.make_query(name, 'A', 'IN')
72 response = dns.message.make_response(query)
73 rrset = dns.rrset.from_text(name,
74 60,
75 dns.rdataclass.IN,
76 dns.rdatatype.A,
77 '192.0.2.1')
78 response.answer.append(rrset)
79
80 for _ in range(maxQPS):
81 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
82 receivedQuery.id = query.id
83 self.assertEquals(query, receivedQuery)
84 self.assertEquals(response, receivedResponse)
85
86 # we should now be sent to the "abuse" pool which is empty,
87 # so the queries should be dropped
88 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
89 self.assertEquals(receivedResponse, None)
90
91 time.sleep(1)
92
93 # again, over TCP this time
94 for _ in range(maxQPS):
95 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
96 receivedQuery.id = query.id
97 self.assertEquals(query, receivedQuery)
98 self.assertEquals(response, receivedResponse)
99
100
101 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
102 self.assertEquals(receivedResponse, None)
103
104
105 class TestRoutingRoundRobinLB(DNSDistTest):
106
107 _testServer2Port = 5351
108 _config_params = ['_testServerPort', '_testServer2Port']
109 _config_template = """
110 setServerPolicy(roundrobin)
111 s1 = newServer{address="127.0.0.1:%s"}
112 s1:setUp()
113 s2 = newServer{address="127.0.0.1:%s"}
114 s2:setUp()
115 """
116
117 @classmethod
118 def startResponders(cls):
119 print("Launching responders..")
120 cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
121 cls._UDPResponder.setDaemon(True)
122 cls._UDPResponder.start()
123 cls._UDPResponder2 = threading.Thread(name='UDP Responder 2', target=cls.UDPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue])
124 cls._UDPResponder2.setDaemon(True)
125 cls._UDPResponder2.start()
126
127 cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
128 cls._TCPResponder.setDaemon(True)
129 cls._TCPResponder.start()
130
131 cls._TCPResponder2 = threading.Thread(name='TCP Responder 2', target=cls.TCPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue])
132 cls._TCPResponder2.setDaemon(True)
133 cls._TCPResponder2.start()
134
135 def testRR(self):
136 """
137 Routing: Round Robin
138
139 Send 10 A queries to "rr.routing.tests.powerdns.com.",
140 check that dnsdist routes half of it to each backend.
141 """
142 numberOfQueries = 10
143 name = 'rr.routing.tests.powerdns.com.'
144 query = dns.message.make_query(name, 'A', 'IN')
145 response = dns.message.make_response(query)
146 rrset = dns.rrset.from_text(name,
147 60,
148 dns.rdataclass.IN,
149 dns.rdatatype.A,
150 '192.0.2.1')
151 response.answer.append(rrset)
152
153 # the round robin counter is shared for UDP and TCP,
154 # so we need to do UDP then TCP to have a clean count
155 for _ in range(numberOfQueries):
156 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
157 receivedQuery.id = query.id
158 self.assertEquals(query, receivedQuery)
159 self.assertEquals(response, receivedResponse)
160
161 for _ in range(numberOfQueries):
162 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
163 receivedQuery.id = query.id
164 self.assertEquals(query, receivedQuery)
165 self.assertEquals(response, receivedResponse)
166
167 for key in self._responsesCounter:
168 value = self._responsesCounter[key]
169 self.assertEquals(value, numberOfQueries / 2)
170
171 class TestRoutingRoundRobinLBOneDown(DNSDistTest):
172
173 _testServer2Port = 5351
174 _config_params = ['_testServerPort', '_testServer2Port']
175 _config_template = """
176 setServerPolicy(roundrobin)
177 s1 = newServer{address="127.0.0.1:%s"}
178 s1:setUp()
179 s2 = newServer{address="127.0.0.1:%s"}
180 s2:setDown()
181 """
182
183 def testRRWithOneDown(self):
184 """
185 Routing: Round Robin with one server down
186
187 Send 100 A queries to "rr.routing.tests.powerdns.com.",
188 check that dnsdist routes all of it to the only backend up.
189 """
190 numberOfQueries = 10
191 name = 'rr.routing.tests.powerdns.com.'
192 query = dns.message.make_query(name, 'A', 'IN')
193 response = dns.message.make_response(query)
194 rrset = dns.rrset.from_text(name,
195 60,
196 dns.rdataclass.IN,
197 dns.rdatatype.A,
198 '192.0.2.1')
199 response.answer.append(rrset)
200
201 # the round robin counter is shared for UDP and TCP,
202 # so we need to do UDP then TCP to have a clean count
203 for _ in range(numberOfQueries):
204 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
205 receivedQuery.id = query.id
206 self.assertEquals(query, receivedQuery)
207 self.assertEquals(response, receivedResponse)
208
209 for _ in range(numberOfQueries):
210 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
211 receivedQuery.id = query.id
212 self.assertEquals(query, receivedQuery)
213 self.assertEquals(response, receivedResponse)
214
215 total = 0
216 for key in self._responsesCounter:
217 value = self._responsesCounter[key]
218 self.assertTrue(value == numberOfQueries or value == 0)
219 total += value
220
221 self.assertEquals(total, numberOfQueries * 2)
222
223 class TestRoutingRoundRobinLBAllDown(DNSDistTest):
224
225 _testServer2Port = 5351
226 _config_params = ['_testServerPort', '_testServer2Port']
227 _config_template = """
228 setServerPolicy(roundrobin)
229 setRoundRobinFailOnNoServer(true)
230 s1 = newServer{address="127.0.0.1:%s"}
231 s1:setDown()
232 s2 = newServer{address="127.0.0.1:%s"}
233 s2:setDown()
234 """
235
236 def testRRWithAllDown(self):
237 """
238 Routing: Round Robin with all servers down
239 """
240 numberOfQueries = 10
241 name = 'alldown.rr.routing.tests.powerdns.com.'
242 query = dns.message.make_query(name, 'A', 'IN')
243 response = dns.message.make_response(query)
244 rrset = dns.rrset.from_text(name,
245 60,
246 dns.rdataclass.IN,
247 dns.rdatatype.A,
248 '192.0.2.1')
249 response.answer.append(rrset)
250
251 for method in ("sendUDPQuery", "sendTCPQuery"):
252 sender = getattr(self, method)
253 (_, receivedResponse) = sender(query, response=None, useQueue=False)
254 self.assertEquals(receivedResponse, None)
255
256 class TestRoutingLuaFFIPerThreadRoundRobinLB(DNSDistTest):
257
258 _testServer2Port = 5351
259 _config_params = ['_testServerPort', '_testServer2Port']
260 _config_template = """
261 setServerPolicyLuaFFIPerThread("luaffiroundrobin", [[
262 local ffi = require("ffi")
263 local C = ffi.C
264
265 local counter = 0
266 return function(servers_list, dq)
267 counter = counter + 1
268 return (counter %% tonumber(C.dnsdist_ffi_servers_list_get_count(servers_list)))
269 end
270 ]])
271
272 s1 = newServer{address="127.0.0.1:%s"}
273 s1:setUp()
274 s2 = newServer{address="127.0.0.1:%s"}
275 s2:setUp()
276 """
277
278 @classmethod
279 def startResponders(cls):
280 print("Launching responders..")
281 cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
282 cls._UDPResponder.setDaemon(True)
283 cls._UDPResponder.start()
284 cls._UDPResponder2 = threading.Thread(name='UDP Responder 2', target=cls.UDPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue])
285 cls._UDPResponder2.setDaemon(True)
286 cls._UDPResponder2.start()
287
288 cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
289 cls._TCPResponder.setDaemon(True)
290 cls._TCPResponder.start()
291
292 cls._TCPResponder2 = threading.Thread(name='TCP Responder 2', target=cls.TCPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue])
293 cls._TCPResponder2.setDaemon(True)
294 cls._TCPResponder2.start()
295
296 def testRR(self):
297 """
298 Routing: Round Robin
299
300 Send 10 A queries to "rr.routing.tests.powerdns.com.",
301 check that dnsdist routes half of it to each backend.
302 """
303 numberOfQueries = 10
304 name = 'rr.routing.tests.powerdns.com.'
305 query = dns.message.make_query(name, 'A', 'IN')
306 response = dns.message.make_response(query)
307 rrset = dns.rrset.from_text(name,
308 60,
309 dns.rdataclass.IN,
310 dns.rdatatype.A,
311 '192.0.2.1')
312 response.answer.append(rrset)
313
314 # the round robin counter is shared for UDP and TCP,
315 # so we need to do UDP then TCP to have a clean count
316 for _ in range(numberOfQueries):
317 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
318 receivedQuery.id = query.id
319 self.assertEquals(query, receivedQuery)
320 self.assertEquals(response, receivedResponse)
321
322 for _ in range(numberOfQueries):
323 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
324 receivedQuery.id = query.id
325 self.assertEquals(query, receivedQuery)
326 self.assertEquals(response, receivedResponse)
327
328 for key in self._responsesCounter:
329 value = self._responsesCounter[key]
330 self.assertEquals(value, numberOfQueries / 2)
331
332 class TestRoutingOrder(DNSDistTest):
333
334 _testServer2Port = 5351
335 _config_params = ['_testServerPort', '_testServer2Port']
336 _config_template = """
337 setServerPolicy(firstAvailable)
338 s1 = newServer{address="127.0.0.1:%s", order=2}
339 s1:setUp()
340 s2 = newServer{address="127.0.0.1:%s", order=1}
341 s2:setUp()
342 """
343
344 @classmethod
345 def startResponders(cls):
346 print("Launching responders..")
347 cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
348 cls._UDPResponder.setDaemon(True)
349 cls._UDPResponder.start()
350 cls._UDPResponder2 = threading.Thread(name='UDP Responder 2', target=cls.UDPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue])
351 cls._UDPResponder2.setDaemon(True)
352 cls._UDPResponder2.start()
353
354 cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
355 cls._TCPResponder.setDaemon(True)
356 cls._TCPResponder.start()
357
358 cls._TCPResponder2 = threading.Thread(name='TCP Responder 2', target=cls.TCPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue])
359 cls._TCPResponder2.setDaemon(True)
360 cls._TCPResponder2.start()
361
362 def testOrder(self):
363 """
364 Routing: firstAvailable policy based on 'order'
365
366 Send 50 A queries to "order.routing.tests.powerdns.com.",
367 check that dnsdist routes all of it to the second backend
368 because it has the lower order value.
369 """
370 numberOfQueries = 50
371 name = 'order.routing.tests.powerdns.com.'
372 query = dns.message.make_query(name, 'A', 'IN')
373 response = dns.message.make_response(query)
374 rrset = dns.rrset.from_text(name,
375 60,
376 dns.rdataclass.IN,
377 dns.rdatatype.A,
378 '192.0.2.1')
379 response.answer.append(rrset)
380
381 for _ in range(numberOfQueries):
382 for method in ("sendUDPQuery", "sendTCPQuery"):
383 sender = getattr(self, method)
384 (receivedQuery, receivedResponse) = sender(query, response)
385 receivedQuery.id = query.id
386 self.assertEquals(query, receivedQuery)
387 self.assertEquals(response, receivedResponse)
388
389 total = 0
390 if 'UDP Responder' in self._responsesCounter:
391 self.assertEquals(self._responsesCounter['UDP Responder'], 0)
392 self.assertEquals(self._responsesCounter['UDP Responder 2'], numberOfQueries)
393 if 'TCP Responder' in self._responsesCounter:
394 self.assertEquals(self._responsesCounter['TCP Responder'], 0)
395 self.assertEquals(self._responsesCounter['TCP Responder 2'], numberOfQueries)
396
397 class TestRoutingNoServer(DNSDistTest):
398
399 _config_template = """
400 newServer{address="127.0.0.1:%s", pool="real"}
401 setServFailWhenNoServer(true)
402 """
403
404 def testPolicyPoolNoServer(self):
405 """
406 Routing: No server should return ServFail
407 """
408 name = 'noserver.routing.tests.powerdns.com.'
409 query = dns.message.make_query(name, 'A', 'IN')
410 expectedResponse = dns.message.make_response(query)
411 expectedResponse.set_rcode(dns.rcode.SERVFAIL)
412
413 for method in ("sendUDPQuery", "sendTCPQuery"):
414 sender = getattr(self, method)
415 (_, receivedResponse) = sender(query, response=None, useQueue=False)
416 self.assertEquals(receivedResponse, expectedResponse)
417
418 class TestRoutingWRandom(DNSDistTest):
419
420 _testServer2Port = 5351
421 _config_params = ['_testServerPort', '_testServer2Port']
422 _config_template = """
423 setServerPolicy(wrandom)
424 s1 = newServer{address="127.0.0.1:%s", weight=1}
425 s1:setUp()
426 s2 = newServer{address="127.0.0.1:%s", weight=2}
427 s2:setUp()
428 """
429
430 @classmethod
431 def startResponders(cls):
432 print("Launching responders..")
433 cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
434 cls._UDPResponder.setDaemon(True)
435 cls._UDPResponder.start()
436 cls._UDPResponder2 = threading.Thread(name='UDP Responder 2', target=cls.UDPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue])
437 cls._UDPResponder2.setDaemon(True)
438 cls._UDPResponder2.start()
439
440 cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
441 cls._TCPResponder.setDaemon(True)
442 cls._TCPResponder.start()
443
444 cls._TCPResponder2 = threading.Thread(name='TCP Responder 2', target=cls.TCPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue])
445 cls._TCPResponder2.setDaemon(True)
446 cls._TCPResponder2.start()
447
448 def testWRandom(self):
449 """
450 Routing: WRandom
451
452 Send 100 A queries to "wrandom.routing.tests.powerdns.com.",
453 check that dnsdist routes less than half to one, more to the other.
454 """
455 numberOfQueries = 100
456 name = 'wrandom.routing.tests.powerdns.com.'
457 query = dns.message.make_query(name, 'A', 'IN')
458 response = dns.message.make_response(query)
459 rrset = dns.rrset.from_text(name,
460 60,
461 dns.rdataclass.IN,
462 dns.rdatatype.A,
463 '192.0.2.1')
464 response.answer.append(rrset)
465
466 # the counter is shared for UDP and TCP,
467 # so we need to do UDP then TCP to have a clean count
468 for _ in range(numberOfQueries):
469 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
470 receivedQuery.id = query.id
471 self.assertEquals(query, receivedQuery)
472 self.assertEquals(response, receivedResponse)
473
474 for _ in range(numberOfQueries):
475 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
476 receivedQuery.id = query.id
477 self.assertEquals(query, receivedQuery)
478 self.assertEquals(response, receivedResponse)
479
480 # The lower weight downstream should receive less than half the queries
481 self.assertLess(self._responsesCounter['UDP Responder'], numberOfQueries * 0.50)
482 self.assertLess(self._responsesCounter['TCP Responder'], numberOfQueries * 0.50)
483
484 # The higher weight downstream should receive more than half the queries
485 self.assertGreater(self._responsesCounter['UDP Responder 2'], numberOfQueries * 0.50)
486 self.assertGreater(self._responsesCounter['TCP Responder 2'], numberOfQueries * 0.50)
487
488
489 class TestRoutingHighValueWRandom(DNSDistTest):
490
491 _testServer2Port = 5351
492 _consoleKey = DNSDistTest.generateConsoleKey()
493 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
494 _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_testServer2Port']
495 _config_template = """
496 setKey("%s")
497 controlSocket("127.0.0.1:%s")
498 setServerPolicy(wrandom)
499 s1 = newServer{address="127.0.0.1:%s", weight=2000000000}
500 s1:setUp()
501 s2 = newServer{address="127.0.0.1:%s", weight=2000000000}
502 s2:setUp()
503 """
504
505 @classmethod
506 def startResponders(cls):
507 print("Launching responders..")
508 cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
509 cls._UDPResponder.setDaemon(True)
510 cls._UDPResponder.start()
511 cls._UDPResponder2 = threading.Thread(name='UDP Responder 2', target=cls.UDPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue])
512 cls._UDPResponder2.setDaemon(True)
513 cls._UDPResponder2.start()
514
515 cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
516 cls._TCPResponder.setDaemon(True)
517 cls._TCPResponder.start()
518
519 cls._TCPResponder2 = threading.Thread(name='TCP Responder 2', target=cls.TCPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue])
520 cls._TCPResponder2.setDaemon(True)
521 cls._TCPResponder2.start()
522
523 def testHighValueWRandom(self):
524 """
525 Routing: WRandom (overflow)
526
527 Send 100 A queries to "wrandom-overflow.routing.tests.powerdns.com.",
528 check that dnsdist routes to each downstream, rather than failing with
529 no-policy.
530 """
531 numberOfQueries = 100
532 name = 'wrandom-overflow.routing.tests.powerdns.com.'
533 query = dns.message.make_query(name, 'A', 'IN')
534 response = dns.message.make_response(query)
535 rrset = dns.rrset.from_text(name,
536 60,
537 dns.rdataclass.IN,
538 dns.rdatatype.A,
539 '192.0.2.1')
540 response.answer.append(rrset)
541
542 # the counter is shared for UDP and TCP,
543 # so we need to do UDP then TCP to have a clean count
544 for _ in range(numberOfQueries):
545 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
546 receivedQuery.id = query.id
547 self.assertEquals(query, receivedQuery)
548 self.assertEquals(response, receivedResponse)
549
550 for _ in range(numberOfQueries):
551 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
552 receivedQuery.id = query.id
553 self.assertEquals(query, receivedQuery)
554 self.assertEquals(response, receivedResponse)
555
556 stats = self.sendConsoleCommand("dumpStats()").split()
557 stats_dict = {}
558
559 # Map to a dict with every other element being the value to the previous one
560 for i, x in enumerate(stats):
561 if not i % 2:
562 stats_dict[x] = stats[i+1]
563
564 # There should be no queries getting "no-policy" responses
565 self.assertEquals(stats_dict['no-policy'], '0')
566
567 # Each downstream should receive some queries, but it will be unbalanced
568 # because the sum of the weights is higher than INT_MAX.
569 # The first downstream will receive more than half the queries
570 self.assertGreater(self._responsesCounter['UDP Responder'], numberOfQueries / 2)
571 self.assertGreater(self._responsesCounter['TCP Responder'], numberOfQueries / 2)
572
573 # The second downstream will receive the remainder of the queries, but it might very well be 0
574 if 'UDP Responder 2' in self._responsesCounter:
575 self.assertEquals(self._responsesCounter['UDP Responder 2'], numberOfQueries - self._responsesCounter['UDP Responder'])
576 if 'TCP Responder 2' in self._responsesCounter:
577 self.assertEquals(self._responsesCounter['TCP Responder 2'], numberOfQueries - self._responsesCounter['TCP Responder'])
578
579 class TestRoutingBadWeightWRandom(DNSDistTest):
580
581 _testServer2Port = 5351
582 _consoleKey = DNSDistTest.generateConsoleKey()
583 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
584 _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_testServer2Port']
585 _config_template = """
586 setKey("%s")
587 controlSocket("127.0.0.1:%s")
588 setServerPolicy(wrandom)
589 s1 = newServer{address="127.0.0.1:%s", weight=-1}
590 s2 = newServer{address="127.0.0.1:%s", weight=2147483648}
591 """
592 _checkConfigExpectedOutput = b"""Error creating new server: downstream weight value must be greater than 0.
593 Error creating new server: downstream weight value must be between 1 and 2147483647
594 Configuration 'configs/dnsdist_TestRoutingBadWeightWRandom.conf' OK!
595 """
596
597 def testBadWeightWRandom(self):
598 """
599 Routing: WRandom
600
601 Test that downstreams cannot be added with invalid weights.
602 """
603 # There should be no downstreams
604 self.assertTrue(self.sendConsoleCommand("getServer(0)").startswith("Error"))