]>
Commit | Line | Data |
---|---|---|
1 | #!/usr/bin/env python | |
2 | ||
3 | import requests | |
4 | from dnsdisttests import DNSDistTest | |
5 | ||
6 | class TestBasics(DNSDistTest): | |
7 | ||
8 | _webTimeout = 2.0 | |
9 | _webServerPort = 8083 | |
10 | _webServerBasicAuthPassword = 'secret' | |
11 | _webServerAPIKey = 'apisecret' | |
12 | # paths accessible using the API key | |
13 | _apiPaths = ['/api/v1/servers/localhost', '/api/v1/servers/localhost/config', '/api/v1/servers/localhost/statistics', '/jsonstat?command=stats', '/jsonstat?command=dynblocklist'] | |
14 | # paths accessible using basic auth only (list not exhaustive) | |
15 | _basicOnlyPaths = ['/', '/index.html'] | |
16 | _config_params = ['_testServerPort', '_webServerPort', '_webServerBasicAuthPassword', '_webServerAPIKey'] | |
17 | _config_template = """ | |
18 | newServer{address="127.0.0.1:%s"} | |
19 | webserver("127.0.0.1:%s", "%s", "%s") | |
20 | """ | |
21 | ||
22 | def testBasicAuth(self): | |
23 | """ | |
24 | API: Basic Authentication | |
25 | """ | |
26 | for path in self._basicOnlyPaths + self._apiPaths: | |
27 | url = 'http://127.0.0.1:' + str(self._webServerPort) + path | |
28 | r = requests.get(url, auth=('whatever', self._webServerBasicAuthPassword), timeout=self._webTimeout) | |
29 | self.assertTrue(r) | |
30 | self.assertEquals(r.status_code, 200) | |
31 | ||
32 | def testXAPIKey(self): | |
33 | """ | |
34 | API: X-Api-Key | |
35 | """ | |
36 | headers = {'x-api-key': self._webServerAPIKey} | |
37 | for path in self._apiPaths: | |
38 | url = 'http://127.0.0.1:' + str(self._webServerPort) + path | |
39 | r = requests.get(url, headers=headers, timeout=self._webTimeout) | |
40 | self.assertTrue(r) | |
41 | self.assertEquals(r.status_code, 200) | |
42 | ||
43 | def testBasicAuthOnly(self): | |
44 | """ | |
45 | API: Basic Authentication Only | |
46 | """ | |
47 | headers = {'x-api-key': self._webServerAPIKey} | |
48 | for path in self._basicOnlyPaths: | |
49 | url = 'http://127.0.0.1:' + str(self._webServerPort) + path | |
50 | r = requests.get(url, headers=headers, timeout=self._webTimeout) | |
51 | self.assertEquals(r.status_code, 401) | |
52 | ||
53 | def testServersLocalhost(self): | |
54 | """ | |
55 | API: /api/v1/servers/localhost | |
56 | """ | |
57 | headers = {'x-api-key': self._webServerAPIKey} | |
58 | url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost' | |
59 | r = requests.get(url, headers=headers, timeout=self._webTimeout) | |
60 | self.assertTrue(r) | |
61 | self.assertEquals(r.status_code, 200) | |
62 | self.assertTrue(r.json()) | |
63 | content = r.json() | |
64 | ||
65 | self.assertEquals(content['daemon_type'], 'dnsdist') | |
66 | ||
67 | for key in ['version', 'acl', 'local', 'rules', 'servers', 'frontends']: | |
68 | self.assertIn(key, content) | |
69 | ||
70 | for rule in content['rules']: | |
71 | for key in ['id', 'matches', 'rule', 'action']: | |
72 | self.assertIn(key, rule) | |
73 | for key in ['id', 'matches']: | |
74 | self.assertTrue(rule[key] >= 0) | |
75 | ||
76 | for server in content['servers']: | |
77 | for key in ['id', 'latency', 'name', 'weight', 'outstanding', 'qpsLimit', | |
78 | 'reuseds', 'state', 'address', 'pools', 'qps', 'queries', 'order']: | |
79 | self.assertIn(key, server) | |
80 | ||
81 | for key in ['id', 'latency', 'weight', 'outstanding', 'qpsLimit', 'reuseds', | |
82 | 'qps', 'queries', 'order']: | |
83 | self.assertTrue(server[key] >= 0) | |
84 | ||
85 | self.assertTrue(server['state'] in ['up', 'down', 'UP', 'DOWN']) | |
86 | ||
87 | for frontend in content['frontends']: | |
88 | for key in ['id', 'address', 'udp', 'tcp', 'queries']: | |
89 | self.assertIn(key, frontend) | |
90 | ||
91 | for key in ['id', 'queries']: | |
92 | self.assertTrue(frontend[key] >= 0) | |
93 | ||
94 | def testServersLocalhostConfig(self): | |
95 | """ | |
96 | API: /api/v1/servers/localhost/config | |
97 | """ | |
98 | headers = {'x-api-key': self._webServerAPIKey} | |
99 | url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost/config' | |
100 | r = requests.get(url, headers=headers, timeout=self._webTimeout) | |
101 | self.assertTrue(r) | |
102 | self.assertEquals(r.status_code, 200) | |
103 | self.assertTrue(r.json()) | |
104 | content = r.json() | |
105 | values = {} | |
106 | for entry in content: | |
107 | for key in ['type', 'name', 'value']: | |
108 | self.assertIn(key, entry) | |
109 | ||
110 | self.assertEquals(entry['type'], 'ConfigSetting') | |
111 | values[entry['name']] = entry['value'] | |
112 | ||
113 | for key in ['acl', 'control-socket', 'ecs-override', 'ecs-source-prefix-v4', | |
114 | 'ecs-source-prefix-v6', 'fixup-case', 'max-outstanding', 'server-policy', | |
115 | 'stale-cache-entries-ttl', 'tcp-recv-timeout', 'tcp-send-timeout', | |
116 | 'truncate-tc', 'verbose', 'verbose-health-checks']: | |
117 | self.assertIn(key, values) | |
118 | ||
119 | for key in ['max-outstanding', 'stale-cache-entries-ttl', 'tcp-recv-timeout', | |
120 | 'tcp-send-timeout']: | |
121 | self.assertTrue(values[key] >= 0) | |
122 | ||
123 | self.assertTrue(values['ecs-source-prefix-v4'] >= 0 and values['ecs-source-prefix-v4'] <= 32) | |
124 | self.assertTrue(values['ecs-source-prefix-v6'] >= 0 and values['ecs-source-prefix-v6'] <= 128) | |
125 | ||
126 | def testServersLocalhostStatistics(self): | |
127 | """ | |
128 | API: /api/v1/servers/localhost/statistics | |
129 | """ | |
130 | headers = {'x-api-key': self._webServerAPIKey} | |
131 | url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost/statistics' | |
132 | r = requests.get(url, headers=headers, timeout=self._webTimeout) | |
133 | self.assertTrue(r) | |
134 | self.assertEquals(r.status_code, 200) | |
135 | self.assertTrue(r.json()) | |
136 | content = r.json() | |
137 | values = {} | |
138 | for entry in content: | |
139 | self.assertIn('type', entry) | |
140 | self.assertIn('name', entry) | |
141 | self.assertIn('value', entry) | |
142 | self.assertEquals(entry['type'], 'StatisticItem') | |
143 | values[entry['name']] = entry['value'] | |
144 | ||
145 | expected = ['responses', 'servfail-responses', 'queries', 'acl-drops', 'block-filter', | |
146 | 'rule-drop', 'rule-nxdomain', 'self-answered', 'downstream-timeouts', | |
147 | 'downstream-send-errors', 'trunc-failures', 'no-policy', 'latency0-1', | |
148 | 'latency1-10', 'latency10-50', 'latency50-100', 'latency100-1000', | |
149 | 'latency-slow', 'latency-avg100', 'latency-avg1000', 'latency-avg10000', | |
150 | 'latency-avg1000000', 'uptime', 'real-memory-usage', 'noncompliant-queries', | |
151 | 'noncompliant-responses', 'rdqueries', 'empty-queries', 'cache-hits', | |
152 | 'cache-misses', 'cpu-user-msec', 'cpu-sys-msec', 'fd-usage', 'dyn-blocked', | |
153 | 'dyn-block-nmg-size'] | |
154 | ||
155 | for key in expected: | |
156 | self.assertIn(key, values) | |
157 | self.assertTrue(values[key] >= 0) | |
158 | ||
159 | def testJsonstatStats(self): | |
160 | """ | |
161 | API: /jsonstat?command=stats | |
162 | """ | |
163 | headers = {'x-api-key': self._webServerAPIKey} | |
164 | url = 'http://127.0.0.1:' + str(self._webServerPort) + '/jsonstat?command=stats' | |
165 | r = requests.get(url, headers=headers, timeout=self._webTimeout) | |
166 | self.assertTrue(r) | |
167 | self.assertEquals(r.status_code, 200) | |
168 | self.assertTrue(r.json()) | |
169 | content = r.json() | |
170 | ||
171 | for key in ['packetcache-hits', 'packetcache-misses', 'over-capacity-drops', 'too-old-drops']: | |
172 | self.assertIn(key, content) | |
173 | self.assertTrue(content[key] >= 0) | |
174 | ||
175 | expected = ['responses', 'servfail-responses', 'queries', 'acl-drops', 'block-filter', | |
176 | 'rule-drop', 'rule-nxdomain', 'self-answered', 'downstream-timeouts', | |
177 | 'downstream-send-errors', 'trunc-failures', 'no-policy', 'latency0-1', | |
178 | 'latency1-10', 'latency10-50', 'latency50-100', 'latency100-1000', | |
179 | 'latency-slow', 'latency-avg100', 'latency-avg1000', 'latency-avg10000', | |
180 | 'latency-avg1000000', 'uptime', 'real-memory-usage', 'noncompliant-queries', | |
181 | 'noncompliant-responses', 'rdqueries', 'empty-queries', 'cache-hits', | |
182 | 'cache-misses', 'cpu-user-msec', 'cpu-sys-msec', 'fd-usage', 'dyn-blocked', | |
183 | 'dyn-block-nmg-size'] | |
184 | ||
185 | for key in expected: | |
186 | self.assertIn(key, content) | |
187 | self.assertTrue(content[key] >= 0) | |
188 | ||
189 | def testJsonstatDynblocklist(self): | |
190 | """ | |
191 | API: /jsonstat?command=dynblocklist | |
192 | """ | |
193 | headers = {'x-api-key': self._webServerAPIKey} | |
194 | url = 'http://127.0.0.1:' + str(self._webServerPort) + '/jsonstat?command=dynblocklist' | |
195 | r = requests.get(url, headers=headers, timeout=self._webTimeout) | |
196 | self.assertTrue(r) | |
197 | self.assertEquals(r.status_code, 200) | |
198 | ||
199 | content = r.json() | |
200 | ||
201 | if content: | |
202 | for key in ['reason', 'seconds', 'blocks']: | |
203 | self.assertIn(key, content) | |
204 | ||
205 | for key in ['blocks']: | |
206 | self.assertTrue(content[key] >= 0) |