Blob


1 /*
2 * Copyright (c) 2019 Stefan Sperling <stsp@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
17 #include <stdarg.h>
18 #include <string.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <err.h>
24 #include "got_error.h"
26 #include "got_lib_pathset.h"
28 static int verbose;
30 void
31 test_printf(char *fmt, ...)
32 {
33 va_list ap;
35 if (!verbose)
36 return;
38 va_start(ap, fmt);
39 vprintf(fmt, ap);
40 va_end(ap);
41 }
43 static const char *path1 = "/", *path2 = "/usr", *path3 = "/usr/bin";
44 static const char *data1 = "data1", *data2 = "data2", *data3 = "data3";
46 static const struct got_error *
47 pathset_add_remove_iter_cb(const char *path, void *data, void *arg) {
48 test_printf("%s\n", path);
49 if ((strcmp(path, path1) == 0 && data == (void *)data1) ||
50 (strcmp(path, path3) == 0 && data == (void *)data3))
51 return NULL;
52 abort();
53 return NULL; /* not reached */
54 }
56 static int
57 pathset_add_remove_iter(void)
58 {
59 const struct got_error *err = NULL;
60 struct got_pathset *set;
62 set = got_pathset_alloc();
63 if (set == NULL) {
64 err = got_error_from_errno();
65 goto done;
66 }
67 if (got_pathset_num_elements(set) != 0) {
68 err = got_error(GOT_ERR_BAD_PATH);
69 goto done;
70 }
73 err = got_pathset_add(set, path1, (void *)data1);
74 if (err)
75 goto done;
76 if (got_pathset_num_elements(set) != 1) {
77 err = got_error(GOT_ERR_BAD_PATH);
78 goto done;
79 }
81 if (!got_pathset_contains(set, path1)) {
82 err = got_error(GOT_ERR_BAD_PATH);
83 goto done;
84 }
86 err = got_pathset_add(set, path2, (void *)data2);
87 if (err)
88 goto done;
89 if (!got_pathset_contains(set, path2)) {
90 err = got_error(GOT_ERR_BAD_PATH);
91 goto done;
92 }
93 if (got_pathset_num_elements(set) != 2) {
94 err = got_error(GOT_ERR_BAD_PATH);
95 goto done;
96 }
98 err = got_pathset_add(set, path3, (void *)data3);
99 if (err)
100 goto done;
101 if (got_pathset_get(set, path3) != (void *)data3) {
102 err = got_error(GOT_ERR_BAD_PATH);
103 goto done;
105 if (got_pathset_num_elements(set) != 3) {
106 err = got_error(GOT_ERR_BAD_PATH);
107 goto done;
110 err = got_pathset_remove(NULL, set, path2);
111 if (err)
112 goto done;
113 if (got_pathset_num_elements(set) != 2) {
114 err = got_error(GOT_ERR_BAD_PATH);
115 goto done;
117 if (got_pathset_contains(set, path2)) {
118 err = got_error(GOT_ERR_BAD_PATH);
119 goto done;
121 if (got_pathset_get(set, path2) != NULL) {
122 err = got_error(GOT_ERR_BAD_PATH);
123 goto done;
126 got_pathset_for_each(set, pathset_add_remove_iter_cb, NULL);
127 done:
128 got_pathset_free(set);
129 return (err == NULL);
132 static const struct got_error *
133 pathset_iter_order_cb(const char *path, void *data, void *arg)
135 static int i;
136 test_printf("%s\n", path);
137 if (i == 0 && strcmp(path, "/") != 0)
138 abort();
139 if (i == 1 && strcmp(path, "/usr.bin") != 0)
140 abort();
141 if (i == 2 && strcmp(path, "/usr.bin/vi") != 0)
142 abort();
143 if (i == 3 && strcmp(path, "/usr.sbin") != 0)
144 abort();
145 if (i == 4 && strcmp(path, "/usr.sbin/unbound") != 0)
146 abort();
147 if (i == 5 && strcmp(path, "/usr.sbin/zic") != 0)
148 abort();
149 if (i > 5)
150 abort();
151 i++;
152 return NULL;
155 static const struct got_error *
156 pathset_iter_reverse_order_cb(const char *path, void *data, void *arg)
158 static int i;
159 test_printf("%s\n", path);
160 if (i == 0 && strcmp(path, "/usr.sbin/zic") != 0)
161 abort();
162 if (i == 1 && strcmp(path, "/usr.sbin/unbound") != 0)
163 abort();
164 if (i == 2 && strcmp(path, "/usr.sbin") != 0)
165 abort();
166 if (i == 3 && strcmp(path, "/usr.bin/vi") != 0)
167 abort();
168 if (i == 4 && strcmp(path, "/usr.bin") != 0)
169 abort();
170 if (i == 5 && strcmp(path, "/") != 0)
171 abort();
172 if (i > 5)
173 abort();
174 i++;
175 return NULL;
178 static int
179 pathset_iter_order(void)
181 const struct got_error *err = NULL;
182 struct got_pathset *set;
184 set = got_pathset_alloc();
185 if (set == NULL) {
186 err = got_error_from_errno();
187 goto done;
189 if (got_pathset_num_elements(set) != 0) {
190 err = got_error(GOT_ERR_BAD_PATH);
191 goto done;
195 err = got_pathset_add(set, "/usr.bin", (void *)data1);
196 if (err)
197 goto done;
198 err = got_pathset_add(set, "/usr.sbin/unbound", (void *)data1);
199 if (err)
200 goto done;
201 err = got_pathset_add(set, "/usr.bin/vi", (void *)data1);
202 if (err)
203 goto done;
204 err = got_pathset_add(set, "/", (void *)data1);
205 if (err)
206 goto done;
207 err = got_pathset_add(set, "/usr.sbin/zic", (void *)data1);
208 if (err)
209 goto done;
210 err = got_pathset_add(set, "/usr.sbin", (void *)data1);
211 if (err)
212 goto done;
214 test_printf("normal order:\n");
215 got_pathset_for_each(set, pathset_iter_order_cb, NULL);
216 test_printf("reverse order:\n");
217 got_pathset_for_each_reverse(set, pathset_iter_reverse_order_cb,
218 NULL);
219 done:
220 got_pathset_free(set);
221 return (err == NULL);
224 #define RUN_TEST(expr, name) \
225 { test_ok = (expr); \
226 printf("test_%s %s\n", (name), test_ok ? "ok" : "failed"); \
227 failure = (failure || !test_ok); }
229 void
230 usage(void)
232 fprintf(stderr, "usage: pathset_test [-v]\n");
235 int
236 main(int argc, char *argv[])
238 int test_ok = 0, failure = 0;
239 int ch;
241 #ifndef PROFILE
242 if (pledge("stdio", NULL) == -1)
243 err(1, "pledge");
244 #endif
246 while ((ch = getopt(argc, argv, "v")) != -1) {
247 switch (ch) {
248 case 'v':
249 verbose = 1;
250 break;
251 default:
252 usage();
253 return 1;
256 argc -= optind;
257 argv += optind;
259 RUN_TEST(pathset_add_remove_iter(), "pathset_add_remove_iter");
260 RUN_TEST(pathset_iter_order(), "pathset_iter_order");
262 return failure ? 1 : 0;