Imported Upstream version 0.9.1
[platform/upstream/iotivity.git] / resource / csdk / connectivity / lib / libcoap-4.1.1 / tests / test_sendqueue.c
1 /* libcoap unit tests
2  *
3  * Copyright (C) 2013 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 <stdio.h>
10 #include <coap.h>
11 #include "test_sendqueue.h"
12
13 static coap_queue_t *sendqueue;
14
15 /* timestamps for tests. The first element in this array denotes the
16  * base time in ticks, the following elements are timestamps relative
17  * to this basetime.
18  */
19 static coap_tick_t timestamp[] =
20 { 0, 100, 200, 30, 160 };
21
22 /* nodes for testing. node[0] is left empty */
23 coap_queue_t *node[5];
24
25 coap_tick_t add_timestamps(coap_queue_t *queue, size_t num)
26 {
27     coap_tick_t t = 0;
28     while (queue && num--)
29     {
30         t += queue->t;
31         queue = queue->next;
32     }
33
34     return t;
35 }
36
37 void t_sendqueue1(void)
38 {
39     int result = coap_insert_node(&sendqueue, node[1]);
40
41     CU_ASSERT(result > 0);
42     CU_ASSERT_PTR_NOT_NULL(sendqueue);
43     CU_ASSERT_PTR_EQUAL(sendqueue, node[1]);
44     CU_ASSERT(node[1]->t == timestamp[1]);
45 }
46
47 void t_sendqueue2(void)
48 {
49     int result;
50
51     result = coap_insert_node(&sendqueue, node[2]);
52
53     CU_ASSERT(result > 0);
54     CU_ASSERT_PTR_EQUAL(sendqueue, node[1]);
55     CU_ASSERT_PTR_EQUAL(sendqueue->next, node[2]);
56
57     CU_ASSERT(sendqueue->t == timestamp[1]);
58     CU_ASSERT(node[2]->t == timestamp[2] - timestamp[1]);
59 }
60
61 /* insert new node as first element in queue */
62 void t_sendqueue3(void)
63 {
64     int result;
65     result = coap_insert_node(&sendqueue, node[3]);
66
67     CU_ASSERT(result > 0);
68
69     CU_ASSERT_PTR_EQUAL(sendqueue, node[3]);
70     CU_ASSERT(node[3]->t == timestamp[3]);
71
72     CU_ASSERT_PTR_NOT_NULL(sendqueue->next);
73     CU_ASSERT_PTR_NOT_NULL(sendqueue->next->next);
74
75     CU_ASSERT(sendqueue->next->t == timestamp[1] - timestamp[3]);
76     CU_ASSERT(sendqueue->next->next->t == timestamp[2] - timestamp[1]);
77 }
78
79 /* insert new node as fourth element in queue */
80 void t_sendqueue4(void)
81 {
82     int result;
83
84     result = coap_insert_node(&sendqueue, node[4]);
85
86     CU_ASSERT(result > 0);
87
88     CU_ASSERT_PTR_EQUAL(sendqueue, node[3]);
89
90     CU_ASSERT_PTR_NOT_NULL(sendqueue->next);
91     CU_ASSERT_PTR_EQUAL(sendqueue->next, node[1]);
92
93     CU_ASSERT_PTR_NOT_NULL(sendqueue->next->next);
94     CU_ASSERT_PTR_EQUAL(sendqueue->next->next, node[4]);
95
96     CU_ASSERT_PTR_NOT_NULL(sendqueue->next->next->next);
97     CU_ASSERT_PTR_EQUAL(sendqueue->next->next->next, node[2]);
98
99     CU_ASSERT(sendqueue->next->t == timestamp[1] - timestamp[3]);
100     CU_ASSERT(add_timestamps(sendqueue, 1) == timestamp[3]);
101     CU_ASSERT(add_timestamps(sendqueue, 2) == timestamp[1]);
102     CU_ASSERT(add_timestamps(sendqueue, 3) == timestamp[4]);
103     CU_ASSERT(add_timestamps(sendqueue, 4) == timestamp[2]);
104 }
105
106 void t_sendqueue5(void)
107 {
108     const coap_tick_diff_t delta1 = 20, delta2 = 130;
109     unsigned int result;
110     coap_tick_t now;
111     struct coap_context_t ctx;
112
113     /* space for saving the current node timestamps */
114     static coap_tick_t times[sizeof(timestamp) / sizeof(coap_tick_t)];
115     coap_queue_t *p;
116     int i;
117
118     /* save timestamps of nodes in the sendqueue in their actual order */
119     memset(times, 0, sizeof(times));
120     for (p = sendqueue, i = 0; p; p = p->next, i++)
121     {
122         times[i] = p->t;
123     }
124
125     coap_ticks(&now);
126     ctx.sendqueue = sendqueue;
127     ctx.sendqueue_basetime = now;
128
129     now -= delta1;
130     result = coap_adjust_basetime(&ctx, now);
131
132     CU_ASSERT(result == 0);
133     CU_ASSERT_PTR_NOT_NULL(ctx.sendqueue);
134     CU_ASSERT(ctx.sendqueue_basetime == now);
135     CU_ASSERT(ctx.sendqueue->t == timestamp[3] + delta1);
136
137     now += delta2;
138     result = coap_adjust_basetime(&ctx, now);
139     CU_ASSERT(result == 2);
140     CU_ASSERT(ctx.sendqueue_basetime == now);
141     CU_ASSERT_PTR_NOT_NULL(ctx.sendqueue);
142     CU_ASSERT(ctx.sendqueue->t == 0);
143
144     CU_ASSERT_PTR_NOT_NULL(ctx.sendqueue->next);
145     CU_ASSERT(ctx.sendqueue->next->t == 0);
146
147     CU_ASSERT_PTR_NOT_NULL(ctx.sendqueue->next->next);
148     CU_ASSERT(ctx.sendqueue->next->next->t == delta2 - delta1 - timestamp[1]);
149
150     /* restore timestamps of nodes in the sendqueue */
151     for (p = sendqueue, i = 0; p; p = p->next, i++)
152     {
153         p->t = times[i];
154     }
155 }
156
157 void t_sendqueue6(void)
158 {
159     unsigned int result;
160     coap_tick_t now;
161     const coap_tick_diff_t delta = 20;
162     struct coap_context_t ctx;
163
164     /* space for saving the current node timestamps */
165     static coap_tick_t times[sizeof(timestamp) / sizeof(coap_tick_t)];
166     coap_queue_t *p;
167     int i;
168
169     /* save timestamps of nodes in the sendqueue in their actual order */
170     memset(times, 0, sizeof(times));
171     for (p = sendqueue, i = 0; p; p = p->next, i++)
172     {
173         times[i] = p->t;
174     }
175
176     coap_ticks(&now);
177     ctx.sendqueue = NULL;
178     ctx.sendqueue_basetime = now;
179
180     result = coap_adjust_basetime(&ctx, now + delta);
181
182     CU_ASSERT(result == 0);
183     CU_ASSERT(ctx.sendqueue_basetime == now + delta);
184
185     /* restore timestamps of nodes in the sendqueue */
186     for (p = sendqueue, i = 0; p; p = p->next, i++)
187     {
188         p->t = times[i];
189     }
190 }
191 ;
192
193 void t_sendqueue7(void)
194 {
195     int result;
196     coap_queue_t *tmp_node;
197
198     CU_ASSERT_PTR_NOT_NULL(sendqueue);
199     CU_ASSERT_PTR_EQUAL(sendqueue, node[3]);
200
201     CU_ASSERT_PTR_NOT_NULL(sendqueue->next);
202     CU_ASSERT_PTR_EQUAL(sendqueue->next, node[1]);
203
204     result = coap_remove_from_queue(&sendqueue, 3, &tmp_node);
205
206     CU_ASSERT(result == 1);
207     CU_ASSERT_PTR_NOT_NULL(tmp_node);
208     CU_ASSERT_PTR_EQUAL(tmp_node, node[3]);
209
210     CU_ASSERT_PTR_NOT_NULL(sendqueue);
211     CU_ASSERT_PTR_EQUAL(sendqueue, node[1]);
212
213     CU_ASSERT(sendqueue->t == timestamp[1]);
214 }
215 ;
216
217 void t_sendqueue8(void)
218 {
219     int result;
220     coap_queue_t *tmp_node;
221
222     result = coap_remove_from_queue(&sendqueue, 4, &tmp_node);
223
224     CU_ASSERT(result == 1);
225     CU_ASSERT_PTR_NOT_NULL(tmp_node);
226     CU_ASSERT_PTR_EQUAL(tmp_node, node[4]);
227
228     CU_ASSERT_PTR_NOT_NULL(sendqueue);
229     CU_ASSERT_PTR_EQUAL(sendqueue, node[1]);
230     CU_ASSERT(sendqueue->t == timestamp[1]);
231
232     CU_ASSERT_PTR_NOT_NULL(sendqueue->next);
233     CU_ASSERT_PTR_EQUAL(sendqueue->next, node[2]);
234     CU_ASSERT(sendqueue->next->t == timestamp[2] - timestamp[1]);
235
236     CU_ASSERT_PTR_NULL(sendqueue->next->next);
237 }
238 ;
239
240 void t_sendqueue9(void)
241 {
242     coap_queue_t *tmp_node;
243     struct coap_context_t ctx;
244
245     /* Initialize a fake context that points to our global sendqueue
246      * Note that all changes happen on ctx.sendqueue. */
247     ctx.sendqueue = sendqueue;
248     tmp_node = coap_peek_next(&ctx);
249     sendqueue = ctx.sendqueue; /* must update global sendqueue for correct result */
250
251     CU_ASSERT_PTR_NOT_NULL(tmp_node);
252     CU_ASSERT_PTR_EQUAL(tmp_node, node[1]);
253     CU_ASSERT_PTR_EQUAL(tmp_node, ctx.sendqueue);
254
255     tmp_node = coap_pop_next(&ctx);
256     sendqueue = ctx.sendqueue; /* must update global sendqueue for correct result */
257
258     CU_ASSERT_PTR_NOT_NULL(tmp_node);
259     CU_ASSERT_PTR_EQUAL(tmp_node, node[1]);
260
261     CU_ASSERT_PTR_NOT_NULL(sendqueue);
262     CU_ASSERT_PTR_EQUAL(sendqueue, node[2]);
263
264     CU_ASSERT(tmp_node->t == timestamp[1]);
265     CU_ASSERT(sendqueue->t == timestamp[2]);
266
267     CU_ASSERT_PTR_NULL(sendqueue->next);
268 }
269 ;
270
271 void t_sendqueue10(void)
272 {
273     coap_queue_t *tmp_node;
274     struct coap_context_t ctx;
275
276     /* Initialize a fake context that points to our global sendqueue
277      * Note that all changes happen on ctx.sendqueue. */
278     ctx.sendqueue = sendqueue;
279
280     tmp_node = coap_pop_next(&ctx);
281     sendqueue = ctx.sendqueue; /* must update global sendqueue for correct result */
282
283     CU_ASSERT_PTR_NOT_NULL(tmp_node);
284     CU_ASSERT_PTR_EQUAL(tmp_node, node[2]);
285
286     CU_ASSERT_PTR_NULL(sendqueue);
287
288     CU_ASSERT(tmp_node->t == timestamp[2]);
289 }
290 ;
291
292 /* This function creates a set of nodes for testing. These nodes
293  * will exist for all tests and are modified by coap_insert_node()
294  * and
295  */
296 int t_sendqueue_tests_create(void)
297 {
298     int n, error = 0;
299     sendqueue = NULL;
300     coap_ticks(&timestamp[0]);
301
302     memset(node, 0, sizeof(node));
303     for (n = 1; n < sizeof(node) / sizeof(coap_queue_t *); n++)
304     {
305         node[n] = coap_new_node();
306         if (!node[n])
307         {
308             error = 1;
309             break;
310         }
311
312         node[n]->id = n;
313         node[n]->t = timestamp[n];
314     }
315
316     if (error)
317     {
318         /* destroy all test nodes and set entry to zero */
319         for (n = 0; n < sizeof(node) / sizeof(coap_queue_t *); n++)
320         {
321             if (node[n])
322             {
323                 coap_delete_node(node[n]);
324                 node[n] = NULL;
325             }
326         }
327     }
328
329     return error;
330 }
331
332 int t_sendqueue_tests_remove(void)
333 {
334     int n;
335
336     /* destroy all test nodes */
337     for (n = 0; n < sizeof(node) / sizeof(coap_queue_t *); n++)
338     {
339         if (node[n])
340         {
341             coap_delete_node(node[n]);
342         }
343     }
344
345     return 0;
346 }
347
348 CU_pSuite t_init_sendqueue_tests(void)
349 {
350     CU_pSuite suite;
351
352     suite = CU_add_suite("sendqueue", t_sendqueue_tests_create, t_sendqueue_tests_remove);
353     if (!suite)
354     { /* signal error */
355         fprintf(stderr, "W: cannot add sendqueue test suite (%s)\n", CU_get_error_msg());
356
357         return NULL;
358     }
359
360 #define SENDQUEUE_TEST(s,t)                       \
361   if (!CU_ADD_TEST(s,t)) {                        \
362     fprintf(stderr, "W: cannot add sendqueue test (%s)\n",        \
363         CU_get_error_msg());                      \
364   }
365
366     SENDQUEUE_TEST(suite, t_sendqueue1);
367     SENDQUEUE_TEST(suite, t_sendqueue2);
368     SENDQUEUE_TEST(suite, t_sendqueue3);
369     SENDQUEUE_TEST(suite, t_sendqueue4);
370     SENDQUEUE_TEST(suite, t_sendqueue5);
371     SENDQUEUE_TEST(suite, t_sendqueue6);
372     SENDQUEUE_TEST(suite, t_sendqueue7);
373     SENDQUEUE_TEST(suite, t_sendqueue8);
374     SENDQUEUE_TEST(suite, t_sendqueue9);
375     SENDQUEUE_TEST(suite, t_sendqueue10);
376
377     return suite;
378 }
379