dnsdist: Add regression tests for our prometheus export
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 25 Oct 2019 09:24:43 +0000 (11:24 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 25 Oct 2019 09:29:57 +0000 (11:29 +0200)
.circleci/config.yml
build-scripts/travis.sh
regression-tests.dnsdist/test_Prometheus.py [new file with mode: 0644]

index 089625cbd30980f5e973d124c191db84451f1a70..fc35a7e8ec23b9625bbd2beff9afc87fe12806e3 100644 (file)
@@ -1276,6 +1276,10 @@ jobs:
             apt-get -qq --no-install-recommends install snmpd
             sed "s/agentxperms 0700 0755 dnsdist/agentxperms 0700 0755/g" regression-tests.dnsdist/snmpd.conf > /etc/snmp/snmpd.conf
             /etc/init.d/snmpd start
+      - run:
+          name: install prometheus tools
+          command: |
+            apt-get -qq --no-install-recommends install prometheus
       - run:
           name: Run dnsdist tests
           workdir: ~/project/regression-tests.dnsdist
index c9ffa50cb61113f32edcef8d2280ccacf5001d4e..0b64ee5e76245da0e900daa33ac14f9c858288e9 100755 (executable)
@@ -639,7 +639,7 @@ test_recursor() {
 
 test_dnsdist(){
   run "cd regression-tests.dnsdist"
-  run "DNSDISTBIN=$HOME/dnsdist/bin/dnsdist ./runtests -v --ignore-files='(?:^\.|^_,|^setup\.py$|^test_DOH\.py$|^test_OCSP\.py$|^test_TLSSessionResumption\.py$)'"
+  run "DNSDISTBIN=$HOME/dnsdist/bin/dnsdist ./runtests -v --ignore-files='(?:^\.|^_,|^setup\.py$|^test_DOH\.py$|^test_OCSP\.py$|^test_Prometheus\.py$|^test_TLSSessionResumption\.py$)'"
   run "rm -f ./DNSCryptResolver.cert ./DNSCryptResolver.key"
   run "cd .."
 }
diff --git a/regression-tests.dnsdist/test_Prometheus.py b/regression-tests.dnsdist/test_Prometheus.py
new file mode 100644 (file)
index 0000000..02b0159
--- /dev/null
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+import requests
+import subprocess
+from dnsdisttests import DNSDistTest
+
+class TestPrometheus(DNSDistTest):
+
+    _webTimeout = 2.0
+    _webServerPort = 8083
+    _webServerBasicAuthPassword = 'secret'
+    _webServerAPIKey = 'apisecret'
+    _config_params = ['_testServerPort', '_webServerPort', '_webServerBasicAuthPassword', '_webServerAPIKey']
+    _config_template = """
+    newServer{address="127.0.0.1:%s"}
+    webserver("127.0.0.1:%s", "%s", "%s")
+    """
+
+    def checkPrometheusContentBasic(self, content):
+        for line in content.splitlines():
+            if line.startswith('# HELP'):
+                tokens = line.split(' ')
+                self.assertGreaterEqual(len(tokens), 4)
+            elif line.startswith('# TYPE'):
+                tokens = line.split(' ')
+                self.assertEquals(len(tokens), 4)
+                self.assertIn(tokens[3], ['counter', 'gauge', 'histogram'])
+            elif not line.startswith('#'):
+                tokens = line.split(' ')
+                self.assertEquals(len(tokens), 2)
+                if not line.startswith('dnsdist_'):
+                    raise AssertionError('Expecting prometheus metric to be prefixed by \'dnsdist_\', got: "%s"' % (line))
+
+    def checkPrometheusContentPromtool(self, content):
+        output = None
+        try:
+            testcmd = ['promtool', 'check', 'metrics']
+            process = subprocess.Popen(testcmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
+            output = process.communicate(input=content)
+        except subprocess.CalledProcessError as exc:
+            raise AssertionError('%s failed (%d): %s' % (testcmd, process.returncode, process.output))
+
+        # commented out because promtool returns 3 because of the "_total" suffix warnings
+        #if process.returncode != 0:
+        #  raise AssertionError('%s failed (%d): %s' % (testcmd, process.returncode, output))
+
+        for line in output[0].splitlines():
+            if line.endswith(b"should have \"_total\" suffix"):
+                continue
+            raise AssertionError('%s returned an unexpected output. Faulty line is "%s", complete content is "%s"' % (testcmd, line, output))
+
+    def testMetrics(self):
+        """
+        Prometheus: Retrieve metrics
+        """
+        url = 'http://127.0.0.1:' + str(self._webServerPort) + '/metrics'
+        r = requests.get(url, auth=('whatever', self._webServerBasicAuthPassword), timeout=self._webTimeout)
+        self.assertTrue(r)
+        self.assertEquals(r.status_code, 200)
+        self.checkPrometheusContentBasic(r.text)
+        self.checkPrometheusContentPromtool(r.content)