Implementation of connectivity abstraction feature-Ubutu v0.1
[platform/upstream/iotivity.git] / resource / csdk / connectivity / lib / libcoap-4.1.1 / tests / test_wellknown.c
1 /* libcoap unit tests
2  *
3  * Copyright (C) 2013--2014 Olaf Bergmann <bergmann@tzi.org>
4  *
5  * This file is part of the CoAP library libcoap. Please see
6  * README for terms of use. 
7  */
8
9 #include <assert.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <coap.h>
14 #include <netinet/in.h>
15 #include "test_wellknown.h"
16
17 #define TEST_PDU_SIZE 120
18 #define TEST_URI_LEN    4
19
20 coap_context_t *ctx; /* Holds the coap context for most tests */
21 coap_pdu_t *pdu; /* Holds the parsed PDU for most tests */
22
23 extern coap_pdu_t *wellknown_response(coap_context_t *, coap_pdu_t *);
24 extern int print_wellknown(coap_context_t *context, unsigned char *buf, size_t *buflen,
25         size_t offset, coap_opt_t *query_filter);
26
27 void t_wellknown1(void)
28 {
29     coap_print_status_t result;
30     coap_resource_t *r;
31     unsigned char buf[40];
32     size_t buflen, offset, ofs;
33
34     char teststr[] =
35     { /* </>;title="some attribute";ct=0 (31 chars) */
36     '<', '/', '>', ';', 't', 'i', 't', 'l', 'e', '=', '"', 's', 'o', 'm', 'e', ' ', 'a', 't', 't',
37             'r', 'i', 'b', 'u', 't', 'e', '"', ';', 'c', 't', '=', '0' };
38
39     r = coap_resource_init(NULL, 0, 0);
40
41     coap_add_attr(r, (unsigned char *) "ct", 2, (unsigned char *) "0", 1, 0);
42     coap_add_attr(r, (unsigned char *) "title", 5, (unsigned char *) "\"some attribute\"", 16, 0);
43
44     coap_add_resource(ctx, r);
45
46     for (offset = 0; offset < sizeof(teststr); offset++)
47     {
48         ofs = offset;
49         buflen = sizeof(buf);
50
51         result = coap_print_link(r, buf, &buflen, &ofs);
52
53         CU_ASSERT(result == sizeof(teststr) - offset);
54         CU_ASSERT(buflen == sizeof(teststr));
55         CU_ASSERT(memcmp(buf, teststr + offset, sizeof(teststr) - offset) == 0);
56     }
57
58     /* offset points behind teststr */
59     ofs = offset;
60     buflen = sizeof(buf);
61     result = coap_print_link(r, buf, &buflen, &ofs);
62
63     CU_ASSERT(result == 0);
64     CU_ASSERT(buflen == sizeof(teststr));
65
66     /* offset exceeds buffer */
67     buflen = sizeof(buf);
68     ofs = buflen;
69     result = coap_print_link(r, buf, &buflen, &ofs);
70
71     CU_ASSERT(result == 0);
72     CU_ASSERT(buflen == sizeof(teststr));
73 }
74
75 void t_wellknown2(void)
76 {
77     coap_print_status_t result;
78     coap_resource_t *r;
79     unsigned char buf[10]; /* smaller than teststr */
80     size_t buflen, offset, ofs;
81
82     char teststr[] =
83     { /* ,</abcd>;if="one";obs (21 chars) */
84     '<', '/', 'a', 'b', 'c', 'd', '>', ';', 'i', 'f', '=', '"', 'o', 'n', 'e', '"', ';', 'o', 'b',
85             's' };
86
87     r = coap_resource_init((unsigned char *) "abcd", 4, 0);
88     r->observable = 1;
89     coap_add_attr(r, (unsigned char *) "if", 2, (unsigned char *) "\"one\"", 5, 0);
90
91     coap_add_resource(ctx, r);
92
93     for (offset = 0; offset < sizeof(teststr) - sizeof(buf); offset++)
94     {
95         ofs = offset;
96         buflen = sizeof(buf);
97
98         result = coap_print_link(r, buf, &buflen, &ofs);
99
100         CU_ASSERT(result == (COAP_PRINT_STATUS_TRUNC | sizeof(buf)));
101         CU_ASSERT(buflen == sizeof(teststr));
102         CU_ASSERT(ofs == 0);
103         CU_ASSERT(memcmp(buf, teststr + offset, sizeof(buf)) == 0);
104     }
105
106     /* from here on, the resource description fits into buf */
107     for (; offset < sizeof(teststr); offset++)
108     {
109         ofs = offset;
110         buflen = sizeof(buf);
111         result = coap_print_link(r, buf, &buflen, &ofs);
112
113         CU_ASSERT(result == sizeof(teststr) - offset);
114         CU_ASSERT(buflen == sizeof(teststr));
115         CU_ASSERT(ofs == 0);
116         CU_ASSERT(memcmp(buf, teststr + offset, COAP_PRINT_OUTPUT_LENGTH(result)) == 0);
117     }
118
119     /* offset exceeds buffer */
120     buflen = sizeof(buf);
121     ofs = offset;
122     result = coap_print_link(r, buf, &buflen, &ofs);
123     CU_ASSERT(result == 0);
124     CU_ASSERT(buflen == sizeof(teststr));
125     CU_ASSERT(ofs == offset - sizeof(teststr));
126 }
127
128 void t_wellknown3(void)
129 {
130     coap_print_status_t result;
131     int j;
132     coap_resource_t *r;
133     static char uris[2 * COAP_MAX_PDU_SIZE];
134     unsigned char *uribuf = (unsigned char *) uris;
135     unsigned char buf[40];
136     size_t buflen = sizeof(buf);
137     size_t offset;
138     const unsigned short num_resources = (sizeof(uris) / TEST_URI_LEN) - 1;
139
140     /* ,</0000> (TEST_URI_LEN + 4 chars) */
141     for (j = 0; j < num_resources; j++)
142     {
143         int len = snprintf((char *) uribuf, TEST_URI_LEN + 1, "%0*d", TEST_URI_LEN, j);
144         r = coap_resource_init(uribuf, len, 0);
145         coap_add_resource(ctx, r);
146         uribuf += TEST_URI_LEN;
147     }
148
149     /* the following test assumes that the first two resources from
150      * t_wellknown1() and t_wellknown2() need more than buflen
151      * characters. Otherwise, CU_ASSERT(result > 0) will fail.
152      */
153     offset = num_resources * (TEST_URI_LEN + 4);
154     result = print_wellknown(ctx, buf, &buflen, offset, NULL);
155     CU_ASSERT((result & COAP_PRINT_STATUS_ERROR) == 0);
156     CU_ASSERT(COAP_PRINT_OUTPUT_LENGTH(result) > 0);
157 }
158
159 /* Create wellknown response for request without Block-option. */
160 void t_wellknown4(void)
161 {
162     coap_pdu_t *response;
163     coap_block_t block;
164
165     response = wellknown_response(ctx, pdu);
166
167     CU_ASSERT_PTR_NOT_NULL(response);
168
169     CU_ASSERT(coap_get_block(response, COAP_OPTION_BLOCK2, &block) != 0);
170
171     CU_ASSERT(block.num == 0);
172     CU_ASSERT(block.m == 1);
173     CU_ASSERT(
174             1 << (block.szx + 4)
175                     == (unsigned char *) response->hdr + response->length - response->data);
176
177     coap_delete_pdu(response);
178 }
179
180 /* Create wellknown response for request with Block2-option and an szx
181  * value smaller than COAP_MAX_BLOCK_SZX.
182  */
183 void t_wellknown5(void)
184 {
185     coap_pdu_t *response;
186     coap_block_t inblock =
187     { .num = 1, .m = 0, .szx = 1 };
188     coap_block_t block;
189     unsigned char buf[3];
190
191     if (!coap_add_option(pdu, COAP_OPTION_BLOCK2,
192             coap_encode_var_bytes(buf, ((inblock.num << 4) | (inblock.m << 3) | inblock.szx)), buf))
193     {
194         CU_FAIL("cannot add Block2 option");
195         return;
196     }
197
198     response = wellknown_response(ctx, pdu);
199
200     CU_ASSERT_PTR_NOT_NULL(response);
201
202     CU_ASSERT(coap_get_block(response, COAP_OPTION_BLOCK2, &block) != 0);
203
204     CU_ASSERT(block.num == inblock.num);
205     CU_ASSERT(block.m == 1);
206     CU_ASSERT(
207             1 << (block.szx + 4)
208                     == (unsigned char *) response->hdr + response->length - response->data);
209
210     coap_delete_pdu(response);
211 }
212
213 void t_wellknown6(void)
214 {
215     coap_pdu_t *response;
216     coap_block_t block =
217     { .num = 0, .szx = 6 };
218     unsigned char buf[TEST_PDU_SIZE];
219
220     do
221     {
222         coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
223
224         pdu->hdr->type = COAP_MESSAGE_NON;
225         pdu->hdr->code = COAP_REQUEST_GET;
226         pdu->hdr->id = htons(0x1234);
227
228         CU_ASSERT_PTR_NOT_NULL(pdu);
229
230         if (!pdu
231                 || !coap_add_option(pdu, COAP_OPTION_BLOCK2,
232                         coap_encode_var_bytes(buf, ((block.num << 4) | block.szx)), buf))
233         {
234             CU_FAIL("cannot create request");
235             return;
236         }
237
238         response = wellknown_response(ctx, pdu);
239
240         CU_ASSERT_PTR_NOT_NULL(response);
241
242         /* coap_show_pdu(response); */
243
244         CU_ASSERT(coap_get_block(response, COAP_OPTION_BLOCK2, &block) != 0);
245
246         block.num++;
247         coap_delete_pdu(response);
248     } while (block.m == 1);
249 }
250
251 int t_wkc_tests_create(void)
252 {
253     coap_address_t addr;
254
255     coap_address_init(&addr);
256
257     addr.size = sizeof(struct sockaddr_in6);
258     addr.addr.sin6.sin6_family = AF_INET6;
259     addr.addr.sin6.sin6_addr = in6addr_any;
260     addr.addr.sin6.sin6_port = htons(COAP_DEFAULT_PORT);
261
262     ctx = coap_new_context(&addr);
263
264     pdu = coap_pdu_init(0, 0, 0, TEST_PDU_SIZE);
265 #if 0
266     /* add resources to coap context */
267     if (ctx && pdu)
268     {
269         coap_resource_t *r;
270         static char _buf[2 * COAP_MAX_PDU_SIZE];
271         unsigned char *buf = (unsigned char *)_buf;
272         int i;
273
274         /* </>;title="some attribute";ct=0 (31 chars) */
275         r = coap_resource_init(NULL, 0, 0);
276
277         coap_add_attr(r, (unsigned char *)"ct", 2, (unsigned char *)"0", 1, 0);
278         coap_add_attr(r, (unsigned char *)"title", 5, (unsigned char *)"\"some attribute\"", 16, 0);
279         coap_add_resource(ctx, r);
280
281         /* ,</abcd>;if="one";obs (21 chars) */
282         r = coap_resource_init((unsigned char *)"abcd", 4, 0);
283         r->observable = 1;
284         coap_add_attr(r, (unsigned char *)"if", 2, (unsigned char *)"\"one\"", 5, 0);
285
286         coap_add_resource(ctx, r);
287
288         /* ,</0000> (TEST_URI_LEN + 4 chars) */
289         for (i = 0; i < sizeof(_buf) / (TEST_URI_LEN + 4); i++)
290         {
291             int len = snprintf((char *)buf, TEST_URI_LEN + 1,
292                     "%0*d", TEST_URI_LEN, i);
293             r = coap_resource_init(buf, len, 0);
294             coap_add_resource(ctx, r);
295             buf += TEST_URI_LEN + 1;
296         }
297
298     }
299 #endif  
300     return ctx == NULL || pdu == NULL;
301 }
302
303 int t_wkc_tests_remove(void)
304 {
305     coap_delete_pdu(pdu);
306     coap_free_context(ctx);
307     return 0;
308 }
309
310 CU_pSuite t_init_wellknown_tests(void)
311 {
312     CU_pSuite suite;
313
314     suite = CU_add_suite(".well-known/core", t_wkc_tests_create, t_wkc_tests_remove);
315     if (!suite)
316     { /* signal error */
317         fprintf(stderr, "W: cannot add .well-known/core test suite (%s)\n", CU_get_error_msg());
318
319         return NULL;
320     }
321
322 #define WKC_TEST(s,t)                                                 \
323   if (!CU_ADD_TEST(s,t)) {                                            \
324     fprintf(stderr, "W: cannot add .well-known/core test (%s)\n",             \
325             CU_get_error_msg());                                      \
326   }
327
328     WKC_TEST(suite, t_wellknown1);
329     WKC_TEST(suite, t_wellknown2);
330     WKC_TEST(suite, t_wellknown3);
331     WKC_TEST(suite, t_wellknown4);
332     WKC_TEST(suite, t_wellknown5);
333     WKC_TEST(suite, t_wellknown6);
334
335     return suite;
336 }
337