]> granicus.if.org Git - sudo/blob - lib/util/regress/tailq/hltq_test.c
Add SPDX-License-Identifier to files.
[sudo] / lib / util / regress / tailq / hltq_test.c
1 /*
2  * SPDX-License-Identifier: ISC
3  *
4  * Copyright (c) 2013 Todd C. Miller <Todd.Miller@sudo.ws>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18
19 #include <config.h>
20
21 #include <sys/types.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stddef.h>
25 #ifdef HAVE_STRING_H
26 # include <string.h>
27 #endif /* HAVE_STRING_H */
28 #ifdef HAVE_STRINGS_H
29 # include <strings.h>
30 #endif /* HAVE_STRINGS_H */
31 #ifdef HAVE_STDBOOL_H
32 # include <stdbool.h>
33 #else
34 # include "compat/stdbool.h"
35 #endif
36
37 #include "sudo_compat.h"
38 #include "sudo_fatal.h"
39 #include "sudo_queue.h"
40 #include "sudo_util.h"
41
42 __dso_public int main(int argc, char *argv[]);
43
44 /*
45  * Note: HLTQ_ENTRY is intentionally in the middle of the struct
46  *       to catch bad assumptions in the PREV/NEXT macros.
47  */
48 struct test_data {
49     int a;
50     HLTQ_ENTRY(test_data) entries;
51     char b;
52 };
53
54 TAILQ_HEAD(test_data_list, test_data);
55
56 /*
57  * Simple tests for headless tail queue macros.
58  */
59 int
60 main(int argc, char *argv[])
61 {
62     struct test_data d1, d2, d3;
63     struct test_data *hltq;
64     struct test_data_list tq;
65     int errors = 0;
66     int ntests = 0;
67
68     initprogname(argc > 0 ? argv[0] : "hltq_test");
69
70     /*
71      * Initialize three data elements and concatenate them in order.
72      */
73     HLTQ_INIT(&d1, entries);
74     d1.a = 1;
75     d1.b = 'a';
76     if (HLTQ_FIRST(&d1) != &d1) {
77         sudo_warnx_nodebug("FAIL: HLTQ_FIRST(1 entry) doesn't return first element: got %p, expected %p", HLTQ_FIRST(&d1), &d1);
78         errors++;
79     }
80     ntests++;
81     if (HLTQ_LAST(&d1, test_data, entries) != &d1) {
82         sudo_warnx_nodebug("FAIL: HLTQ_LAST(1 entry) doesn't return first element: got %p, expected %p", HLTQ_LAST(&d1, test_data, entries), &d1);
83         errors++;
84     }
85     ntests++;
86     if (HLTQ_PREV(&d1, test_data, entries) != NULL) {
87         sudo_warnx_nodebug("FAIL: HLTQ_PREV(1 entry) doesn't return NULL: got %p", HLTQ_PREV(&d1, test_data, entries));
88         errors++;
89     }
90     ntests++;
91
92     HLTQ_INIT(&d2, entries);
93     d2.a = 2;
94     d2.b = 'b';
95
96     HLTQ_INIT(&d3, entries);
97     d3.a = 3;
98     d3.b = 'c';
99
100     HLTQ_CONCAT(&d1, &d2, entries);
101     HLTQ_CONCAT(&d1, &d3, entries);
102     hltq = &d1;
103
104     /*
105      * Verify that HLTQ_FIRST, HLTQ_LAST, HLTQ_NEXT, HLTQ_PREV
106      * work as expected.
107      */
108     if (HLTQ_FIRST(hltq) != &d1) {
109         sudo_warnx_nodebug("FAIL: HLTQ_FIRST(3 entries) doesn't return first element: got %p, expected %p", HLTQ_FIRST(hltq), &d1);
110         errors++;
111     }
112     ntests++;
113     if (HLTQ_LAST(hltq, test_data, entries) != &d3) {
114         sudo_warnx_nodebug("FAIL: HLTQ_LAST(3 entries) doesn't return third element: got %p, expected %p", HLTQ_LAST(hltq, test_data, entries), &d3);
115         errors++;
116     }
117     ntests++;
118
119     if (HLTQ_NEXT(&d1, entries) != &d2) {
120         sudo_warnx_nodebug("FAIL: HLTQ_NEXT(&d1) doesn't return &d2: got %p, expected %p", HLTQ_NEXT(&d1, entries), &d2);
121         errors++;
122     }
123     ntests++;
124     if (HLTQ_NEXT(&d2, entries) != &d3) {
125         sudo_warnx_nodebug("FAIL: HLTQ_NEXT(&d2) doesn't return &d3: got %p, expected %p", HLTQ_NEXT(&d2, entries), &d3);
126         errors++;
127     }
128     ntests++;
129     if (HLTQ_NEXT(&d3, entries) != NULL) {
130         sudo_warnx_nodebug("FAIL: HLTQ_NEXT(&d3) doesn't return NULL: got %p", HLTQ_NEXT(&d3, entries));
131         errors++;
132     }
133     ntests++;
134
135     if (HLTQ_PREV(&d1, test_data, entries) != NULL) {
136         sudo_warnx_nodebug("FAIL: HLTQ_PREV(&d1) doesn't return NULL: got %p", HLTQ_PREV(&d1, test_data, entries));
137         errors++;
138     }
139     ntests++;
140     if (HLTQ_PREV(&d2, test_data, entries) != &d1) {
141         sudo_warnx_nodebug("FAIL: HLTQ_PREV(&d2) doesn't return &d1: got %p, expected %p", HLTQ_PREV(&d2, test_data, entries), &d1);
142         errors++;
143     }
144     ntests++;
145     if (HLTQ_PREV(&d3, test_data, entries) != &d2) {
146         sudo_warnx_nodebug("FAIL: HLTQ_PREV(&d3) doesn't return &d2: got %p, expected %p", HLTQ_PREV(&d3, test_data, entries), &d2);
147         errors++;
148     }
149     ntests++;
150
151     /* Test conversion to TAILQ. */
152     HLTQ_TO_TAILQ(&tq, hltq, entries);
153
154     if (TAILQ_FIRST(&tq) != &d1) {
155         sudo_warnx_nodebug("FAIL: TAILQ_FIRST(&tq) doesn't return first element: got %p, expected %p", TAILQ_FIRST(&tq), &d1);
156         errors++;
157     }
158     ntests++;
159     if (TAILQ_LAST(&tq, test_data_list) != &d3) {
160         sudo_warnx_nodebug("FAIL: TAILQ_LAST(&tq) doesn't return third element: got %p, expected %p", TAILQ_LAST(&tq, test_data_list), &d3);
161         errors++;
162     }
163     ntests++;
164
165     if (TAILQ_NEXT(&d1, entries) != &d2) {
166         sudo_warnx_nodebug("FAIL: TAILQ_NEXT(&d1) doesn't return &d2: got %p, expected %p", TAILQ_NEXT(&d1, entries), &d2);
167         errors++;
168     }
169     ntests++;
170     if (TAILQ_NEXT(&d2, entries) != &d3) {
171         sudo_warnx_nodebug("FAIL: TAILQ_NEXT(&d2) doesn't return &d3: got %p, expected %p", TAILQ_NEXT(&d2, entries), &d3);
172         errors++;
173     }
174     ntests++;
175     if (TAILQ_NEXT(&d3, entries) != NULL) {
176         sudo_warnx_nodebug("FAIL: TAILQ_NEXT(&d3) doesn't return NULL: got %p", TAILQ_NEXT(&d3, entries));
177         errors++;
178     }
179     ntests++;
180
181     if (TAILQ_PREV(&d1, test_data_list, entries) != NULL) {
182         sudo_warnx_nodebug("FAIL: TAILQ_PREV(&d1) doesn't return NULL: got %p", TAILQ_PREV(&d1, test_data_list, entries));
183         errors++;
184     }
185     ntests++;
186     if (TAILQ_PREV(&d2, test_data_list, entries) != &d1) {
187         sudo_warnx_nodebug("FAIL: TAILQ_PREV(&d2) doesn't return &d1: got %p, expected %p", TAILQ_PREV(&d2, test_data_list, entries), &d1);
188         errors++;
189     }
190     ntests++;
191     if (TAILQ_PREV(&d3, test_data_list, entries) != &d2) {
192         sudo_warnx_nodebug("FAIL: TAILQ_PREV(&d3) doesn't return &d2: got %p, expected %p", TAILQ_PREV(&d3, test_data_list, entries), &d2);
193         errors++;
194     }
195     ntests++;
196
197     printf("%s: %d tests run, %d errors, %d%% success rate\n", getprogname(),
198         ntests, errors, (ntests - errors) * 100 / ntests);
199
200     exit(errors);
201 }