1 /*
2  * Copyright (c) 2024 Endress+Hauser AG
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <zephyr/fff.h>
7 #include <zephyr/ztest.h>
8 #include "dns_cache.h"
9 
10 #define TEST_DNS_CACHE_SIZE        12
11 #define TEST_DNS_CACHE_DEFAULT_TTL 1
12 DNS_CACHE_DEFINE(test_dns_cache, TEST_DNS_CACHE_SIZE);
13 
clear_cache(void * fixture)14 void clear_cache(void *fixture)
15 {
16 	ARG_UNUSED(fixture);
17 	dns_cache_flush(&test_dns_cache);
18 }
19 
20 ZTEST_SUITE(net_dns_cache_test, NULL, NULL, clear_cache, NULL, NULL);
21 
ZTEST(net_dns_cache_test,test_simple_cache_entry)22 ZTEST(net_dns_cache_test, test_simple_cache_entry)
23 {
24 	struct dns_addrinfo info_write = {.ai_family = AF_INET};
25 	struct dns_addrinfo info_read = {0};
26 	const char *query = "example.com";
27 	enum dns_query_type query_type = DNS_QUERY_TYPE_A;
28 
29 	zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL),
30 		   "Cache entry adding should work.");
31 	zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type, &info_read, 1));
32 	zassert_equal(AF_INET, info_read.ai_family);
33 }
34 
ZTEST(net_dns_cache_test,test_not_cached)35 ZTEST(net_dns_cache_test, test_not_cached)
36 {
37 	struct dns_addrinfo info_read = {0};
38 	const char *query = "example.com";
39 	enum dns_query_type query_type = DNS_QUERY_TYPE_A;
40 
41 	zassert_equal(0, dns_cache_find(&test_dns_cache, query, query_type, &info_read, 1));
42 	zassert_equal(0, info_read.ai_family);
43 }
44 
ZTEST(net_dns_cache_test,test_fill_cache)45 ZTEST(net_dns_cache_test, test_fill_cache)
46 {
47 	struct dns_addrinfo info_write = {.ai_family = AF_INET};
48 	struct dns_addrinfo info_read[TEST_DNS_CACHE_SIZE] = {0};
49 	const char *query = "example.com";
50 	enum dns_query_type query_type = DNS_QUERY_TYPE_A;
51 
52 	for (size_t i = 0; i < TEST_DNS_CACHE_SIZE; i++) {
53 		zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write,
54 					 TEST_DNS_CACHE_DEFAULT_TTL),
55 			   "Cache entry adding should work.");
56 	}
57 	zassert_equal(TEST_DNS_CACHE_SIZE, dns_cache_find(&test_dns_cache, query, query_type,
58 							  info_read, TEST_DNS_CACHE_SIZE));
59 	zassert_equal(AF_INET, info_read[TEST_DNS_CACHE_SIZE - 1].ai_family);
60 }
61 
ZTEST(net_dns_cache_test,test_flush)62 ZTEST(net_dns_cache_test, test_flush)
63 {
64 	struct dns_addrinfo info_write = {.ai_family = AF_INET};
65 	struct dns_addrinfo info_read[TEST_DNS_CACHE_SIZE] = {0};
66 	const char *query = "example.com";
67 	enum dns_query_type query_type = DNS_QUERY_TYPE_A;
68 
69 	for (size_t i = 0; i < TEST_DNS_CACHE_SIZE; i++) {
70 		zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write,
71 					 TEST_DNS_CACHE_DEFAULT_TTL),
72 			   "Cache entry adding should work.");
73 	}
74 	zassert_ok(dns_cache_flush(&test_dns_cache));
75 	zassert_equal(0, dns_cache_find(&test_dns_cache, query, query_type, info_read,
76 					TEST_DNS_CACHE_SIZE));
77 	zassert_equal(0, info_read[TEST_DNS_CACHE_SIZE - 1].ai_family);
78 }
79 
ZTEST(net_dns_cache_test,test_fill_cache_to_small)80 ZTEST(net_dns_cache_test, test_fill_cache_to_small)
81 {
82 	struct dns_addrinfo info_write = {.ai_family = AF_INET};
83 	struct dns_addrinfo info_read[TEST_DNS_CACHE_SIZE - 1] = {0};
84 	const char *query = "example.com";
85 	enum dns_query_type query_type = DNS_QUERY_TYPE_A;
86 
87 	for (size_t i = 0; i < TEST_DNS_CACHE_SIZE; i++) {
88 		zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write,
89 					 TEST_DNS_CACHE_DEFAULT_TTL),
90 			   "Cache entry adding should work.");
91 	}
92 	zassert_equal(-ENOSR, dns_cache_find(&test_dns_cache, query, query_type, info_read,
93 					     TEST_DNS_CACHE_SIZE - 1));
94 	zassert_equal(AF_INET, info_read[TEST_DNS_CACHE_SIZE - 2].ai_family);
95 }
96 
ZTEST(net_dns_cache_test,test_closest_expiry_removed)97 ZTEST(net_dns_cache_test, test_closest_expiry_removed)
98 {
99 	struct dns_addrinfo info_write = {.ai_family = AF_INET};
100 	struct dns_addrinfo info_read = {0};
101 	const char *closest_expiry = "example.com";
102 	enum dns_query_type query_type = DNS_QUERY_TYPE_A;
103 
104 	zassert_ok(dns_cache_add(&test_dns_cache, closest_expiry, &info_write,
105 				 TEST_DNS_CACHE_DEFAULT_TTL),
106 		   "Cache entry adding should work.");
107 	k_sleep(K_MSEC(1));
108 	for (size_t i = 0; i < TEST_DNS_CACHE_SIZE; i++) {
109 		zassert_ok(dns_cache_add(&test_dns_cache, "example2.com", &info_write,
110 					 TEST_DNS_CACHE_DEFAULT_TTL),
111 			   "Cache entry adding should work.");
112 	}
113 	zassert_equal(0,
114 		      dns_cache_find(&test_dns_cache, closest_expiry, query_type, &info_read, 1));
115 	zassert_equal(0, info_read.ai_family);
116 }
117 
ZTEST(net_dns_cache_test,test_expired_entries_removed)118 ZTEST(net_dns_cache_test, test_expired_entries_removed)
119 {
120 	struct dns_addrinfo info_write = {.ai_family = AF_INET};
121 	struct dns_addrinfo info_read[3] = {0};
122 	const char *query = "example.com";
123 	enum dns_query_type query_type = DNS_QUERY_TYPE_A;
124 
125 	zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL),
126 		   "Cache entry adding should work.");
127 	zassert_ok(
128 		dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL * 2),
129 		"Cache entry adding should work.");
130 	zassert_ok(
131 		dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL * 3),
132 		"Cache entry adding should work.");
133 	zassert_equal(3, dns_cache_find(&test_dns_cache, query, query_type, info_read, 3));
134 	zassert_equal(AF_INET, info_read[0].ai_family);
135 	k_sleep(K_MSEC(TEST_DNS_CACHE_DEFAULT_TTL * 1000 + 1));
136 	zassert_equal(2, dns_cache_find(&test_dns_cache, query, query_type, info_read, 3));
137 	zassert_equal(AF_INET, info_read[0].ai_family);
138 	k_sleep(K_MSEC(TEST_DNS_CACHE_DEFAULT_TTL * 1000 + 1));
139 	zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type, info_read, 3));
140 	zassert_equal(AF_INET, info_read[0].ai_family);
141 	k_sleep(K_MSEC(1));
142 	zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type, info_read, 3));
143 	zassert_equal(AF_INET, info_read[0].ai_family);
144 }
145 
ZTEST(net_dns_cache_test,test_different_type_not_returned)146 ZTEST(net_dns_cache_test, test_different_type_not_returned)
147 {
148 	struct dns_addrinfo info_write = {.ai_family = AF_INET};
149 	struct dns_addrinfo info_read = {0};
150 	const char *query = "example.com";
151 	enum dns_query_type query_type = DNS_QUERY_TYPE_AAAA;
152 
153 	zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL),
154 		   "Cache entry adding should work.");
155 	zassert_equal(0, dns_cache_find(&test_dns_cache, query, query_type, &info_read, 1));
156 	zassert_equal(0, info_read.ai_family);
157 }
158 
ZTEST(net_dns_cache_test,test_only_expected_type_returned)159 ZTEST(net_dns_cache_test, test_only_expected_type_returned)
160 {
161 	struct dns_addrinfo info_write_a = {.ai_family = AF_INET};
162 	struct dns_addrinfo info_write_b = {.ai_family = AF_INET6};
163 	struct dns_addrinfo info_read = {0};
164 	const char *query = "example.com";
165 	enum dns_query_type query_type_a = DNS_QUERY_TYPE_A;
166 	enum dns_query_type query_type_b = DNS_QUERY_TYPE_AAAA;
167 
168 	zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write_a, TEST_DNS_CACHE_DEFAULT_TTL),
169 		   "Cache entry adding should work.");
170 	zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write_b, TEST_DNS_CACHE_DEFAULT_TTL),
171 		   "Cache entry adding should work.");
172 	zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type_a, &info_read, 1));
173 	zassert_equal(AF_INET, info_read.ai_family);
174 	zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type_b, &info_read, 1));
175 	zassert_equal(AF_INET6, info_read.ai_family);
176 }
177