From 16078b817287978655b2f63941614d8168abb337 Mon Sep 17 00:00:00 2001 From: James Coglan Date: Fri, 21 Jun 2024 15:40:20 +0100 Subject: [PATCH] resolved: tests for dns_query_go() -- with and without network link --- src/resolve/test-dns-query.c | 102 +++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/src/resolve/test-dns-query.c b/src/resolve/test-dns-query.c index 0f917a3e45..4f6d70f1c1 100644 --- a/src/resolve/test-dns-query.c +++ b/src/resolve/test-dns-query.c @@ -3,6 +3,9 @@ #include "log.h" #include "resolved-dns-query.h" #include "resolved-dns-rr.h" +#include "resolved-dns-scope.h" +#include "resolved-dns-server.h" +#include "resolved-link.h" #include "resolved-manager.h" #include "tests.h" @@ -614,4 +617,103 @@ TEST(dns_query_process_cname_many_success_match_multiple_cname) { dns_resource_key_unref(key); } +/* ================================================================ + * dns_query_go() + * ================================================================ */ + +/* Testing this function is somewhat problematic since, in addition to setting up the state for query + * candidates, their scopes and transactions, it also directly initiates I/O to files and the network. In + * particular: + * + * - The very first thing it does is try to respond to the query by reading the system /etc/hosts file, which + * may be symlinked to a SystemD resource. Ideally we could test this without accessing global files. + * + * - dns_scope_get_dns_server() calls manager_get_dns_server(), which tries to read /etc/resolv.conf. + * + * - A potential solution to these issues would be to let these file paths be configured instead of + * hard-coded into the source. + * + * - dns_scope_good_domain(), by checking dns_scope_get_dns_server(), will not match with a scope that does + * not have a server configured, either on the scope's link (if it has one) or the manager's main/fallback + * server. Configuring a server means that dns_query_candidate_go() and then dns_transaction_go() will send + * UDP/TCP traffic to that server. Ideally we'd like to test that we can set up all the candidate and + * transaction state without actually causing any requests to be sent. + */ + +static void dns_scope_freep(DnsScope **s) { + dns_scope_free(*s); +} + +typedef struct GoConfig { + bool use_link; +} GoConfig; + +static GoConfig mk_go_config(void) { + return (GoConfig) { + .use_link = false + }; +} + +static void exercise_dns_query_go(GoConfig *cfg) { + Manager manager = {}; + Link *link = NULL; + _cleanup_(dns_server_unrefp) DnsServer *server = NULL; + _cleanup_(dns_scope_freep) DnsScope *scope = NULL; + + _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL; + _cleanup_(dns_query_freep) DnsQuery *query = NULL; + + DnsProtocol protocol = DNS_PROTOCOL_DNS; + int family = AF_INET; + int flags = SD_RESOLVED_FLAGS_MAKE(protocol, family, false, false); + int ifindex; + + union in_addr_union server_addr = { .in.s_addr = htobe32(0x7f000001) }; + const char *server_name = "localhost"; + uint16_t port = 53; + DnsServerType type; + + if (cfg->use_link) { + ifindex = 1; + ASSERT_OK(link_new(&manager, &link, ifindex)); + ASSERT_NOT_NULL(link); + type = DNS_SERVER_LINK; + } else { + ifindex = 0; + link = NULL; + type = DNS_SERVER_FALLBACK; + } + + ASSERT_OK(sd_event_new(&manager.event)); + ASSERT_NOT_NULL(manager.event); + + ASSERT_OK(dns_server_new(&manager, &server, type, link, family, &server_addr, + port, ifindex, server_name, RESOLVE_CONFIG_SOURCE_DBUS)); + + ASSERT_NOT_NULL(server); + + ASSERT_OK(dns_scope_new(&manager, &scope, link, protocol, family)); + ASSERT_NOT_NULL(scope); + + ASSERT_OK(dns_question_new_address(&question, AF_INET, "www.example.com", false)); + ASSERT_NOT_NULL(question); + + ASSERT_OK(dns_query_new(&manager, &query, question, question, NULL, ifindex, flags)); + ASSERT_NOT_NULL(query); + + ASSERT_OK(dns_query_go(query)); + + dns_server_unref(server); + sd_event_unref(manager.event); +} + +TEST(dns_query_go) { + GoConfig cfg1 = mk_go_config(); + exercise_dns_query_go(&cfg1); + + GoConfig cfg2 = mk_go_config(); + cfg2.use_link = true; + exercise_dns_query_go(&cfg2); +} + DEFINE_TEST_MAIN(LOG_DEBUG); -- 2.25.1