]>
Commit | Line | Data |
---|---|---|
a14bc59f BP |
1 | /* |
2 | * Copyright (c) 2008, 2009 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 | ||
064af421 BP |
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, struct element, 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, struct element, 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, struct element, 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, struct element, 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 |