Switch many macros from using CONTAINER_OF to using OBJECT_CONTAINING.
[openvswitch] / tests / test-list.c
1 /*
2  * Copyright (c) 2008, 2009, 2010 Nicira Networks.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /* A non-exhaustive test for some of the functions and macros declared in
18  * list.h. */
19
20 #include <config.h>
21 #include "list.h"
22 #include <string.h>
23
24 #undef NDEBUG
25 #include <assert.h>
26
27 /* Sample list element. */
28 struct element {
29     int value;
30     struct list node;
31 };
32
33 /* Puts the 'n' values in 'values' into 'elements', and then puts those
34  * elements in order into 'list'. */
35 static void
36 make_list(struct list *list, struct element elements[],
37           int values[], size_t n)
38 {
39     size_t i;
40
41     list_init(list);
42     for (i = 0; i < n; i++) {
43         elements[i].value = i;
44         list_push_back(list, &elements[i].node);
45         values[i] = i;
46     }
47 }
48
49 /* Verifies that 'list' contains exactly the 'n' values in 'values', in the
50  * specified order. */
51 static void
52 check_list(struct list *list, const int values[], size_t n)
53 {
54     struct element *e;
55     size_t i;
56
57     i = 0;
58     LIST_FOR_EACH (e, node, list) {
59         assert(i < n);
60         assert(e->value == values[i]);
61         i++;
62     }
63     assert(&e->node == list);
64     assert(i == n);
65
66     i = 0;
67     LIST_FOR_EACH_REVERSE (e, node, list) {
68         assert(i < n);
69         assert(e->value == values[n - i - 1]);
70         i++;
71     }
72     assert(&e->node == list);
73     assert(i == n);
74
75     assert(list_is_empty(list) == !n);
76     assert(list_size(list) == n);
77 }
78
79 #if 0
80 /* Prints the values in 'list', plus 'name' as a title. */
81 static void
82 print_list(const char *name, struct list *list)
83 {
84     struct element *e;
85
86     printf("%s:", name);
87     LIST_FOR_EACH (e, node, list) {
88         printf(" %d", e->value);
89     }
90     printf("\n");
91 }
92 #endif
93
94 /* Tests basic list construction. */
95 static void
96 test_list_construction(void)
97 {
98     enum { MAX_ELEMS = 100 };
99     size_t n;
100
101     for (n = 0; n <= MAX_ELEMS; n++) {
102         struct element elements[MAX_ELEMS];
103         int values[MAX_ELEMS];
104         struct list list;
105
106         make_list(&list, elements, values, n);
107         check_list(&list, values, n);
108     }
109 }
110
111 /* Tests that LIST_FOR_EACH_SAFE properly allows for deletion of the current
112  * element of a list.  */
113 static void
114 test_list_for_each_safe(void)
115 {
116     enum { MAX_ELEMS = 10 };
117     size_t n;
118     unsigned long int pattern;
119
120     for (n = 0; n <= MAX_ELEMS; n++) {
121         for (pattern = 0; pattern < 1ul << n; pattern++) {
122             struct element elements[MAX_ELEMS];
123             int values[MAX_ELEMS];
124             struct list list;
125             struct element *e, *next;
126             size_t values_idx, n_remaining;
127             int i;
128
129             make_list(&list, elements, values, n);
130
131             i = 0;
132             values_idx = 0;
133             n_remaining = n;
134             LIST_FOR_EACH_SAFE (e, next, node, &list) {
135                 assert(i < n);
136                 if (pattern & (1ul << i)) {
137                     list_remove(&e->node);
138                     n_remaining--;
139                     memmove(&values[values_idx], &values[values_idx + 1],
140                             sizeof *values * (n_remaining - values_idx));
141                 } else {
142                     values_idx++;
143                 }
144                 check_list(&list, values, n_remaining);
145                 i++;
146             }
147             assert(i == n);
148             assert(&e->node == &list);
149
150             for (i = 0; i < n; i++) {
151                 if (pattern & (1ul << i)) {
152                     n_remaining++;
153                 }
154             }
155             assert(n == n_remaining);
156         }
157     }
158 }
159
160 static void
161 run_test(void (*function)(void))
162 {
163     function();
164     printf(".");
165 }
166
167 int
168 main(void)
169 {
170     run_test(test_list_construction);
171     run_test(test_list_for_each_safe);
172     printf("\n");
173     return 0;
174 }
175