]> git.ozlabs.org Git - ccan/blob - ccan/lpq/test/api.c
tcon: add testcase for const members in tcon_container_of()
[ccan] / ccan / lpq / test / api.c
1 #include <ccan/lpq/lpq.h>
2 #include <ccan/array_size/array_size.h>
3 #include <ccan/permutation/permutation.h>
4 #include <ccan/tap/tap.h>
5
6 struct waiter {
7         int intval;
8         float floatval;
9         struct lpq_link link;
10 };
11
12 static void test_array(struct waiter *waiters, int n,
13                        total_order_cb(order_cb, struct waiter, ptrint_t *),
14                        ptrint_t *order_ctx, bool invert)
15 {
16         LPQ(struct waiter, link) pq;
17         struct permutation *pi = permutation_new(n);
18         int i;
19
20         lpq_init(&pq, order_cb, order_ctx);
21
22         ok1(lpq_empty(&pq));
23         ok1(lpq_front(&pq) == NULL);
24         ok1(lpq_dequeue(&pq) == NULL);
25         ok1(lpq_empty(&pq));
26
27         do {
28                 for (i = 0; i < n; i++) {
29                         lpq_enqueue(&pq, &waiters[pi->v[i]]);
30                         ok1(!lpq_empty(&pq));
31                         ok1(lpq_front(&pq) != NULL);
32                 }
33
34                 for (i = 0; i < n; i++) {
35                         int expected = invert ? i : (n - 1 - i);
36
37                         ok1(!lpq_empty(&pq));
38                         ok1(lpq_front(&pq) == &waiters[expected]);
39                         ok1(lpq_dequeue(&pq) == &waiters[expected]);
40                 }
41
42                 ok1(lpq_empty(&pq));
43         } while (permutation_change(pi));
44         free(pi);
45 }
46
47 #define ARRAY_NTESTS(arr) \
48         ((1 + 5 * ARRAY_SIZE(arr)) * permutation_count(ARRAY_SIZE(arr)) + 4)
49
50 static void test_reorder(void)
51 {
52         struct waiter waiters[] = {
53                 { .intval = -1, },
54                 { .intval = 0, },
55                 { .intval = 1, },
56                 { .intval = 12, },
57         };
58         int n = ARRAY_SIZE(waiters);
59         total_order_by_field(order, int, struct waiter, intval);
60         LPQ(struct waiter, link) pq;
61         int i;
62
63         lpq_init(&pq, order.cb, order.ctx);
64
65         for (i = 0; i < n; i++)
66                 lpq_enqueue(&pq, &waiters[i]);
67
68         for (i = 0; i < n; i++) {
69                 waiters[i].intval = -waiters[i].intval;
70                 lpq_reorder(&pq, &waiters[i]);
71         }
72
73         for (i = 0; i < n; i++) {
74                 ok1(lpq_dequeue(&pq) == &waiters[i]);
75         }
76
77         ok1(lpq_empty(&pq));
78 }
79
80 int main(void)
81 {
82         struct waiter w1[] = {
83                 { .intval = -1, },
84                 { .intval = 0, },
85                 { .intval = 1, },
86                 { .intval = 12, },
87         };
88         total_order_by_field(order1, int, struct waiter, intval);
89         total_order_by_field(order1r, int_reverse, struct waiter, intval);
90         struct waiter w2[] = {
91                 { .floatval = 0.01, },
92                 { .floatval = 0.1, },
93                 { .floatval = 0.2 },
94                 { .floatval = 1.0E+18, },
95         };
96         total_order_by_field(order2, float, struct waiter, floatval);
97         total_order_by_field(order2r, float_reverse, struct waiter, floatval);
98
99         /* This is how many tests you plan to run */
100         plan_tests(2 * (ARRAY_NTESTS(w1) + ARRAY_NTESTS(w2)) + 5);
101
102         test_array(w1, ARRAY_SIZE(w1), order1.cb, order1.ctx, false);
103         test_array(w1, ARRAY_SIZE(w1), order1r.cb, order1r.ctx, true);
104
105         test_array(w2, ARRAY_SIZE(w2), order2.cb, order2.ctx, false);
106         test_array(w2, ARRAY_SIZE(w2), order2r.cb, order2r.ctx, true);
107
108         test_reorder();
109
110         /* This exits depending on whether all tests passed */
111         return exit_status();
112 }