From: Miod Vallat Date: Fri, 11 Apr 2025 08:49:57 +0000 (+0200) Subject: Add API networks and views testing. X-Git-Tag: auth-5.0.0-alpha1~1^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2da02f9a1c3f06408ef1ccbdb69e243b69bfb494;p=thirdparty%2Fpdns.git Add API networks and views testing. --- diff --git a/regression-tests.api/runtests.py b/regression-tests.api/runtests.py index b82c623752..9e8ec5c11f 100755 --- a/regression-tests.api/runtests.py +++ b/regression-tests.api/runtests.py @@ -67,6 +67,7 @@ AUTH_LMDB_TPL = """ # Generated by runtests.py launch=lmdb lmdb-filename="""+LMDB_DB+""" +views """ AUTH_COMMON_TPL = """ diff --git a/regression-tests.api/test_Views.py b/regression-tests.api/test_Views.py new file mode 100644 index 0000000000..e4a24b7d74 --- /dev/null +++ b/regression-tests.api/test_Views.py @@ -0,0 +1,163 @@ +# this tests Networks and Views + +import subprocess +import json +import unittest +import os + +from test_helper import ApiTestCase, is_auth, is_auth_lmdb, pdnsutil +from test_Zones import AuthZonesHelperMixin + +@unittest.skipIf(not is_auth(), "Not applicable") +@unittest.skipIf(not is_auth_lmdb(), "Views require the LMDB backend") +class Networks(ApiTestCase): + def setUp(self): + super(Networks, self).setUp() + + def tearDown(self): + super(Networks, self).tearDown() + + def test_networks(self): + r = self.set_network('192.0.2.0/24', view='view1') + self.assertEqual(r.status_code, 204) + self.assertEqual(r.content, b"") + + # Check network presence + nets = self.get_networks() + self.assertEqual(nets['192.0.2.0/24'], 'view1') + + # Check individual fetch + r = self.get_network('192.0.2.0/24') + print(r.content) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.json()['networks'][0], dict(network='192.0.2.0/24', view='view1')) # FIXME: should this really be wrapped inside `networks:`? + + # empty view name is equivalent to delete + r = self.set_network('192.0.2.0/24', view='') + print(r.content) + self.assertEqual(r.status_code, 204) + self.assertEqual(r.content, b"") + + # Check network absence + nets = self.get_networks() + self.assertNotIn('192.0.2.0/24', nets) + + # Check individual fetch + r = self.get_network('192.0.2.0/24') + print(r.content) + self.assertEqual(r.status_code, 404) + + def set_network(self, prefix, **content): + r = self.session.put( + self.url("/api/v1/servers/localhost/networks/"+prefix), + data=json.dumps(content), + headers={'content-type': 'application/json'}) + + return r + + def get_network(self, prefix): + r = self.session.get( + self.url("/api/v1/servers/localhost/networks/"+prefix), + headers={'content-type': 'application/json'}) + + return r + + def get_networks(self): + r = self.session.get( + self.url("/api/v1/servers/localhost/networks"), + headers={'content-type': 'application/json'}) + + ret = {} + + for netview in r.json()['networks']: + net = netview['network'] + view = netview['view'] + self.assertNotIn(net, ret) + ret[net] = view + + return ret + +@unittest.skipIf(not is_auth(), "Not applicable") +@unittest.skipIf(not is_auth_lmdb(), "Views require the LMDB backend") +class Views(ApiTestCase, AuthZonesHelperMixin): + def setUp(self): + super(Views, self).setUp() + self.create_zone('example.com..spiceoflife') + + def tearDown(self): + super(Views, self).tearDown() + self.session.delete(self.url("/api/v1/servers/localhost/zones/example.com..spiceoflife")) + + def _test_views(self, variant=''): + zone = 'example.com.' + variant + r = self.set_view_zone('view1', zone) + self.assertEqual(r.status_code, 204) + self.assertEqual(r.content, b"") + + # Check view presence + r = self.get_views() + self.assertEqual(r.status_code, 200) + self.assertIn('view1', r.json()["views"]) + + # Check individual fetch + r = self.get_view('view1') + print(r) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.json()["zones"], [zone]) + + r = self.del_view_zone('view1', zone) + print(r.content) + self.assertEqual(r.status_code, 204) + self.assertEqual(r.content, b"") + + # Check view absence + r = self.get_views() + self.assertEqual(r.status_code, 200) + self.assertNotIn('view1', r.json()["views"]) + + # Check individual fetch + r = self.get_view('view1') + print(r.content) + self.assertEqual(r.status_code, 404) + + def test_views_novariant(self): + return self._test_views() + + def test_views_variant(self): + return self._test_views('.spiceoflife') + + def set_view_zone(self, view, zone): + r = self.session.post( + self.url("/api/v1/servers/localhost/views/"+view), + data=json.dumps(dict(name=zone)), + headers={'content-type': 'application/json'}) + + self.assertEqual(r.status_code, 204) + + return r + + def del_view_zone(self, view, zone): + r = self.session.delete( + self.url("/api/v1/servers/localhost/views/"+view+"/"+zone), + data=json.dumps(dict(name=zone)), + headers={'content-type': 'application/json'}) + + self.assertEqual(r.status_code, 204) + + return r + + def get_view(self, view): + r = self.session.get( + self.url("/api/v1/servers/localhost/views/"+view), + headers={'content-type': 'application/json'}) + + return r + + def get_views(self): + r = self.session.get( + self.url("/api/v1/servers/localhost/views"), + headers={'content-type': 'application/json'}) + + self.assertEqual(r.status_code, 200) + + return r diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 3902376ac2..6538c2ee67 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -456,7 +456,7 @@ class AuthZones(ApiTestCase, AuthZonesHelperMixin): data=json.dumps(payload), headers={'content-type': 'application/json'}) self.assertEqual(r.status_code, 422) - self.assertIn('Unable to parse DNS Name', r.json()['error']) + self.assertIn('Unable to parse Zone Name', r.json()['error']) def test_create_zone_restricted_chars(self): name = 'test:' + unique_zone_name() # : isn't good as a name. diff --git a/regression-tests/backends/lmdb-master b/regression-tests/backends/lmdb-master index a02fd240bf..6cdc3b482c 100644 --- a/regression-tests/backends/lmdb-master +++ b/regression-tests/backends/lmdb-master @@ -87,7 +87,7 @@ __EOF__ $RUNWRAPPER_PDNSUTIL $PDNSUTIL --config-dir=. --config-name=lmdb set-options-json tsig.com$plusvariant '{"producer":{"group":["pdns-group-x","pdns-group-y"]}}' fi - [ -n "$plusvariant" ] && $RUNWRAPPER_PDNSUTIL $PDNSUTIL --config-dir=. --config-name=lmdb network-set 0.0.0.0/0 variant-view + [ -n "$plusvariant" ] && $RUNWRAPPER_PDNSUTIL $PDNSUTIL --config-dir=. --config-name=lmdb set-network 0.0.0.0/0 variant-view for variant in foo bar do @@ -106,8 +106,8 @@ __EOF__ $RUNWRAPPER_PDNSUTIL $PDNSUTIL --config-dir=. --config-name=lmdb add-record example.org..foo target TXT '"hello from target..foo"' $RUNWRAPPER_PDNSUTIL $PDNSUTIL --config-dir=. --config-name=lmdb view-add-zone view1 example.org..foo - $RUNWRAPPER_PDNSUTIL $PDNSUTIL --config-dir=. --config-name=lmdb network-set 192.0.2.0/24 view1 - $RUNWRAPPER_PDNSUTIL $PDNSUTIL --config-dir=. --config-name=lmdb network-set 192.0.2.0/25 view2 + $RUNWRAPPER_PDNSUTIL $PDNSUTIL --config-dir=. --config-name=lmdb set-network 192.0.2.0/24 view1 + $RUNWRAPPER_PDNSUTIL $PDNSUTIL --config-dir=. --config-name=lmdb set-network 192.0.2.0/25 view2 $RUNWRAPPER $PDNS --loglevel=7 --daemon=no --local-address=$address --local-port=$port --config-dir=. \ --config-name=lmdb --socket-dir=./ --no-shuffle \ diff --git a/regression-tests/tests/views-management/command b/regression-tests/tests/views-management/command index fde841f178..419547383f 100755 --- a/regression-tests/tests/views-management/command +++ b/regression-tests/tests/views-management/command @@ -10,29 +10,29 @@ pdnsutil_wrapper view-add-zone myview example.org..variant3 set +e echo == one view -pdnsutil_wrapper view-list +pdnsutil_wrapper list-views echo == with one zone -pdnsutil_wrapper view-list myview +pdnsutil_wrapper list-view myview pdnsutil_wrapper view-add-zone myotherview example.com echo == view with one zone -pdnsutil_wrapper view-list myotherview +pdnsutil_wrapper list-view myotherview pdnsutil_wrapper view-add-zone myview example.org..variant2 pdnsutil_wrapper view-add-zone myview example.net..variant5 echo == with two zones -pdnsutil_wrapper view-list myview +pdnsutil_wrapper list-view myview pdnsutil_wrapper view-del-zone myview example.org..variant2 echo == view with one zone -pdnsutil_wrapper view-list myview +pdnsutil_wrapper list-view myview pdnsutil_wrapper view-del-zone myotherview example.com echo == one view -pdnsutil_wrapper view-list +pdnsutil_wrapper list-views echo == check proper variant replacement -pdnsutil_wrapper view-list myview +pdnsutil_wrapper list-view myview pdnsutil_wrapper view-add-zone myview example.net..completelydifferent -pdnsutil_wrapper view-list myview +pdnsutil_wrapper list-view myview