1/*-
2 * Copyright (c) 2015 EMC Corp.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/queue.h>
28#include <stdio.h>
29#include <stdlib.h>
30
31#include <atf-c.h>
32
33ATF_TC(slist_test);
34ATF_TC_HEAD(slist_test, tc)
35{
36
37	atf_tc_set_md_var(tc, "descr", "SLIST macro feature tests");
38}
39
40ATF_TC_BODY(slist_test, tc)
41{
42	SLIST_HEAD(stailhead, entry) head = SLIST_HEAD_INITIALIZER(head);
43	struct entry {
44		SLIST_ENTRY(entry) entries;
45		int i;
46	} *n1, *n2, *n3, *np;
47	int i, j, length;
48
49	SLIST_INIT(&head);
50
51	printf("Ensuring SLIST_EMPTY works\n");
52
53	ATF_REQUIRE(SLIST_EMPTY(&head));
54
55	i = length = 0;
56
57	SLIST_FOREACH(np, &head, entries) {
58		length++;
59	}
60	ATF_REQUIRE_EQ(length, 0);
61
62	printf("Ensuring SLIST_INSERT_HEAD works\n");
63
64	n1 = malloc(sizeof(struct entry));
65	ATF_REQUIRE(n1 != NULL);
66	n1->i = i++;
67
68	SLIST_INSERT_HEAD(&head, n1, entries);
69
70	printf("Ensuring SLIST_FIRST returns element 1\n");
71	ATF_REQUIRE_EQ(SLIST_FIRST(&head), n1);
72
73	j = length = 0;
74	SLIST_FOREACH(np, &head, entries) {
75		ATF_REQUIRE_EQ_MSG(np->i, j,
76		    "%d (entry counter) != %d (counter)", np->i, j);
77		j++;
78		length++;
79	}
80	ATF_REQUIRE_EQ(length, 1);
81
82	printf("Ensuring SLIST_INSERT_AFTER works\n");
83
84	n2 = malloc(sizeof(struct entry));
85	ATF_REQUIRE(n2 != NULL);
86	n2->i = i++;
87
88	SLIST_INSERT_AFTER(n1, n2, entries);
89
90	n3 = malloc(sizeof(struct entry));
91	ATF_REQUIRE(n3 != NULL);
92	n3->i = i++;
93
94	SLIST_INSERT_AFTER(n2, n3, entries);
95
96	j = length = 0;
97	SLIST_FOREACH(np, &head, entries) {
98		ATF_REQUIRE_EQ_MSG(np->i, j,
99		    "%d (entry counter) != %d (counter)", np->i, j);
100		j++;
101		length++;
102	}
103	ATF_REQUIRE_EQ(length, 3);
104
105	printf("Ensuring SLIST_REMOVE_HEAD works\n");
106
107	printf("Ensuring SLIST_FIRST returns element 1\n");
108	ATF_REQUIRE_EQ(SLIST_FIRST(&head), n1);
109
110	SLIST_REMOVE_HEAD(&head, entries);
111
112	printf("Ensuring SLIST_FIRST now returns element 2\n");
113	ATF_REQUIRE_EQ(SLIST_FIRST(&head), n2);
114
115	j = 1; /* Starting point's 1 this time */
116	length = 0;
117	SLIST_FOREACH(np, &head, entries) {
118		ATF_REQUIRE_EQ_MSG(np->i, j,
119		    "%d (entry counter) != %d (counter)", np->i, j);
120		j++;
121		length++;
122	}
123	ATF_REQUIRE_EQ(length, 2);
124
125	printf("Ensuring SLIST_REMOVE_AFTER works by removing the tail\n");
126
127	SLIST_REMOVE_AFTER(n2, entries);
128
129	j = 1; /* Starting point's 1 this time */
130	length = 0;
131	SLIST_FOREACH(np, &head, entries) {
132		ATF_REQUIRE_EQ_MSG(np->i, j,
133		    "%d (entry counter) != %d (counter)", np->i, j);
134		j++;
135		length++;
136	}
137	ATF_REQUIRE_EQ(length, 1);
138
139	printf("Ensuring SLIST_FIRST returns element 2\n");
140	ATF_REQUIRE_EQ(SLIST_FIRST(&head), n2);
141
142}
143
144ATF_TC(stailq_test);
145ATF_TC_HEAD(stailq_test, tc)
146{
147
148	atf_tc_set_md_var(tc, "descr", "STAILQ macro feature tests");
149}
150
151ATF_TC_BODY(stailq_test, tc)
152{
153	STAILQ_HEAD(stailhead, entry) head = STAILQ_HEAD_INITIALIZER(head);
154	struct entry {
155		STAILQ_ENTRY(entry) entries;
156		int i;
157	} *n1, *n2, *n3, *np;
158	int i, j, length;
159
160	printf("Ensuring empty STAILQs are treated properly\n");
161	STAILQ_INIT(&head);
162	ATF_REQUIRE(STAILQ_EMPTY(&head));
163
164	i = length = 0;
165
166	STAILQ_FOREACH(np, &head, entries) {
167		length++;
168	}
169	ATF_REQUIRE_EQ(length, 0);
170
171	printf("Ensuring STAILQ_INSERT_HEAD works\n");
172
173	n1 = malloc(sizeof(struct entry));
174	ATF_REQUIRE(n1 != NULL);
175	n1->i = i++;
176
177	STAILQ_INSERT_HEAD(&head, n1, entries);
178
179	j = length = 0;
180	STAILQ_FOREACH(np, &head, entries) {
181		ATF_REQUIRE_EQ_MSG(np->i, j,
182		    "%d (entry counter) != %d (counter)", np->i, j);
183		j++;
184		length++;
185	}
186	ATF_REQUIRE_EQ(length, 1);
187
188	printf("Ensuring STAILQ_INSERT_TAIL works\n");
189
190	n2 = malloc(sizeof(struct entry));
191	ATF_REQUIRE(n2 != NULL);
192	n2->i = i++;
193
194	STAILQ_INSERT_TAIL(&head, n2, entries);
195
196	n3 = malloc(sizeof(struct entry));
197	ATF_REQUIRE(n3 != NULL);
198	n3->i = i++;
199
200	STAILQ_INSERT_TAIL(&head, n3, entries);
201
202	j = length = 0;
203	STAILQ_FOREACH(np, &head, entries) {
204		ATF_REQUIRE_EQ_MSG(np->i, j,
205		    "%d (entry counter) != %d (counter)", np->i, j);
206		j++;
207		length++;
208	}
209	ATF_REQUIRE_EQ(length, 3);
210
211	printf("Ensuring STAILQ_REMOVE_HEAD works\n");
212
213	STAILQ_REMOVE_HEAD(&head, entries);
214
215	j = 1; /* Starting point's 1 this time */
216	length = 0;
217	STAILQ_FOREACH(np, &head, entries) {
218		ATF_REQUIRE_EQ_MSG(np->i, j,
219		    "%d (entry counter) != %d (counter)", np->i, j);
220		j++;
221		length++;
222	}
223	ATF_REQUIRE_EQ(length, 2);
224
225}
226
227ATF_TP_ADD_TCS(tp)
228{
229
230	ATF_TP_ADD_TC(tp, slist_test);
231	ATF_TP_ADD_TC(tp, stailq_test);
232
233	return (atf_no_error());
234}
235