1 /*
2 * Copyright (c) 2024 Endress+Hauser AG
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <errno.h>
7 #include <zephyr/fff.h>
8 #include <zephyr/ztest.h>
9 #include "dns_cache.h"
10
11 #define TEST_DNS_CACHE_SIZE 12
12 #define TEST_DNS_CACHE_DEFAULT_TTL 1
13 DNS_CACHE_DEFINE(test_dns_cache, TEST_DNS_CACHE_SIZE);
14
clear_cache(void * fixture)15 void clear_cache(void *fixture)
16 {
17 ARG_UNUSED(fixture);
18 dns_cache_flush(&test_dns_cache);
19 }
20
21 ZTEST_SUITE(net_dns_cache_test, NULL, NULL, clear_cache, NULL, NULL);
22
ZTEST(net_dns_cache_test,test_simple_cache_entry)23 ZTEST(net_dns_cache_test, test_simple_cache_entry)
24 {
25 struct dns_addrinfo info_write = {.ai_family = AF_INET};
26 struct dns_addrinfo info_read = {0};
27 const char *query = "example.com";
28 enum dns_query_type query_type = DNS_QUERY_TYPE_A;
29
30 zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL),
31 "Cache entry adding should work.");
32 zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type, &info_read, 1));
33 zassert_equal(AF_INET, info_read.ai_family);
34 }
35
ZTEST(net_dns_cache_test,test_not_cached)36 ZTEST(net_dns_cache_test, test_not_cached)
37 {
38 struct dns_addrinfo info_read = {0};
39 const char *query = "example.com";
40 enum dns_query_type query_type = DNS_QUERY_TYPE_A;
41
42 zassert_equal(0, dns_cache_find(&test_dns_cache, query, query_type, &info_read, 1));
43 zassert_equal(0, info_read.ai_family);
44 }
45
ZTEST(net_dns_cache_test,test_fill_cache)46 ZTEST(net_dns_cache_test, test_fill_cache)
47 {
48 struct dns_addrinfo info_write = {.ai_family = AF_INET};
49 struct dns_addrinfo info_read[TEST_DNS_CACHE_SIZE] = {0};
50 const char *query = "example.com";
51 enum dns_query_type query_type = DNS_QUERY_TYPE_A;
52
53 for (size_t i = 0; i < TEST_DNS_CACHE_SIZE; i++) {
54 zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write,
55 TEST_DNS_CACHE_DEFAULT_TTL),
56 "Cache entry adding should work.");
57 }
58 zassert_equal(TEST_DNS_CACHE_SIZE, dns_cache_find(&test_dns_cache, query, query_type,
59 info_read, TEST_DNS_CACHE_SIZE));
60 zassert_equal(AF_INET, info_read[TEST_DNS_CACHE_SIZE - 1].ai_family);
61 }
62
ZTEST(net_dns_cache_test,test_flush)63 ZTEST(net_dns_cache_test, test_flush)
64 {
65 struct dns_addrinfo info_write = {.ai_family = AF_INET};
66 struct dns_addrinfo info_read[TEST_DNS_CACHE_SIZE] = {0};
67 const char *query = "example.com";
68 enum dns_query_type query_type = DNS_QUERY_TYPE_A;
69
70 for (size_t i = 0; i < TEST_DNS_CACHE_SIZE; i++) {
71 zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write,
72 TEST_DNS_CACHE_DEFAULT_TTL),
73 "Cache entry adding should work.");
74 }
75 zassert_ok(dns_cache_flush(&test_dns_cache));
76 zassert_equal(0, dns_cache_find(&test_dns_cache, query, query_type, info_read,
77 TEST_DNS_CACHE_SIZE));
78 zassert_equal(0, info_read[TEST_DNS_CACHE_SIZE - 1].ai_family);
79 }
80
ZTEST(net_dns_cache_test,test_fill_cache_to_small)81 ZTEST(net_dns_cache_test, test_fill_cache_to_small)
82 {
83 struct dns_addrinfo info_write = {.ai_family = AF_INET};
84 struct dns_addrinfo info_read[TEST_DNS_CACHE_SIZE - 1] = {0};
85 const char *query = "example.com";
86 enum dns_query_type query_type = DNS_QUERY_TYPE_A;
87
88 for (size_t i = 0; i < TEST_DNS_CACHE_SIZE; i++) {
89 zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write,
90 TEST_DNS_CACHE_DEFAULT_TTL),
91 "Cache entry adding should work.");
92 }
93 zassert_equal(-ENOSR, dns_cache_find(&test_dns_cache, query, query_type, info_read,
94 TEST_DNS_CACHE_SIZE - 1));
95 zassert_equal(AF_INET, info_read[TEST_DNS_CACHE_SIZE - 2].ai_family);
96 }
97
ZTEST(net_dns_cache_test,test_closest_expiry_removed)98 ZTEST(net_dns_cache_test, test_closest_expiry_removed)
99 {
100 struct dns_addrinfo info_write = {.ai_family = AF_INET};
101 struct dns_addrinfo info_read = {0};
102 const char *closest_expiry = "example.com";
103 enum dns_query_type query_type = DNS_QUERY_TYPE_A;
104
105 zassert_ok(dns_cache_add(&test_dns_cache, closest_expiry, &info_write,
106 TEST_DNS_CACHE_DEFAULT_TTL),
107 "Cache entry adding should work.");
108 k_sleep(K_MSEC(1));
109 for (size_t i = 0; i < TEST_DNS_CACHE_SIZE; i++) {
110 zassert_ok(dns_cache_add(&test_dns_cache, "example2.com", &info_write,
111 TEST_DNS_CACHE_DEFAULT_TTL),
112 "Cache entry adding should work.");
113 }
114 zassert_equal(0,
115 dns_cache_find(&test_dns_cache, closest_expiry, query_type, &info_read, 1));
116 zassert_equal(0, info_read.ai_family);
117 }
118
ZTEST(net_dns_cache_test,test_expired_entries_removed)119 ZTEST(net_dns_cache_test, test_expired_entries_removed)
120 {
121 struct dns_addrinfo info_write = {.ai_family = AF_INET};
122 struct dns_addrinfo info_read[3] = {0};
123 const char *query = "example.com";
124 enum dns_query_type query_type = DNS_QUERY_TYPE_A;
125
126 zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL),
127 "Cache entry adding should work.");
128 zassert_ok(
129 dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL * 2),
130 "Cache entry adding should work.");
131 zassert_ok(
132 dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL * 3),
133 "Cache entry adding should work.");
134 zassert_equal(3, dns_cache_find(&test_dns_cache, query, query_type, info_read, 3));
135 zassert_equal(AF_INET, info_read[0].ai_family);
136 k_sleep(K_MSEC(TEST_DNS_CACHE_DEFAULT_TTL * 1000 + 1));
137 zassert_equal(2, dns_cache_find(&test_dns_cache, query, query_type, info_read, 3));
138 zassert_equal(AF_INET, info_read[0].ai_family);
139 k_sleep(K_MSEC(TEST_DNS_CACHE_DEFAULT_TTL * 1000 + 1));
140 zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type, info_read, 3));
141 zassert_equal(AF_INET, info_read[0].ai_family);
142 k_sleep(K_MSEC(1));
143 zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type, info_read, 3));
144 zassert_equal(AF_INET, info_read[0].ai_family);
145 }
146
ZTEST(net_dns_cache_test,test_different_type_not_returned)147 ZTEST(net_dns_cache_test, test_different_type_not_returned)
148 {
149 struct dns_addrinfo info_write = {.ai_family = AF_INET};
150 struct dns_addrinfo info_read = {0};
151 const char *query = "example.com";
152 enum dns_query_type query_type = DNS_QUERY_TYPE_AAAA;
153
154 zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL),
155 "Cache entry adding should work.");
156 zassert_equal(0, dns_cache_find(&test_dns_cache, query, query_type, &info_read, 1));
157 zassert_equal(0, info_read.ai_family);
158 }
159
ZTEST(net_dns_cache_test,test_only_expected_type_returned)160 ZTEST(net_dns_cache_test, test_only_expected_type_returned)
161 {
162 struct dns_addrinfo info_write_a = {.ai_family = AF_INET};
163 struct dns_addrinfo info_write_b = {.ai_family = AF_INET6};
164 struct dns_addrinfo info_read = {0};
165 const char *query = "example.com";
166 enum dns_query_type query_type_a = DNS_QUERY_TYPE_A;
167 enum dns_query_type query_type_b = DNS_QUERY_TYPE_AAAA;
168
169 zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write_a, TEST_DNS_CACHE_DEFAULT_TTL),
170 "Cache entry adding should work.");
171 zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write_b, TEST_DNS_CACHE_DEFAULT_TTL),
172 "Cache entry adding should work.");
173 zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type_a, &info_read, 1));
174 zassert_equal(AF_INET, info_read.ai_family);
175 zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type_b, &info_read, 1));
176 zassert_equal(AF_INET6, info_read.ai_family);
177 }
178
ZTEST(net_dns_cache_test,test_remove_single_entry)179 ZTEST(net_dns_cache_test, test_remove_single_entry)
180 {
181 struct dns_addrinfo info_write = {.ai_family = AF_INET};
182 struct dns_addrinfo info_read = {0};
183 const char *query = "example.com";
184 enum dns_query_type query_type = DNS_QUERY_TYPE_A;
185
186 zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL),
187 "Cache entry adding should work.");
188 zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type, &info_read, 1));
189 zassert_equal(AF_INET, info_read.ai_family);
190
191 zassert_ok(dns_cache_remove(&test_dns_cache, query), "Cache entry removal should work.");
192 zassert_equal(0, dns_cache_find(&test_dns_cache, query, query_type, &info_read, 1));
193 }
194
ZTEST(net_dns_cache_test,test_remove_multiple_entries_same_query)195 ZTEST(net_dns_cache_test, test_remove_multiple_entries_same_query)
196 {
197 struct dns_addrinfo info_write_a = {.ai_family = AF_INET};
198 struct dns_addrinfo info_write_b = {.ai_family = AF_INET6};
199 struct dns_addrinfo info_read[2] = {0};
200 const char *query = "example.com";
201 enum dns_query_type query_type_a = DNS_QUERY_TYPE_A;
202 enum dns_query_type query_type_b = DNS_QUERY_TYPE_AAAA;
203
204 zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write_a, TEST_DNS_CACHE_DEFAULT_TTL),
205 "Cache entry adding should work.");
206 zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write_b, TEST_DNS_CACHE_DEFAULT_TTL),
207 "Cache entry adding should work.");
208 zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type_a, &info_read[0], 1));
209 zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type_b, &info_read[0], 1));
210
211 zassert_ok(dns_cache_remove(&test_dns_cache, query), "Cache entry removal should work.");
212 zassert_equal(0, dns_cache_find(&test_dns_cache, query, query_type_a, &info_read[0], 1));
213 zassert_equal(0, dns_cache_find(&test_dns_cache, query, query_type_b, &info_read[0], 1));
214 }
215
ZTEST(net_dns_cache_test,test_remove_specific_query_only)216 ZTEST(net_dns_cache_test, test_remove_specific_query_only)
217 {
218 struct dns_addrinfo info_write = {.ai_family = AF_INET};
219 struct dns_addrinfo info_read = {0};
220 const char *query1 = "example.com";
221 const char *query2 = "test.com";
222 enum dns_query_type query_type = DNS_QUERY_TYPE_A;
223
224 zassert_ok(dns_cache_add(&test_dns_cache, query1, &info_write, TEST_DNS_CACHE_DEFAULT_TTL),
225 "Cache entry adding should work.");
226 zassert_ok(dns_cache_add(&test_dns_cache, query2, &info_write, TEST_DNS_CACHE_DEFAULT_TTL),
227 "Cache entry adding should work.");
228 zassert_equal(1, dns_cache_find(&test_dns_cache, query1, query_type, &info_read, 1));
229 zassert_equal(1, dns_cache_find(&test_dns_cache, query2, query_type, &info_read, 1));
230
231 zassert_ok(dns_cache_remove(&test_dns_cache, query1), "Cache entry removal should work.");
232 zassert_equal(0, dns_cache_find(&test_dns_cache, query1, query_type, &info_read, 1));
233 zassert_equal(1, dns_cache_find(&test_dns_cache, query2, query_type, &info_read, 1));
234 zassert_equal(AF_INET, info_read.ai_family);
235 }
236
ZTEST(net_dns_cache_test,test_remove_nonexistent_query)237 ZTEST(net_dns_cache_test, test_remove_nonexistent_query)
238 {
239 struct dns_addrinfo info_write = {.ai_family = AF_INET};
240 struct dns_addrinfo info_read = {0};
241 const char *query = "example.com";
242 const char *nonexistent_query = "nonexistent.com";
243 enum dns_query_type query_type = DNS_QUERY_TYPE_A;
244
245 zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL),
246 "Cache entry adding should work.");
247 zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type, &info_read, 1));
248
249 zassert_ok(dns_cache_remove(&test_dns_cache, nonexistent_query),
250 "Removing nonexistent query should not fail.");
251 zassert_equal(1, dns_cache_find(&test_dns_cache, query, query_type, &info_read, 1));
252 zassert_equal(AF_INET, info_read.ai_family);
253 }
254
ZTEST(net_dns_cache_test,test_remove_empty_cache)255 ZTEST(net_dns_cache_test, test_remove_empty_cache)
256 {
257 const char *query = "example.com";
258
259 zassert_ok(dns_cache_remove(&test_dns_cache, query),
260 "Removing from empty cache should not fail.");
261 }
262
ZTEST(net_dns_cache_test,test_remove_null_parameters)263 ZTEST(net_dns_cache_test, test_remove_null_parameters)
264 {
265 zassert_equal(-EINVAL, dns_cache_remove(NULL, "example.com"),
266 "NULL cache should return error.");
267 zassert_equal(-EINVAL, dns_cache_remove(&test_dns_cache, NULL),
268 "NULL query should return error.");
269 }
270