b9599dbfee71f87d89acdc9b547ab48b4d32d530
[sliver-openvswitch.git] / tests / test-list.c
1 /* A non-exhaustive test for some of the functions and macros declared in
2  * list.h. */
3
4 #include "list.h"
5 #include <string.h>
6
7 #undef NDEBUG
8 #include <assert.h>
9
10 /* Sample list element. */
11 struct element {
12     int value;
13     struct list node;
14 };
15
16 /* Puts the 'n' values in 'values' into 'elements', and then puts those
17  * elements in order into 'list'. */
18 static void
19 make_list(struct list *list, struct element elements[],
20           int values[], size_t n) 
21 {
22     size_t i;
23     
24     list_init(list);
25     for (i = 0; i < n; i++) {
26         elements[i].value = i;
27         list_push_back(list, &elements[i].node);
28         values[i] = i;
29     }
30 }
31
32 /* Verifies that 'list' contains exactly the 'n' values in 'values', in the
33  * specified order. */
34 static void
35 check_list(struct list *list, const int values[], size_t n) 
36 {
37     struct element *e;
38     size_t i;
39     
40     i = 0;
41     LIST_FOR_EACH (e, struct element, node, list) {
42         assert(i < n);
43         assert(e->value == values[i]);
44         i++;
45     }
46     assert(&e->node == list);
47     assert(i == n);
48
49     i = 0;
50     LIST_FOR_EACH_REVERSE (e, struct element, node, list) {
51         assert(i < n);
52         assert(e->value == values[n - i - 1]);
53         i++;
54     }
55     assert(&e->node == list);
56     assert(i == n);
57
58     assert(list_is_empty(list) == !n);
59     assert(list_size(list) == n);
60 }
61
62 #if 0
63 /* Prints the values in 'list', plus 'name' as a title. */
64 static void
65 print_list(const char *name, struct list *list) 
66 {
67     struct element *e;
68     
69     printf("%s:", name);
70     LIST_FOR_EACH (e, struct element, node, list) {
71         printf(" %d", e->value);
72     }
73     printf("\n");
74 }
75 #endif
76
77 /* Tests basic list construction. */
78 static void
79 test_list_construction(void) 
80 {
81     enum { MAX_ELEMS = 100 };
82     size_t n;
83
84     for (n = 0; n <= MAX_ELEMS; n++) {
85         struct element elements[MAX_ELEMS];
86         int values[MAX_ELEMS];
87         struct list list;
88         
89         make_list(&list, elements, values, n);
90         check_list(&list, values, n);
91     }
92 }
93
94 /* Tests that LIST_FOR_EACH_SAFE properly allows for deletion of the current
95  * element of a list.  */
96 static void
97 test_list_for_each_safe(void) 
98 {
99     enum { MAX_ELEMS = 10 };
100     size_t n;
101     unsigned long int pattern;
102
103     for (n = 0; n <= MAX_ELEMS; n++) {
104         for (pattern = 0; pattern < 1ul << n; pattern++) {
105             struct element elements[MAX_ELEMS];
106             int values[MAX_ELEMS];
107             struct list list;
108             struct element *e, *next;
109             size_t values_idx, n_remaining;
110             int i;
111         
112             make_list(&list, elements, values, n);
113
114             i = 0;
115             values_idx = 0;
116             n_remaining = n;
117             LIST_FOR_EACH_SAFE (e, next, struct element, node, &list) {
118                 assert(i < n);
119                 if (pattern & (1ul << i)) {
120                     list_remove(&e->node);
121                     n_remaining--;
122                     memmove(&values[values_idx], &values[values_idx + 1],
123                             sizeof *values * (n_remaining - values_idx));
124                 } else {
125                     values_idx++;
126                 }
127                 check_list(&list, values, n_remaining);
128                 i++;
129             }
130             assert(i == n);
131             assert(&e->node == &list);
132
133             for (i = 0; i < n; i++) {
134                 if (pattern & (1ul << i)) {
135                     n_remaining++;
136                 }
137             }
138             assert(n == n_remaining);
139         }
140     }
141 }
142
143 static void
144 run_test(void (*function)(void)) 
145 {
146     function();
147     printf(".");
148 }
149
150 int
151 main(void) 
152 {
153     run_test(test_list_construction);
154     run_test(test_list_for_each_safe);
155     printf("\n");
156     return 0;
157 }
158