From: Otto Moerbeek Date: Thu, 23 Oct 2025 08:34:01 +0000 (+0200) Subject: Rewrite tests using reloading of config in place of several test classes with differe... X-Git-Tag: rec-5.4.0-alpha1~103^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6ec85711ec2f315eec6df7ee9f978567dd6a42ef;p=thirdparty%2Fpdns.git Rewrite tests using reloading of config in place of several test classes with different configs Signed-off-by: Otto Moerbeek Signed-off-by: Otto Moerbeek --- diff --git a/pdns/recursordist/rec-rust-lib/cxxsupport.cc b/pdns/recursordist/rec-rust-lib/cxxsupport.cc index f3d3371885..f3b0af57b6 100644 --- a/pdns/recursordist/rec-rust-lib/cxxsupport.cc +++ b/pdns/recursordist/rec-rust-lib/cxxsupport.cc @@ -1425,6 +1425,7 @@ bool pdns::settings::rec::luaItemSet(const pdns::rust::settings::rec::Recursorse alldefault = alldefault && settings.recursor.allowed_additional_qtypes.empty(); alldefault = alldefault && settings.incoming.proxymappings.empty(); alldefault = alldefault && settings.outgoing.tls_configurations.empty(); // actually not a Lua item, but very much alike + alldefault = alldefault && settings.logging.opentelemetry_trace_conditions.empty(); // actually not a Lua item, but very much alike return !alldefault; } diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index b6ec2c6214..b0c4b127f0 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -1975,11 +1975,9 @@ static RecursorControlChannel::Answer help(ArgIterator /* begin */, ArgIterator RecursorControlChannel::Answer luaconfig(bool broadcast) { ProxyMapping proxyMapping; - OpenTelemetryTraceConditions conditions; LuaConfigItems lci; lci.d_slog = g_slog; extern std::unique_ptr g_proxyMapping; - extern std::unique_ptr g_OTConditions; if (!g_luaSettingsInYAML) { try { if (::arg()["lua-config-file"].empty()) { @@ -2022,6 +2020,7 @@ RecursorControlChannel::Answer luaconfig(bool broadcast) } auto generation = g_luaconfs.getLocal()->generation; lci.generation = generation + 1; + OpenTelemetryTraceConditions conditions; pdns::settings::rec::fromBridgeStructToLuaConfig(settings, lci, proxyMapping, conditions); activateLuaConfig(lci); lci = g_luaconfs.getCopy(); @@ -2031,6 +2030,7 @@ RecursorControlChannel::Answer luaconfig(bool broadcast) broadcastFunction([conds = std::move(conditions)] { return pleaseSupplantOTConditions(conds); }); } else { + extern std::unique_ptr g_OTConditions; // Initial proxy mapping g_proxyMapping = proxyMapping.empty() ? nullptr : std::make_unique(proxyMapping); g_OTConditions = conditions.empty() ? nullptr : std::make_unique(conditions); diff --git a/regression-tests.recursor-dnssec/test_Protobuf.py b/regression-tests.recursor-dnssec/test_Protobuf.py index 20b85aa0bc..169e763b95 100644 --- a/regression-tests.recursor-dnssec/test_Protobuf.py +++ b/regression-tests.recursor-dnssec/test_Protobuf.py @@ -10,14 +10,14 @@ import clientsubnetoption # Python2/3 compatibility hacks try: - from queue import Queue + from queue import Queue except ImportError: - from Queue import Queue + from Queue import Queue try: - range = xrange + range = xrange except NameError: - pass + pass from recursortests import RecursorTest @@ -382,7 +382,27 @@ logging: def generateRecursorConfig(cls, confdir): super(ProtobufDefaultTest, cls).generateRecursorYamlConfig(confdir, False) - def testA(self): + def reloadConfig(self, config): + confdir = os.path.join('configs', ProtobufDefaultTest._confdir) + ProtobufDefaultTest._config_template = config + ProtobufDefaultTest.generateRecursorYamlConfig(confdir, False) + ProtobufDefaultTest.recControl(confdir, 'reload-yaml') + + config_default = """ +recursor: + auth_zones: + - zone: example + file: configs/%s/example.zone + event_trace_enabled: 4 +logging: + protobuf_servers: + - servers: [127.0.0.1:%s, 127.0.0.1:%s] + opentelemetry_trace_conditions: + - acls: ['0.0.0.0/0'] +""" % (_confdir, protobufServersParameters[0].port, protobufServersParameters[1].port) + + def testADefault(self): + self.reloadConfig(self.config_default) name = 'a.example.' expected = dns.rrset.from_text(name, 0, dns.rdataclass.IN, 'A', '192.0.2.42') query = dns.message.make_query(name, 'A', want_dnssec=True) @@ -407,9 +427,7 @@ logging: self.checkProtobufResponse(msg, protocol, res, '127.0.0.1') self.assertEqual(len(msg.response.rrs), 1) rr = msg.response.rrs[0] - # we have max-cache-ttl set to 15 - if method == 'sendUDPQuery': - self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15) + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15, checkTTL=False) self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.42') self.checkProtobufOT(msg, True, True) self.checkProtobufEDE(msg, 0, '') @@ -437,15 +455,14 @@ logging: self.checkProtobufResponse(msg, protocol, res, '127.0.0.1') self.assertEqual(len(msg.response.rrs), 1) rr = msg.response.rrs[0] - # we have max-cache-ttl set to 15 - if method == 'sendUDPQuery': - self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15) + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15, checkTTL=False) self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.42') self.checkProtobufOT(msg, True, True) self.checkProtobufEDE(msg, 0, '') self.checkNoRemainingMessage() - def testCNAME(self): + def testCNAMEDefault(self): + self.reloadConfig(self.config_default) name = 'cname.example.' expectedCNAME = dns.rrset.from_text(name, 0, dns.rdataclass.IN, 'CNAME', 'a.example.') expectedA = dns.rrset.from_text('a.example.', 0, dns.rdataclass.IN, 'A', '192.0.2.42') @@ -466,23 +483,17 @@ logging: self.assertEqual(len(msg.response.rrs), 2) rr = msg.response.rrs[0] # we don't want to check the TTL for the A record, it has been cached by the previous test - self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.CNAME, name, 15) + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.CNAME, name, 15, checkTTL=False) self.assertEqual(rr.rdata, b'a.example.') rr = msg.response.rrs[1] - # we have max-cache-ttl set to 15 self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, 'a.example.', 15, checkTTL=False) self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.42') self.checkProtobufOT(msg, True, True) self.checkProtobufEDE(msg, 0, '') self.checkNoRemainingMessage() -class ProtobufDefaultTraceIDOnlyTest(TestRecursorProtobuf): - """ - This test makes sure that we correctly export queries and response over protobuf, but not with full OpenTelemetry data - """ - _confdir = 'ProtobufDefaultTraceIDOnly' - _config_template = """ + config_traceid_only = """ recursor: auth_zones: - zone: example @@ -496,11 +507,8 @@ logging: traceid_only: true """ % (_confdir, protobufServersParameters[0].port, protobufServersParameters[1].port) - @classmethod - def generateRecursorConfig(cls, confdir): - super(ProtobufDefaultTraceIDOnlyTest, cls).generateRecursorYamlConfig(confdir, False) - - def testA(self): + def testATraceIDOnly(self): + self.reloadConfig(self.config_traceid_only) name = 'a.example.' expected = dns.rrset.from_text(name, 0, dns.rdataclass.IN, 'A', '192.0.2.42') edns = self.getOpenTelemetryEDNS(b'012345678012345678') @@ -526,9 +534,7 @@ logging: self.checkProtobufResponse(msg, protocol, res, '127.0.0.1') self.assertEqual(len(msg.response.rrs), 1) rr = msg.response.rrs[0] - # we have max-cache-ttl set to 15 - if method == 'sendUDPQuery': - self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15) + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15, checkTTL=False) self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.42') self.checkProtobufOT(msg, False, True) self.checkProtobufEDE(msg, 0, '') @@ -556,15 +562,14 @@ logging: self.checkProtobufResponse(msg, protocol, res, '127.0.0.1') self.assertEqual(len(msg.response.rrs), 1) rr = msg.response.rrs[0] - # we have max-cache-ttl set to 15 - if method == 'sendUDPQuery': - self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15) + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15, checkTTL=False) self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.42') self.checkProtobufOT(msg, False, True) self.checkProtobufEDE(msg, 0, '') self.checkNoRemainingMessage() - def testCNAME(self): + def testCNAMETraceIDOnly(self): + self.reloadConfig(self.config_traceid_only) name = 'cname.example.' expectedCNAME = dns.rrset.from_text(name, 0, dns.rdataclass.IN, 'CNAME', 'a.example.') expectedA = dns.rrset.from_text('a.example.', 0, dns.rdataclass.IN, 'A', '192.0.2.42') @@ -585,23 +590,16 @@ logging: self.assertEqual(len(msg.response.rrs), 2) rr = msg.response.rrs[0] # we don't want to check the TTL for the A record, it has been cached by the previous test - self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.CNAME, name, 15) + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.CNAME, name, 15, checkTTL=False) self.assertEqual(rr.rdata, b'a.example.') rr = msg.response.rrs[1] - # we have max-cache-ttl set to 15 self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, 'a.example.', 15, checkTTL=False) self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.42') self.checkProtobufOT(msg, False, False) self.checkProtobufEDE(msg, 0, '') self.checkNoRemainingMessage() -class ProtobufDefaultOTAOnlyTest(TestRecursorProtobuf): - """ - This test makes sure that we correctly export queries and response over protobuf, but only for A queries - """ - - _confdir = 'ProtobufDefaultOTAOnly' - _config_template = """ + config_otaonly = """ recursor: auth_zones: - zone: example @@ -616,11 +614,8 @@ logging: qtypes: ['A'] """ % (_confdir, protobufServersParameters[0].port, protobufServersParameters[1].port) - @classmethod - def generateRecursorConfig(cls, confdir): - super(ProtobufDefaultOTAOnlyTest, cls).generateRecursorYamlConfig(confdir, False) - - def testA(self): + def testAOTAOnly(self): + self.reloadConfig(self.config_otaonly) name = 'a.example.' expected = dns.rrset.from_text(name, 0, dns.rdataclass.IN, 'A', '192.0.2.42') query = dns.message.make_query(name, 'A', want_dnssec=True) @@ -645,9 +640,7 @@ logging: self.checkProtobufResponse(msg, protocol, res, '127.0.0.1') self.assertEqual(len(msg.response.rrs), 1) rr = msg.response.rrs[0] - # we have max-cache-ttl set to 15 - if method == 'sendUDPQuery': - self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15) + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15, checkTTL=False) self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.42') self.checkProtobufOT(msg, True, True) self.checkProtobufEDE(msg, 0, '') @@ -675,15 +668,116 @@ logging: self.checkProtobufResponse(msg, protocol, res, '127.0.0.1') self.assertEqual(len(msg.response.rrs), 1) rr = msg.response.rrs[0] - # we have max-cache-ttl set to 15 + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15, checkTTL=False) + self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.42') + self.checkProtobufOT(msg, True, True) + self.checkProtobufEDE(msg, 0, '') + self.checkNoRemainingMessage() + + def testAAAAOTAOnly(self): + self.reloadConfig(self.config_otaonly) + name = 'aaaa.example.' + expectedAAAA = dns.rrset.from_text('aaaa.example.', 0, dns.rdataclass.IN, 'AAAA', '2001:db8::2') + edns = self.getOpenTelemetryEDNS(b'012345678012345678') + query = dns.message.make_query(name, 'AAAA', want_dnssec=True, options=[edns]) + query.flags |= dns.flags.CD + raw = self.sendUDPQuery(query, decode=False) + res = dns.message.from_wire(raw) + self.assertRRsetInAnswer(res, expectedAAAA) + + # check the protobuf messages corresponding to the UDP query and answer + # but first let the protobuf messages the time to get there + msg = self.getFirstProtobufMessage() + self.checkProtobufQuery(msg, dnsmessage_pb2.PBDNSMessage.UDP, query, dns.rdataclass.IN, dns.rdatatype.AAAA, name) + # then the response + msg = self.getFirstProtobufMessage() + self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, res, '127.0.0.1', receivedSize=len(raw)) + self.assertEqual(len(msg.response.rrs), 1) + rr = msg.response.rrs[0] + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.AAAA, 'aaaa.example.', 15, checkTTL=False) + self.assertEqual(socket.inet_ntop(socket.AF_INET6, rr.rdata), '2001:db8::2') + print(msg) + self.checkProtobufOT(msg, False, True) + self.checkProtobufEDE(msg, 0, '') + self.checkNoRemainingMessage() + + config_nameonly = """ +recursor: + auth_zones: + - zone: example + file: configs/%s/example.zone + event_trace_enabled: 4 +logging: + protobuf_servers: + - servers: [127.0.0.1:%s, 127.0.0.1:%s] + opentelemetry_trace_conditions: + - acls: ['0.0.0.0/0'] + traceid_only: false + qnames: ['a.example'] +""" % (_confdir, protobufServersParameters[0].port, protobufServersParameters[1].port) + + def testCorrectNameOnly(self): + self.reloadConfig(self.config_nameonly) + name = 'a.example.' + expected = dns.rrset.from_text(name, 0, dns.rdataclass.IN, 'A', '192.0.2.42') + query = dns.message.make_query(name, 'A', want_dnssec=True) + query.flags |= dns.flags.CD + for method in ('sendUDPQuery', 'sendTCPQuery'): + sender = getattr(self, method) + res = sender(query) + + self.assertRRsetInAnswer(res, expected) + + # check the protobuf messages corresponding to the query and answer + msg = self.getFirstProtobufMessage() + if method == 'sendUDPQuery': + protocol = dnsmessage_pb2.PBDNSMessage.UDP + else: + protocol = dnsmessage_pb2.PBDNSMessage.TCP + self.checkProtobufQuery(msg, protocol, query, dns.rdataclass.IN, dns.rdatatype.A, name) + # wire format, RD and CD set in headerflags, plus DO bit in flags part of EDNS Version + self.checkProtobufHeaderFlagsAndEDNSVersion(msg, 0x0110, 0x00008000) + # then the response + msg = self.getFirstProtobufMessage() + self.checkProtobufResponse(msg, protocol, res, '127.0.0.1') + self.assertEqual(len(msg.response.rrs), 1) + rr = msg.response.rrs[0] + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15, checkTTL=False) + self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.42') + self.checkProtobufOT(msg, True, True) + self.checkProtobufEDE(msg, 0, '') + self.checkNoRemainingMessage() + # + # again, for a PC cache hit + # + for method in ('sendUDPQuery', 'sendTCPQuery'): + sender = getattr(self, method) + res = sender(query) + + self.assertRRsetInAnswer(res, expected) + + # check the protobuf messages corresponding to the UDP query and answer + msg = self.getFirstProtobufMessage() if method == 'sendUDPQuery': - self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15) + protocol = dnsmessage_pb2.PBDNSMessage.UDP + else: + protocol = dnsmessage_pb2.PBDNSMessage.TCP + self.checkProtobufQuery(msg, protocol, query, dns.rdataclass.IN, dns.rdatatype.A, name) + # wire format, RD and CD set in headerflags, plus DO bit in flags part of EDNS Version + self.checkProtobufHeaderFlagsAndEDNSVersion(msg, 0x0110, 0x00008000) + # then the response + msg = self.getFirstProtobufMessage() + self.checkProtobufResponse(msg, protocol, res, '127.0.0.1') + self.assertEqual(len(msg.response.rrs), 1) + rr = msg.response.rrs[0] + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15, checkTTL=False) self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.42') self.checkProtobufOT(msg, True, True) self.checkProtobufEDE(msg, 0, '') self.checkNoRemainingMessage() - def testAAAA(self): + def testOtherNameOnly(self): + self.reloadConfig(self.config_nameonly) name = 'aaaa.example.' expectedAAAA = dns.rrset.from_text('aaaa.example.', 0, dns.rdataclass.IN, 'AAAA', '2001:db8::2') edns = self.getOpenTelemetryEDNS(b'012345678012345678') @@ -702,7 +796,6 @@ logging: self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, res, '127.0.0.1', receivedSize=len(raw)) self.assertEqual(len(msg.response.rrs), 1) rr = msg.response.rrs[0] - # we have max-cache-ttl set to 15 self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.AAAA, 'aaaa.example.', 15, checkTTL=False) self.assertEqual(socket.inet_ntop(socket.AF_INET6, rr.rdata), '2001:db8::2') print(msg)