1#!/usr/bin/python3 2 3# Copyright (C) Internet Systems Consortium, Inc. ("ISC") 4# 5# SPDX-License-Identifier: MPL-2.0 6# 7# This Source Code Form is subject to the terms of the Mozilla Public 8# License, v. 2.0. If a copy of the MPL was not distributed with this 9# file, you can obtain one at https://mozilla.org/MPL/2.0/. 10# 11# See the COPYRIGHT file distributed with this work for additional 12# information regarding copyright ownership. 13 14from datetime import datetime 15import xml.etree.ElementTree as ET 16 17import pytest 18 19import generic 20import pytest_custom_markers 21 22pytestmark = pytest_custom_markers.have_libxml2 23requests = pytest.importorskip("requests") 24 25 26# XML helper functions 27def fetch_zones_xml(statsip, statsport): 28 r = requests.get( 29 "http://{}:{}/xml/v3/zones".format(statsip, statsport), timeout=600 30 ) 31 assert r.status_code == 200 32 33 root = ET.fromstring(r.text) 34 35 default_view = None 36 for view in root.find("views").iter("view"): 37 if view.attrib["name"] == "_default": 38 default_view = view 39 break 40 assert default_view is not None 41 42 return default_view.find("zones").findall("zone") 43 44 45def fetch_traffic_xml(statsip, statsport): 46 def load_counters(data): 47 out = {} 48 for counter in data.findall("counter"): 49 out[counter.attrib["name"]] = int(counter.text) 50 51 return out 52 53 r = requests.get( 54 "http://{}:{}/xml/v3/traffic".format(statsip, statsport), timeout=600 55 ) 56 assert r.status_code == 200 57 58 root = ET.fromstring(r.text) 59 60 traffic = {} 61 for ip in ["ipv4", "ipv6"]: 62 for proto in ["udp", "tcp"]: 63 proto_root = root.find("traffic").find(ip).find(proto) 64 for counters in proto_root.findall("counters"): 65 if counters.attrib["type"] == "request-size": 66 key = "dns-{}-requests-sizes-received-{}".format(proto, ip) 67 else: 68 key = "dns-{}-responses-sizes-sent-{}".format(proto, ip) 69 70 values = load_counters(counters) 71 traffic[key] = values 72 73 return traffic 74 75 76def load_timers_xml(zone, primary=True): 77 name = zone.attrib["name"] 78 79 loaded_el = zone.find("loaded") 80 assert loaded_el is not None 81 loaded = datetime.strptime(loaded_el.text, generic.fmt) 82 83 expires_el = zone.find("expires") 84 refresh_el = zone.find("refresh") 85 if primary: 86 assert expires_el is None 87 assert refresh_el is None 88 expires = None 89 refresh = None 90 else: 91 assert expires_el is not None 92 assert refresh_el is not None 93 expires = datetime.strptime(expires_el.text, generic.fmt) 94 refresh = datetime.strptime(refresh_el.text, generic.fmt) 95 96 return (name, loaded, expires, refresh) 97 98 99def load_zone_xml(zone): 100 name = zone.attrib["name"] 101 102 return name 103 104 105def test_zone_timers_primary_xml(statsport): 106 generic.test_zone_timers_primary( 107 fetch_zones_xml, 108 load_timers_xml, 109 statsip="10.53.0.1", 110 statsport=statsport, 111 zonedir="ns1", 112 ) 113 114 115def test_zone_timers_secondary_xml(statsport): 116 generic.test_zone_timers_secondary( 117 fetch_zones_xml, 118 load_timers_xml, 119 statsip="10.53.0.3", 120 statsport=statsport, 121 zonedir="ns3", 122 ) 123 124 125def test_zone_with_many_keys_xml(statsport): 126 generic.test_zone_with_many_keys( 127 fetch_zones_xml, load_zone_xml, statsip="10.53.0.2", statsport=statsport 128 ) 129 130 131def test_traffic_xml(named_port, statsport): 132 generic_dnspython = pytest.importorskip("generic_dnspython") 133 generic_dnspython.test_traffic( 134 fetch_traffic_xml, statsip="10.53.0.2", statsport=statsport, port=named_port 135 ) 136