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 
28 	zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL),
29 		   "Cache entry adding should work.");
30 	zassert_equal(1, dns_cache_find(&test_dns_cache, query, &info_read, 1));
31 	zassert_equal(AF_INET, info_read.ai_family);
32 }
33 
ZTEST(net_dns_cache_test,test_not_cached)34 ZTEST(net_dns_cache_test, test_not_cached)
35 {
36 	struct dns_addrinfo info_read = {0};
37 	const char *query = "example.com";
38 
39 	zassert_equal(0, dns_cache_find(&test_dns_cache, query, &info_read, 1));
40 	zassert_equal(0, info_read.ai_family);
41 }
42 
ZTEST(net_dns_cache_test,test_fill_cache)43 ZTEST(net_dns_cache_test, test_fill_cache)
44 {
45 	struct dns_addrinfo info_write = {.ai_family = AF_INET};
46 	struct dns_addrinfo info_read[TEST_DNS_CACHE_SIZE] = {0};
47 	const char *query = "example.com";
48 
49 	for (size_t i = 0; i < TEST_DNS_CACHE_SIZE; i++) {
50 		zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write,
51 					 TEST_DNS_CACHE_DEFAULT_TTL),
52 			   "Cache entry adding should work.");
53 	}
54 	zassert_equal(TEST_DNS_CACHE_SIZE,
55 		      dns_cache_find(&test_dns_cache, query, info_read, TEST_DNS_CACHE_SIZE));
56 	zassert_equal(AF_INET, info_read[TEST_DNS_CACHE_SIZE - 1].ai_family);
57 }
58 
ZTEST(net_dns_cache_test,test_flush)59 ZTEST(net_dns_cache_test, test_flush)
60 {
61 	struct dns_addrinfo info_write = {.ai_family = AF_INET};
62 	struct dns_addrinfo info_read[TEST_DNS_CACHE_SIZE] = {0};
63 	const char *query = "example.com";
64 
65 	for (size_t i = 0; i < TEST_DNS_CACHE_SIZE; i++) {
66 		zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write,
67 					 TEST_DNS_CACHE_DEFAULT_TTL),
68 			   "Cache entry adding should work.");
69 	}
70 	zassert_ok(dns_cache_flush(&test_dns_cache));
71 	zassert_equal(0, dns_cache_find(&test_dns_cache, query, info_read, TEST_DNS_CACHE_SIZE));
72 	zassert_equal(0, info_read[TEST_DNS_CACHE_SIZE - 1].ai_family);
73 }
74 
ZTEST(net_dns_cache_test,test_fill_cache_to_small)75 ZTEST(net_dns_cache_test, test_fill_cache_to_small)
76 {
77 	struct dns_addrinfo info_write = {.ai_family = AF_INET};
78 	struct dns_addrinfo info_read[TEST_DNS_CACHE_SIZE - 1] = {0};
79 	const char *query = "example.com";
80 
81 	for (size_t i = 0; i < TEST_DNS_CACHE_SIZE; i++) {
82 		zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write,
83 					 TEST_DNS_CACHE_DEFAULT_TTL),
84 			   "Cache entry adding should work.");
85 	}
86 	zassert_equal(-ENOSR,
87 		      dns_cache_find(&test_dns_cache, query, info_read, TEST_DNS_CACHE_SIZE - 1));
88 	zassert_equal(AF_INET, info_read[TEST_DNS_CACHE_SIZE - 2].ai_family);
89 }
90 
ZTEST(net_dns_cache_test,test_closest_expiry_removed)91 ZTEST(net_dns_cache_test, test_closest_expiry_removed)
92 {
93 	struct dns_addrinfo info_write = {.ai_family = AF_INET};
94 	struct dns_addrinfo info_read = {0};
95 	const char *closest_expiry = "example.com";
96 
97 	zassert_ok(dns_cache_add(&test_dns_cache, closest_expiry, &info_write,
98 				 TEST_DNS_CACHE_DEFAULT_TTL),
99 		   "Cache entry adding should work.");
100 	k_sleep(K_MSEC(1));
101 	for (size_t i = 0; i < TEST_DNS_CACHE_SIZE; i++) {
102 		zassert_ok(dns_cache_add(&test_dns_cache, "example2.com", &info_write,
103 					 TEST_DNS_CACHE_DEFAULT_TTL),
104 			   "Cache entry adding should work.");
105 	}
106 	zassert_equal(0, dns_cache_find(&test_dns_cache, closest_expiry, &info_read, 1));
107 	zassert_equal(0, info_read.ai_family);
108 }
109 
ZTEST(net_dns_cache_test,test_expired_entries_removed)110 ZTEST(net_dns_cache_test, test_expired_entries_removed)
111 {
112 	struct dns_addrinfo info_write = {.ai_family = AF_INET};
113 	struct dns_addrinfo info_read[3] = {0};
114 	const char *query = "example.com";
115 
116 	zassert_ok(dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL),
117 		   "Cache entry adding should work.");
118 	zassert_ok(
119 		dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL * 2),
120 		"Cache entry adding should work.");
121 	zassert_ok(
122 		dns_cache_add(&test_dns_cache, query, &info_write, TEST_DNS_CACHE_DEFAULT_TTL * 3),
123 		"Cache entry adding should work.");
124 	zassert_equal(3, dns_cache_find(&test_dns_cache, query, info_read, 3));
125 	zassert_equal(AF_INET, info_read[0].ai_family);
126 	k_sleep(K_MSEC(TEST_DNS_CACHE_DEFAULT_TTL * 1000 + 1));
127 	zassert_equal(2, dns_cache_find(&test_dns_cache, query, info_read, 3));
128 	zassert_equal(AF_INET, info_read[0].ai_family);
129 	k_sleep(K_MSEC(TEST_DNS_CACHE_DEFAULT_TTL * 1000 + 1));
130 	zassert_equal(1, dns_cache_find(&test_dns_cache, query, info_read, 3));
131 	zassert_equal(AF_INET, info_read[0].ai_family);
132 	k_sleep(K_MSEC(1));
133 	zassert_equal(1, dns_cache_find(&test_dns_cache, query, info_read, 3));
134 	zassert_equal(AF_INET, info_read[0].ai_family);
135 }
136