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 {
49 test_printf("%s\n", path);
50 if ((strcmp(path, path1) == 0 && data == (void *)data1) ||
51 (strcmp(path, path3) == 0 && data == (void *)data3))
52 return NULL;
53 abort();
54 return NULL; /* not reached */
55 }
57 static int
58 pathset_add_remove_iter(void)
59 {
60 const struct got_error *err = NULL;
61 struct got_pathset *set;
63 set = got_pathset_alloc();
64 if (set == NULL) {
65 err = got_error_from_errno();
66 goto done;
67 }
68 if (got_pathset_num_elements(set) != 0) {
69 err = got_error(GOT_ERR_BAD_PATH);
70 goto done;
71 }
74 err = got_pathset_add(set, path1, (void *)data1);
75 if (err)
76 goto done;
77 if (got_pathset_num_elements(set) != 1) {
78 err = got_error(GOT_ERR_BAD_PATH);
79 goto done;
80 }
82 if (!got_pathset_contains(set, path1)) {
83 err = got_error(GOT_ERR_BAD_PATH);
84 goto done;
85 }
87 err = got_pathset_add(set, path2, (void *)data2);
88 if (err)
89 goto done;
90 if (!got_pathset_contains(set, path2)) {
91 err = got_error(GOT_ERR_BAD_PATH);
92 goto done;
93 }
94 if (got_pathset_num_elements(set) != 2) {
95 err = got_error(GOT_ERR_BAD_PATH);
96 goto done;
97 }
99 err = got_pathset_add(set, path3, (void *)data3);
100 if (err)
101 goto done;
102 if (got_pathset_get(set, path3) != (void *)data3) {
103 err = got_error(GOT_ERR_BAD_PATH);
104 goto done;
106 if (got_pathset_num_elements(set) != 3) {
107 err = got_error(GOT_ERR_BAD_PATH);
108 goto done;
111 err = got_pathset_remove(NULL, set, path2);
112 if (err)
113 goto done;
114 if (got_pathset_num_elements(set) != 2) {
115 err = got_error(GOT_ERR_BAD_PATH);
116 goto done;
118 if (got_pathset_contains(set, path2)) {
119 err = got_error(GOT_ERR_BAD_PATH);
120 goto done;
122 if (got_pathset_get(set, path2) != NULL) {
123 err = got_error(GOT_ERR_BAD_PATH);
124 goto done;
127 got_pathset_for_each_safe(set, pathset_add_remove_iter_cb, NULL);
128 done:
129 got_pathset_free(set);
130 return (err == NULL);
133 static const struct got_error *
134 pathset_iter_order_cb(const char *path, void *data, void *arg)
136 static int i;
137 test_printf("%s\n", path);
138 if (i == 0 && strcmp(path, "/") != 0)
139 abort();
140 if (i == 1 && strcmp(path, "/usr.bin") != 0)
141 abort();
142 if (i == 2 && strcmp(path, "/usr.bin/vi") != 0)
143 abort();
144 if (i == 3 && strcmp(path, "/usr.sbin") != 0)
145 abort();
146 if (i == 4 && strcmp(path, "/usr.sbin/unbound") != 0)
147 abort();
148 if (i == 5 && strcmp(path, "/usr.sbin/zic") != 0)
149 abort();
150 if (i > 5)
151 abort();
152 i++;
153 return NULL;
156 static const struct got_error *
157 pathset_iter_reverse_order_cb(const char *path, void *data, void *arg)
159 static int i;
160 test_printf("%s\n", path);
161 if (i == 0 && strcmp(path, "/usr.sbin/zic") != 0)
162 abort();
163 if (i == 1 && strcmp(path, "/usr.sbin/unbound") != 0)
164 abort();
165 if (i == 2 && strcmp(path, "/usr.sbin") != 0)
166 abort();
167 if (i == 3 && strcmp(path, "/usr.bin/vi") != 0)
168 abort();
169 if (i == 4 && strcmp(path, "/usr.bin") != 0)
170 abort();
171 if (i == 5 && strcmp(path, "/") != 0)
172 abort();
173 if (i > 5)
174 abort();
175 i++;
176 return NULL;
179 static int
180 pathset_iter_order(void)
182 const struct got_error *err = NULL;
183 struct got_pathset *set;
185 set = got_pathset_alloc();
186 if (set == NULL) {
187 err = got_error_from_errno();
188 goto done;
190 if (got_pathset_num_elements(set) != 0) {
191 err = got_error(GOT_ERR_BAD_PATH);
192 goto done;
196 err = got_pathset_add(set, "/usr.bin", (void *)data1);
197 if (err)
198 goto done;
199 err = got_pathset_add(set, "/usr.sbin/unbound", (void *)data1);
200 if (err)
201 goto done;
202 err = got_pathset_add(set, "/usr.bin/vi", (void *)data1);
203 if (err)
204 goto done;
205 err = got_pathset_add(set, "/", (void *)data1);
206 if (err)
207 goto done;
208 err = got_pathset_add(set, "/usr.sbin/zic", (void *)data1);
209 if (err)
210 goto done;
211 err = got_pathset_add(set, "/usr.sbin", (void *)data1);
212 if (err)
213 goto done;
215 test_printf("normal order:\n");
216 got_pathset_for_each_safe(set, pathset_iter_order_cb, NULL);
217 test_printf("reverse order:\n");
218 got_pathset_for_each_reverse_safe(set, pathset_iter_reverse_order_cb,
219 NULL);
220 done:
221 got_pathset_free(set);
222 return (err == NULL);
225 #define RUN_TEST(expr, name) \
226 { test_ok = (expr); \
227 printf("test_%s %s\n", (name), test_ok ? "ok" : "failed"); \
228 failure = (failure || !test_ok); }
230 void
231 usage(void)
233 fprintf(stderr, "usage: pathset_test [-v]\n");
236 int
237 main(int argc, char *argv[])
239 int test_ok = 0, failure = 0;
240 int ch;
242 #ifndef PROFILE
243 if (pledge("stdio", NULL) == -1)
244 err(1, "pledge");
245 #endif
247 while ((ch = getopt(argc, argv, "v")) != -1) {
248 switch (ch) {
249 case 'v':
250 verbose = 1;
251 break;
252 default:
253 usage();
254 return 1;
257 argc -= optind;
258 argv += optind;
260 RUN_TEST(pathset_add_remove_iter(), "pathset_add_remove_iter");
261 RUN_TEST(pathset_iter_order(), "pathset_iter_order");
263 return failure ? 1 : 0;