From: Remi Gacogne Date: Fri, 25 Oct 2019 09:24:43 +0000 (+0200) Subject: dnsdist: Add regression tests for our prometheus export X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=116b2602f9b3e5f8f668ed33f4fa76a0baf07e93;p=pdns dnsdist: Add regression tests for our prometheus export --- diff --git a/.circleci/config.yml b/.circleci/config.yml index 089625cbd..fc35a7e8e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -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 diff --git a/build-scripts/travis.sh b/build-scripts/travis.sh index c9ffa50cb..0b64ee5e7 100755 --- a/build-scripts/travis.sh +++ b/build-scripts/travis.sh @@ -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 index 000000000..02b015996 --- /dev/null +++ b/regression-tests.dnsdist/test_Prometheus.py @@ -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)