]> git.ipfire.org Git - thirdparty/pdns.git/blame - regression-tests.dnsdist/test_API.py
dnsdist: Add API regression tests
[thirdparty/pdns.git] / regression-tests.dnsdist / test_API.py
CommitLineData
02bbf9eb
RG
1#!/usr/bin/env python
2
3import requests
4from dnsdisttests import DNSDistTest
5
6class 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)