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/cdefs.h>
28__FBSDID("$FreeBSD$");
29
30#include <sys/queue.h>
31#include <stdio.h>
32#include <stdlib.h>
33
34#include <atf-c.h>
35
36ATF_TC(slist_test);
37ATF_TC_HEAD(slist_test, tc)
38{
39
40	atf_tc_set_md_var(tc, "descr", "SLIST macro feature tests");
41}
42
43ATF_TC_BODY(slist_test, tc)
44{
45	SLIST_HEAD(stailhead, entry) head = SLIST_HEAD_INITIALIZER(head);
46	struct entry {
47		SLIST_ENTRY(entry) entries;
48		int i;
49	} *n1, *n2, *n3, *np;
50	int i, j, length;
51
52	SLIST_INIT(&head);
53
54	printf("Ensuring SLIST_EMPTY works\n");
55
56	ATF_REQUIRE(SLIST_EMPTY(&head));
57
58	i = length = 0;
59
60	SLIST_FOREACH(np, &head, entries) {
61		length++;
62	}
63	ATF_REQUIRE_EQ(length, 0);
64
65	printf("Ensuring SLIST_INSERT_HEAD works\n");
66
67	n1 = malloc(sizeof(struct entry));
68	ATF_REQUIRE(n1 != NULL);
69	n1->i = i++;
70
71	SLIST_INSERT_HEAD(&head, n1, entries);
72
73	printf("Ensuring SLIST_FIRST returns element 1\n");
74	ATF_REQUIRE_EQ(SLIST_FIRST(&head), n1);
75
76	j = length = 0;
77	SLIST_FOREACH(np, &head, entries) {
78		ATF_REQUIRE_EQ_MSG(np->i, j,
79		    "%d (entry counter) != %d (counter)", np->i, j);
80		j++;
81		length++;
82	}
83	ATF_REQUIRE_EQ(length, 1);
84
85	printf("Ensuring SLIST_INSERT_AFTER works\n");
86
87	n2 = malloc(sizeof(struct entry));
88	ATF_REQUIRE(n2 != NULL);
89	n2->i = i++;
90
91	SLIST_INSERT_AFTER(n1, n2, entries);
92
93	n3 = malloc(sizeof(struct entry));
94	ATF_REQUIRE(n3 != NULL);
95	n3->i = i++;
96
97	SLIST_INSERT_AFTER(n2, n3, entries);
98
99	j = length = 0;
100	SLIST_FOREACH(np, &head, entries) {
101		ATF_REQUIRE_EQ_MSG(np->i, j,
102		    "%d (entry counter) != %d (counter)", np->i, j);
103		j++;
104		length++;
105	}
106	ATF_REQUIRE_EQ(length, 3);
107
108	printf("Ensuring SLIST_REMOVE_HEAD works\n");
109
110	printf("Ensuring SLIST_FIRST returns element 1\n");
111	ATF_REQUIRE_EQ(SLIST_FIRST(&head), n1);
112
113	SLIST_REMOVE_HEAD(&head, entries);
114
115	printf("Ensuring SLIST_FIRST now returns element 2\n");
116	ATF_REQUIRE_EQ(SLIST_FIRST(&head), n2);
117
118	j = 1; /* Starting point's 1 this time */
119	length = 0;
120	SLIST_FOREACH(np, &head, entries) {
121		ATF_REQUIRE_EQ_MSG(np->i, j,
122		    "%d (entry counter) != %d (counter)", np->i, j);
123		j++;
124		length++;
125	}
126	ATF_REQUIRE_EQ(length, 2);
127
128	printf("Ensuring SLIST_REMOVE_AFTER works by removing the tail\n");
129
130	SLIST_REMOVE_AFTER(n2, entries);
131
132	j = 1; /* Starting point's 1 this time */
133	length = 0;
134	SLIST_FOREACH(np, &head, entries) {
135		ATF_REQUIRE_EQ_MSG(np->i, j,
136		    "%d (entry counter) != %d (counter)", np->i, j);
137		j++;
138		length++;
139	}
140	ATF_REQUIRE_EQ(length, 1);
141
142	printf("Ensuring SLIST_FIRST returns element 2\n");
143	ATF_REQUIRE_EQ(SLIST_FIRST(&head), n2);
144
145}
146
147ATF_TC(stailq_test);
148ATF_TC_HEAD(stailq_test, tc)
149{
150
151	atf_tc_set_md_var(tc, "descr", "STAILQ macro feature tests");
152}
153
154ATF_TC_BODY(stailq_test, tc)
155{
156	STAILQ_HEAD(stailhead, entry) head = STAILQ_HEAD_INITIALIZER(head);
157	struct entry {
158		STAILQ_ENTRY(entry) entries;
159		int i;
160	} *n1, *n2, *n3, *np;
161	int i, j, length;
162
163	printf("Ensuring empty STAILQs are treated properly\n");
164	STAILQ_INIT(&head);
165	ATF_REQUIRE(STAILQ_EMPTY(&head));
166
167	i = length = 0;
168
169	STAILQ_FOREACH(np, &head, entries) {
170		length++;
171	}
172	ATF_REQUIRE_EQ(length, 0);
173
174	printf("Ensuring STAILQ_INSERT_HEAD works\n");
175
176	n1 = malloc(sizeof(struct entry));
177	ATF_REQUIRE(n1 != NULL);
178	n1->i = i++;
179
180	STAILQ_INSERT_HEAD(&head, n1, entries);
181
182	j = length = 0;
183	STAILQ_FOREACH(np, &head, entries) {
184		ATF_REQUIRE_EQ_MSG(np->i, j,
185		    "%d (entry counter) != %d (counter)", np->i, j);
186		j++;
187		length++;
188	}
189	ATF_REQUIRE_EQ(length, 1);
190
191	printf("Ensuring STAILQ_INSERT_TAIL works\n");
192
193	n2 = malloc(sizeof(struct entry));
194	ATF_REQUIRE(n2 != NULL);
195	n2->i = i++;
196
197	STAILQ_INSERT_TAIL(&head, n2, entries);
198
199	n3 = malloc(sizeof(struct entry));
200	ATF_REQUIRE(n3 != NULL);
201	n3->i = i++;
202
203	STAILQ_INSERT_TAIL(&head, n3, entries);
204
205	j = length = 0;
206	STAILQ_FOREACH(np, &head, entries) {
207		ATF_REQUIRE_EQ_MSG(np->i, j,
208		    "%d (entry counter) != %d (counter)", np->i, j);
209		j++;
210		length++;
211	}
212	ATF_REQUIRE_EQ(length, 3);
213
214	printf("Ensuring STAILQ_REMOVE_HEAD works\n");
215
216	STAILQ_REMOVE_HEAD(&head, entries);
217
218	j = 1; /* Starting point's 1 this time */
219	length = 0;
220	STAILQ_FOREACH(np, &head, entries) {
221		ATF_REQUIRE_EQ_MSG(np->i, j,
222		    "%d (entry counter) != %d (counter)", np->i, j);
223		j++;
224		length++;
225	}
226	ATF_REQUIRE_EQ(length, 2);
227
228}
229
230ATF_TP_ADD_TCS(tp)
231{
232
233	ATF_TP_ADD_TC(tp, slist_test);
234	ATF_TP_ADD_TC(tp, stailq_test);
235
236	return (atf_no_error());
237}
238