]>
Commit | Line | Data |
---|---|---|
9396d955 RG |
1 | #!/usr/bin/env python |
2 | import struct | |
3 | import time | |
4 | import dns | |
630eb526 | 5 | from dnsdisttests import DNSDistTest, pickAvailablePort |
06b0e003 RG |
6 | |
7 | try: | |
8 | range = xrange | |
9 | except NameError: | |
10 | pass | |
9396d955 RG |
11 | |
12 | class TestTCPLimits(DNSDistTest): | |
13 | ||
98650fde RG |
14 | # this test suite uses a different responder port |
15 | # because it uses a different health check configuration | |
630eb526 | 16 | _testServerPort = pickAvailablePort() |
e44df0f1 | 17 | _answerUnexpected = True |
98650fde | 18 | |
9396d955 RG |
19 | _tcpIdleTimeout = 2 |
20 | _maxTCPQueriesPerConn = 5 | |
21 | _maxTCPConnsPerClient = 3 | |
22 | _maxTCPConnDuration = 5 | |
23 | _config_template = """ | |
24 | newServer{address="127.0.0.1:%s"} | |
25 | setTCPRecvTimeout(%s) | |
26 | setMaxTCPQueriesPerConnection(%s) | |
27 | setMaxTCPConnectionsPerClient(%s) | |
28 | setMaxTCPConnectionDuration(%s) | |
29 | """ | |
30 | _config_params = ['_testServerPort', '_tcpIdleTimeout', '_maxTCPQueriesPerConn', '_maxTCPConnsPerClient', '_maxTCPConnDuration'] | |
2a3cafcd | 31 | _verboseMode = True |
9396d955 RG |
32 | |
33 | def testTCPQueriesPerConn(self): | |
34 | """ | |
35 | TCP Limits: Maximum number of queries | |
36 | """ | |
37 | name = 'maxqueriesperconn.tcp.tests.powerdns.com.' | |
38 | query = dns.message.make_query(name, 'A', 'IN') | |
39 | conn = self.openTCPConnection() | |
40 | ||
41 | count = 0 | |
b4f23783 | 42 | for idx in range(self._maxTCPQueriesPerConn): |
9396d955 RG |
43 | try: |
44 | self.sendTCPQueryOverConnection(conn, query) | |
45 | response = self.recvTCPResponseOverConnection(conn) | |
46 | self.assertTrue(response) | |
47 | count = count + 1 | |
48 | except: | |
49 | pass | |
50 | ||
51 | # this one should fail | |
52 | failed = False | |
53 | try: | |
54 | self.sendTCPQueryOverConnection(conn, query) | |
55 | response = self.recvTCPResponseOverConnection(conn) | |
56 | self.assertFalse(response) | |
57 | if not response: | |
58 | failed = True | |
59 | else: | |
60 | count = count + 1 | |
61 | except: | |
62 | failed = True | |
63 | ||
64 | conn.close() | |
65 | self.assertTrue(failed) | |
66 | self.assertEqual(count, self._maxTCPQueriesPerConn) | |
67 | ||
68 | def testTCPConnsPerClient(self): | |
69 | """ | |
70 | TCP Limits: Maximum number of conns per client | |
71 | """ | |
72 | name = 'maxconnsperclient.tcp.tests.powerdns.com.' | |
73 | query = dns.message.make_query(name, 'A', 'IN') | |
74 | conns = [] | |
75 | ||
b4f23783 | 76 | for idx in range(self._maxTCPConnsPerClient + 1): |
9396d955 RG |
77 | conns.append(self.openTCPConnection()) |
78 | ||
79 | count = 0 | |
80 | failed = 0 | |
81 | for conn in conns: | |
82 | try: | |
83 | self.sendTCPQueryOverConnection(conn, query) | |
84 | response = self.recvTCPResponseOverConnection(conn) | |
85 | if response: | |
86 | count = count + 1 | |
87 | else: | |
88 | failed = failed + 1 | |
89 | except: | |
90 | failed = failed + 1 | |
91 | ||
92 | for conn in conns: | |
93 | conn.close() | |
94 | ||
2a3cafcd RG |
95 | # wait a bit to be sure that dnsdist closed the connections |
96 | # and decremented the counters on its side, otherwise subsequent | |
97 | # connections will be dropped | |
98 | time.sleep(1) | |
99 | ||
9396d955 RG |
100 | self.assertEqual(count, self._maxTCPConnsPerClient) |
101 | self.assertEqual(failed, 1) | |
102 | ||
103 | def testTCPDuration(self): | |
104 | """ | |
105 | TCP Limits: Maximum duration | |
106 | """ | |
107 | name = 'duration.tcp.tests.powerdns.com.' | |
108 | ||
109 | start = time.time() | |
110 | conn = self.openTCPConnection() | |
111 | # immediately send the maximum size | |
112 | conn.send(struct.pack("!H", 65535)) | |
113 | ||
114 | count = 0 | |
a6c76ba3 | 115 | while count < (self._maxTCPConnDuration * 20): |
9396d955 RG |
116 | try: |
117 | # sleeping for only one second keeps us below the | |
118 | # idle timeout (setTCPRecvTimeout()) | |
6be16d4c | 119 | time.sleep(0.1) |
06b0e003 | 120 | conn.send(b'A') |
9396d955 | 121 | count = count + 1 |
06b0e003 RG |
122 | except Exception as e: |
123 | print("Exception: %s!" % (e)) | |
9396d955 RG |
124 | break |
125 | ||
126 | end = time.time() | |
127 | ||
4bfebc93 CH |
128 | self.assertAlmostEqual(count / 10, self._maxTCPConnDuration, delta=2) |
129 | self.assertAlmostEqual(end - start, self._maxTCPConnDuration, delta=2) | |
9396d955 RG |
130 | |
131 | conn.close() | |
d4d57f56 RG |
132 | |
133 | class TestTCPFrontendLimits(DNSDistTest): | |
134 | ||
135 | # this test suite uses a different responder port | |
136 | # because it uses a different health check configuration | |
630eb526 | 137 | _testServerPort = pickAvailablePort() |
d4d57f56 RG |
138 | _answerUnexpected = True |
139 | ||
140 | _skipListeningOnCL = True | |
141 | _tcpIdleTimeout = 2 | |
142 | _maxTCPConnsPerFrontend = 10 | |
143 | _config_template = """ | |
144 | newServer{address="127.0.0.1:%s"} | |
145 | setLocal("%s:%d", {maxConcurrentTCPConnections=%d}) | |
146 | """ | |
147 | _config_params = ['_testServerPort', '_dnsDistListeningAddr', '_dnsDistPort', '_maxTCPConnsPerFrontend'] | |
148 | _verboseMode = True | |
149 | ||
150 | def testTCPConnsPerFrontend(self): | |
151 | """ | |
152 | TCP Frontend Limits: Maximum number of conns per frontend | |
153 | """ | |
154 | name = 'maxconnsperfrontend.tcp.tests.powerdns.com.' | |
155 | query = dns.message.make_query(name, 'A', 'IN') | |
156 | conns = [] | |
157 | ||
158 | for idx in range(self._maxTCPConnsPerFrontend + 1): | |
159 | conns.append(self.openTCPConnection()) | |
160 | ||
161 | count = 0 | |
162 | failed = 0 | |
163 | for conn in conns: | |
164 | try: | |
165 | self.sendTCPQueryOverConnection(conn, query) | |
166 | response = self.recvTCPResponseOverConnection(conn) | |
167 | if response: | |
168 | count = count + 1 | |
169 | else: | |
170 | failed = failed + 1 | |
171 | except: | |
172 | failed = failed + 1 | |
173 | ||
174 | for conn in conns: | |
175 | conn.close() | |
176 | ||
177 | # wait a bit to be sure that dnsdist closed the connections | |
178 | # and decremented the counters on its side, otherwise subsequent | |
179 | # connections will be dropped | |
180 | time.sleep(1) | |
181 | ||
182 | self.assertEqual(count, self._maxTCPConnsPerFrontend) | |
183 | self.assertEqual(failed, 1) |