1 /*
2 * Copyright (c) 2023 Basalte bv
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8
9 #include <zephyr/ztest.h>
10 #include <zephyr/net/coap_service.h>
11
coap_method1(struct coap_resource * resource,struct coap_packet * request,struct sockaddr * addr,socklen_t addr_len)12 static int coap_method1(struct coap_resource *resource, struct coap_packet *request,
13 struct sockaddr *addr, socklen_t addr_len)
14 {
15 ARG_UNUSED(resource);
16 ARG_UNUSED(request);
17 ARG_UNUSED(addr);
18 ARG_UNUSED(addr_len);
19
20 return -ENOSYS;
21 }
22
coap_method2(struct coap_resource * resource,struct coap_packet * request,struct sockaddr * addr,socklen_t addr_len)23 static int coap_method2(struct coap_resource *resource, struct coap_packet *request,
24 struct sockaddr *addr, socklen_t addr_len)
25 {
26 ARG_UNUSED(resource);
27 ARG_UNUSED(request);
28 ARG_UNUSED(addr);
29 ARG_UNUSED(addr_len);
30
31 return -ENOSYS;
32 }
33
34 static const uint16_t service_A_port = 4242;
35 COAP_SERVICE_DEFINE(service_A, "a.service.com", &service_A_port, COAP_SERVICE_AUTOSTART);
36
37 static const char * const resource_0_path[] = { "res0", NULL };
38 COAP_RESOURCE_DEFINE(resource_0, service_A, {
39 .path = resource_0_path,
40 .get = coap_method1,
41 .put = coap_method2,
42 });
43
44 static const char * const resource_1_path[] = { "res1", NULL };
45 COAP_RESOURCE_DEFINE(resource_1, service_A, {
46 .path = resource_1_path,
47 .post = coap_method1,
48 });
49
50 static uint16_t service_B_port;
51 COAP_SERVICE_DEFINE(service_B, "b.service.com", &service_B_port, 0);
52
53 static const char * const resource_2_path[] = { "res2", "sub", NULL };
54 COAP_RESOURCE_DEFINE(resource_2, service_B, {
55 .path = resource_2_path,
56 .get = coap_method2,
57 .put = coap_method1,
58 });
59
60 static const char * const resource_3_path[] = { "res3", "+", NULL };
61 COAP_RESOURCE_DEFINE(resource_3, service_B, {
62 .path = resource_3_path,
63 .post = coap_method2,
64 });
65
66 static const uint16_t service_C_port = 5959;
67 COAP_SERVICE_DEFINE(service_C, "192.168.1.1", &service_C_port, 0);
68
69 static const char * const resource_4_path[] = { "res4", "*", NULL };
70 COAP_RESOURCE_DEFINE(resource_4, service_C, {
71 .path = resource_4_path,
72 .get = coap_method1,
73 });
74
ZTEST(coap_service,test_COAP_SERVICE_DEFINE)75 ZTEST(coap_service, test_COAP_SERVICE_DEFINE)
76 {
77 zassert_ok(strcmp(service_A.host, "a.service.com"));
78 zassert_equal(service_A.port, &service_A_port);
79 zassert_equal(*service_A.port, 4242);
80
81 zassert_ok(strcmp(service_B.host, "b.service.com"));
82 zassert_equal(service_B.port, &service_B_port);
83 zassert_equal(*service_B.port, 0);
84
85 zassert_ok(strcmp(service_C.host, "192.168.1.1"));
86 zassert_equal(service_C.port, &service_C_port);
87 zassert_equal(*service_C.port, 5959);
88 }
89
ZTEST(coap_service,test_COAP_SERVICE_COUNT)90 ZTEST(coap_service, test_COAP_SERVICE_COUNT)
91 {
92 size_t n_svc;
93
94 n_svc = 4273;
95 COAP_SERVICE_COUNT(&n_svc);
96 zassert_equal(n_svc, 3);
97 }
98
ZTEST(coap_service,test_COAP_SERVICE_RESOURCE_COUNT)99 ZTEST(coap_service, test_COAP_SERVICE_RESOURCE_COUNT)
100 {
101 zassert_equal(COAP_SERVICE_RESOURCE_COUNT(&service_A), 2);
102 zassert_equal(COAP_SERVICE_RESOURCE_COUNT(&service_B), 2);
103 zassert_equal(COAP_SERVICE_RESOURCE_COUNT(&service_C), 1);
104 }
105
ZTEST(coap_service,test_COAP_SERVICE_HAS_RESOURCE)106 ZTEST(coap_service, test_COAP_SERVICE_HAS_RESOURCE)
107 {
108 zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_A, &resource_0));
109 zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_A, &resource_1));
110 zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_A, &resource_2));
111 zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_A, &resource_3));
112
113 zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_B, &resource_0));
114 zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_B, &resource_1));
115 zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_B, &resource_2));
116 zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_B, &resource_3));
117
118 zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_C, &resource_0));
119 zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_C, &resource_4));
120 }
121
ZTEST(coap_service,test_COAP_SERVICE_FOREACH)122 ZTEST(coap_service, test_COAP_SERVICE_FOREACH)
123 {
124 size_t n_svc = 0;
125 size_t have_service_A = 0;
126 size_t have_service_B = 0;
127 size_t have_service_C = 0;
128
129 COAP_SERVICE_FOREACH(svc) {
130 if (svc == &service_A) {
131 have_service_A = 1;
132 zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, COAP_SERVICE_AUTOSTART);
133 } else if (svc == &service_B) {
134 have_service_B = 1;
135 zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, 0);
136 } else if (svc == &service_C) {
137 have_service_C = 1;
138 zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, 0);
139 } else {
140 zassert_unreachable("svc (%p) not equal to &service_A (%p), &service_B "
141 "(%p), or &service_C (%p)",
142 svc, &service_A, &service_B, &service_C);
143 }
144
145 n_svc++;
146 }
147
148 zassert_equal(n_svc, 3);
149 zassert_equal(have_service_A + have_service_B + have_service_C, n_svc);
150 }
151
ZTEST(coap_service,test_COAP_RESOURCE_FOREACH)152 ZTEST(coap_service, test_COAP_RESOURCE_FOREACH)
153 {
154 size_t first_res, second_res, n_res;
155
156 n_res = 0;
157 first_res = 0;
158 second_res = 0;
159 COAP_RESOURCE_FOREACH(service_A, res) {
160 if (res == &resource_0) {
161 first_res = 1;
162 } else if (res == &resource_1) {
163 second_res = 1;
164 } else {
165 zassert_unreachable(
166 "res (%p) not equal to &resource_0 (%p) or &resource_1 (%p)", res,
167 &resource_0, &resource_1);
168 }
169
170 n_res++;
171 }
172
173 zassert_equal(n_res, 2);
174 zassert_equal(first_res + second_res, n_res);
175
176 n_res = 0;
177 first_res = 0;
178 second_res = 0;
179 COAP_RESOURCE_FOREACH(service_B, res) {
180 if (res == &resource_2) {
181 first_res = 1;
182 } else if (res == &resource_3) {
183 second_res = 1;
184 } else {
185 zassert_unreachable(
186 "res (%p) not equal to &resource_2 (%p) or &resource_3 (%p)", res,
187 &resource_2, &resource_3);
188 }
189
190 n_res++;
191 }
192
193 zassert_equal(n_res, 2);
194 zassert_equal(first_res + second_res, n_res);
195
196 n_res = 0;
197 first_res = 0;
198 second_res = 0;
199 COAP_RESOURCE_FOREACH(service_C, res) {
200 if (res == &resource_4) {
201 first_res = 1;
202 } else {
203 zassert_unreachable(
204 "res (%p) not equal to &resource_4 (%p)", res, &resource_4);
205 }
206 n_res++;
207 }
208
209 zassert_equal(n_res, 1);
210 zassert_equal(first_res + second_res, n_res);
211 }
212
ZTEST(coap_service,test_COAP_SERVICE_FOREACH_RESOURCE)213 ZTEST(coap_service, test_COAP_SERVICE_FOREACH_RESOURCE)
214 {
215 size_t first_res, second_res, n_res;
216
217 n_res = 0;
218 first_res = 0;
219 second_res = 0;
220 COAP_SERVICE_FOREACH_RESOURCE(&service_A, res) {
221 if (res == &resource_0) {
222 first_res = 1;
223 } else if (res == &resource_1) {
224 second_res = 1;
225 } else {
226 zassert_unreachable(
227 "res (%p) not equal to &resource_0 (%p) or &resource_1 (%p)", res,
228 &resource_0, &resource_1);
229 }
230
231 n_res++;
232 }
233
234 zassert_equal(n_res, 2);
235 zassert_equal(first_res + second_res, n_res);
236
237 n_res = 0;
238 first_res = 0;
239 second_res = 0;
240 COAP_SERVICE_FOREACH_RESOURCE(&service_B, res) {
241 if (res == &resource_2) {
242 first_res = 1;
243 } else if (res == &resource_3) {
244 second_res = 1;
245 } else {
246 zassert_unreachable(
247 "res (%p) not equal to &resource_2 (%p) or &resource_3 (%p)", res,
248 &resource_2, &resource_3);
249 }
250
251 n_res++;
252 }
253
254 zassert_equal(n_res, 2);
255 zassert_equal(first_res + second_res, n_res);
256
257 n_res = 0;
258 first_res = 0;
259 second_res = 0;
260 COAP_SERVICE_FOREACH_RESOURCE(&service_C, res) {
261 if (res == &resource_4) {
262 first_res = 1;
263 } else {
264 zassert_unreachable(
265 "res (%p) not equal to &resource_4 (%p)", res, &resource_4);
266 }
267 n_res++;
268 }
269
270 zassert_equal(n_res, 1);
271 zassert_equal(first_res + second_res, n_res);
272 }
273
ZTEST(coap_service,test_COAP_RESOURCE_DEFINE)274 ZTEST(coap_service, test_COAP_RESOURCE_DEFINE)
275 {
276 COAP_SERVICE_FOREACH_RESOURCE(&service_A, res) {
277 if (res == &resource_0) {
278 zassert_ok(strcmp(res->path[0], "res0"));
279 zassert_equal(res->get, coap_method1);
280 zassert_equal(res->put, coap_method2);
281 } else if (res == &resource_1) {
282 zassert_ok(strcmp(res->path[0], "res1"));
283 zassert_equal(res->post, coap_method1);
284 } else {
285 zassert_unreachable(
286 "res (%p) not equal to &resource_0 (%p) or &resource_1 (%p)", res,
287 &resource_0, &resource_1);
288 }
289 }
290
291 COAP_SERVICE_FOREACH_RESOURCE(&service_B, res) {
292 if (res == &resource_2) {
293 zassert_ok(strcmp(res->path[0], "res2"));
294 zassert_ok(strcmp(res->path[1], "sub"));
295 zassert_equal(res->get, coap_method2);
296 zassert_equal(res->put, coap_method1);
297 } else if (res == &resource_3) {
298 zassert_ok(strcmp(res->path[0], "res3"));
299 zassert_ok(strcmp(res->path[1], "+"));
300 zassert_equal(res->post, coap_method2);
301 } else {
302 zassert_unreachable(
303 "res (%p) not equal to &resource_2 (%p) or &resource_3 (%p)", res,
304 &resource_2, &resource_3);
305 }
306 }
307
308 COAP_SERVICE_FOREACH_RESOURCE(&service_C, res) {
309 if (res == &resource_4) {
310 zassert_ok(strcmp(res->path[0], "res4"));
311 zassert_ok(strcmp(res->path[1], "*"));
312 zassert_equal(res->get, coap_method1);
313 zassert_equal(res->put, NULL);
314 } else {
315 zassert_unreachable(
316 "res (%p) not equal to &resource_4 (%p)", res, &resource_4);
317 }
318 }
319 }
320
321 ZTEST_SUITE(coap_service, NULL, NULL, NULL, NULL, NULL);
322