Print this page
5293 desire symbol visibility test
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: TBD
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/test/libc-tests/tests/common/test_common.c
+++ new/usr/src/test/libc-tests/tests/common/test_common.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 - * Copyright 2014 Garrett D'Amore <garrett@damore.org>
13 + * Copyright 2015 Garrett D'Amore <garrett@damore.org>
14 14 */
15 15
16 16 /*
17 17 * Common handling for test programs.
18 18 */
19 19
20 20 #include <stdio.h>
21 21 #include <stdlib.h>
22 22 #include <stdarg.h>
23 +#include <string.h>
24 +#include <errno.h>
23 25 #include <pthread.h>
26 +#include <ctype.h>
27 +#include <unistd.h>
28 +#include <sys/param.h>
24 29 #include "test_common.h"
25 30
26 31 static int debug = 0;
27 32 static int force = 0;
28 33 static pthread_mutex_t lk;
29 34
35 +static int passes;
36 +static int tests;
37 +
30 38 struct test {
31 39 char *name;
32 40 int ntids;
33 41 pthread_t *tids;
34 42 int fails;
35 43 void *arg;
36 44 void (*func)(test_t t, void *);
37 45 };
38 46
39 47 void
40 48 test_set_debug(void)
41 49 {
42 50 debug++;
43 51 }
44 52
45 53 void
46 54 test_set_force(void)
47 55 {
48 56 force++;
49 57 }
50 58
51 59 test_t
52 60 test_start(const char *format, ...)
53 61 {
54 62 va_list args;
55 63 test_t t;
56 64 char *s;
57 65
58 66 t = calloc(1, sizeof (*t));
59 67 va_start(args, format);
60 68 (void) vasprintf(&s, format, args);
61 69 va_end(args);
62 70
63 71 (void) asprintf(&t->name, "%s (%s)", s, ARCH);
64 72 free(s);
65 73
66 74 (void) pthread_mutex_lock(&lk);
67 75 (void) printf("TEST STARTING %s:\n", t->name);
68 76 (void) fflush(stdout);
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
69 77 (void) pthread_mutex_unlock(&lk);
70 78
71 79 #ifdef LINT
72 80 /* We inject references to make avoid name unused warnings */
73 81 test_run(0, NULL, NULL, NULL);
74 82 test_debugf(t, NULL);
75 83 test_failed(t, NULL);
76 84 test_passed(t);
77 85 test_set_debug();
78 86 test_set_force();
87 + test_summary();
88 + (void) test_load_config(t, NULL, NULL);
79 89 #endif
80 90
91 + tests++;
81 92 return (t);
82 -
83 93 }
84 94
85 95 void
86 96 test_failed(test_t t, const char *format, ...)
87 97 {
88 98 va_list args;
89 99
90 100 (void) pthread_mutex_lock(&lk);
101 + if (t == NULL) {
102 + (void) printf("FAILURE: ");
103 + va_start(args, format);
104 + (void) vprintf(format, args);
105 + va_end(args);
106 + (void) printf("\n");
107 + (void) fflush(stdout);
108 + (void) pthread_mutex_unlock(&lk);
109 + return;
110 + }
91 111 if (force || (t->ntids > 0)) {
92 112 (void) printf("TEST FAILING %s: ", t->name);
93 113 } else {
94 114 (void) printf("TEST FAILED %s: ", t->name);
95 115 }
96 116
97 117 va_start(args, format);
98 118 (void) vprintf(format, args);
99 119 va_end(args);
100 120 (void) printf("\n");
101 121 (void) fflush(stdout);
102 122 (void) pthread_mutex_unlock(&lk);
103 123
104 124 t->fails++;
105 125 if (!force) {
106 126 if (t->ntids > 0) {
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
107 127 pthread_exit(NULL);
108 128 } else {
109 129 (void) exit(EXIT_FAILURE);
110 130 }
111 131 }
112 132 }
113 133
114 134 void
115 135 test_passed(test_t t)
116 136 {
137 + if (t == NULL) {
138 + return;
139 + }
117 140 if (t->ntids > 0) {
118 141 if (debug) {
119 142 (void) pthread_mutex_lock(&lk);
120 143 (void) printf("TEST PASSING: %s\n", t->name);
121 144 (void) pthread_mutex_unlock(&lk);
122 145 }
123 146 return;
124 147 }
125 148 (void) pthread_mutex_lock(&lk);
126 149 if (t->fails == 0) {
150 + passes++;
127 151 (void) printf("TEST PASS: %s\n", t->name);
128 152 } else {
129 153 (void) printf("TEST FAILED: %d failures\n", t->fails);
130 154 }
131 155 (void) fflush(stdout);
132 156 (void) pthread_mutex_unlock(&lk);
133 157 free(t->name);
134 158 if (t->tids) {
135 159 free(t->tids);
136 160 }
137 161 free(t);
138 162 }
139 163
140 164 void
165 +test_summary(void)
166 +{
167 + if (passes == tests) {
168 + (void) printf("TEST SUMMARY: %d / %d (ok)\n", passes, tests);
169 + } else {
170 + (void) printf("TEST SUMMARY: %d / %d (%d failing)\n",
171 + passes, tests, tests - passes);
172 + }
173 +}
174 +
175 +void
141 176 test_debugf(test_t t, const char *format, ...)
142 177 {
143 178 va_list args;
144 179
145 180 if (!debug)
146 181 return;
147 182
148 183 (void) pthread_mutex_lock(&lk);
149 - (void) printf("TEST DEBUG %s: ", t->name);
150 -
184 + if (t) {
185 + (void) printf("TEST DEBUG %s: ", t->name);
186 + } else {
187 + (void) printf("TEST DEBUG: ");
188 + }
151 189 va_start(args, format);
152 190 (void) vprintf(format, args);
153 191 va_end(args);
154 192 (void) printf("\n");
155 193 (void) fflush(stdout);
156 194 (void) pthread_mutex_unlock(&lk);
157 195 }
158 196
159 197 static void *
160 198 test_thr_one(void *arg)
161 199 {
162 200 test_t t = arg;
163 201 t->func(t, t->arg);
164 202 return (NULL);
165 203 }
166 204
167 205 void
168 206 test_run(int nthr, void (*func)(test_t, void *), void *arg,
169 207 const char *tname, ...)
170 208 {
171 209 test_t t;
172 210 char *s;
173 211 va_list args;
174 212
175 213 t = calloc(1, sizeof (*t));
176 214 t->ntids = nthr;
177 215 t->tids = calloc(nthr, sizeof (pthread_t));
178 216 t->func = func;
179 217 t->arg = arg;
180 218
181 219 va_start(args, tname);
182 220 (void) vasprintf(&s, tname, args);
183 221 va_end(args);
184 222
185 223 (void) asprintf(&t->name, "%s (%s)", s, ARCH);
186 224 free(s);
187 225
188 226 (void) pthread_mutex_lock(&lk);
189 227 (void) printf("TEST STARTING %s:\n", t->name);
190 228 (void) fflush(stdout);
191 229 (void) pthread_mutex_unlock(&lk);
192 230
193 231 test_debugf(t, "running %d threads", nthr);
194 232
195 233 for (int i = 0; i < nthr; i++) {
↓ open down ↓ |
35 lines elided |
↑ open up ↑ |
196 234 test_debugf(t, "started thread %d", i);
197 235 (void) pthread_create(&t->tids[i], NULL, test_thr_one, t);
198 236 }
199 237
200 238 for (int i = 0; i < nthr; i++) {
201 239 (void) pthread_join(t->tids[i], NULL);
202 240 test_debugf(t, "thread %d joined", i);
203 241 t->ntids--;
204 242 }
205 243 test_passed(t);
244 +}
245 +
246 +void
247 +test_trim(char **ptr)
248 +{
249 + char *p = *ptr;
250 + while (isspace(*p)) {
251 + p++;
252 + }
253 + *ptr = p;
254 + p += strlen(p);
255 + while ((--p >= *ptr) && (isspace(*p))) {
256 + *p = 0;
257 + }
258 +}
259 +
260 +#define MAXCB 20
261 +#define MAXFIELD 20
262 +
263 +int
264 +test_load_config(test_t t, const char *fname, ...)
265 +{
266 + va_list va;
267 + const char *keyws[MAXCB];
268 + test_cfg_func_t callbs[MAXCB];
269 + char *fields[MAXFIELD];
270 + int nfields;
271 +
272 + FILE *cfg;
273 + char line[1024];
274 + char buf[1024];
275 + int done;
276 + char *ptr;
277 + char *tok;
278 + char *err;
279 + int lineno;
280 + int rv;
281 + int found;
282 + char path[MAXPATHLEN];
283 + int i;
284 +
285 + va_start(va, fname);
286 + for (i = 0; i < MAXCB; i++) {
287 + keyws[i] = (const char *)va_arg(va, const char *);
288 + if (keyws[i] == NULL)
289 + break;
290 + callbs[i] = (test_cfg_func_t)va_arg(va, test_cfg_func_t);
291 + }
292 + va_end(va);
293 + if (i == MAXCB) {
294 + test_debugf(t, "too many arguments to function >= %d", MAXCB);
295 + }
296 +
297 + found = 0;
298 +
299 + if (access(fname, F_OK) == 0) {
300 + found++;
301 + }
302 + if (!found && fname[0] != '/') {
303 + char *stf = getenv("STF_SUITE");
304 + if (stf == NULL) {
305 + stf = "../..";
306 + }
307 + (void) snprintf(path, sizeof (path), "%s/cfg/%s", stf, fname);
308 + if (access(path, F_OK) == 0) {
309 + fname = path;
310 + found++;
311 + } else {
312 + (void) snprintf(path, sizeof (path), "cfg/%s", fname);
313 + if (access(path, F_OK) == 0) {
314 + fname = path;
315 + found++;
316 + }
317 + }
318 + }
319 +
320 + if ((cfg = fopen(fname, "r")) == NULL) {
321 + test_failed(t, "open(%s): %s", fname, strerror(errno));
322 + return (-1);
323 + }
324 +
325 + line[0] = 0;
326 + done = 0;
327 + lineno = 0;
328 +
329 + while (!done) {
330 +
331 + lineno++;
332 +
333 + if (fgets(buf, sizeof (buf), cfg) == NULL) {
334 + done++;
335 + } else {
336 + (void) strtok(buf, "\n");
337 + if ((*buf != 0) && (buf[strlen(buf)-1] == '\\')) {
338 + /*
339 + * Continuation. This isn't quite right,
340 + * as it doesn't allow for a "\" at the
341 + * end of line (no escaping).
342 + */
343 + buf[strlen(buf)-1] = 0;
344 + (void) strlcat(line, buf, sizeof (line));
345 + continue;
346 + }
347 + (void) strlcat(line, buf, sizeof (line));
348 + }
349 +
350 + /* got a line */
351 + ptr = line;
352 + test_trim(&ptr);
353 +
354 + /* skip comments and empty lines */
355 + if (ptr[0] == 0 || ptr[0] == '#') {
356 + line[0] = 0;
357 + continue;
358 + }
359 +
360 + tok = strsep(&ptr, "|");
361 + if (tok == NULL) {
362 + break;
363 + }
364 + test_trim(&tok);
365 +
366 + for (nfields = 0; nfields < MAXFIELD; nfields++) {
367 + fields[nfields] = strsep(&ptr, "|");
368 + if (fields[nfields] == NULL) {
369 + break;
370 + }
371 + test_trim(&fields[nfields]);
372 + }
373 +
374 + found = 0;
375 + rv = 0;
376 +
377 + for (int i = 0; keyws[i] != NULL; i++) {
378 + if (strcmp(tok, keyws[i]) == 0) {
379 + found++;
380 + err = NULL;
381 + rv = callbs[i](fields, nfields, &err);
382 + }
383 + }
384 + if (!found) {
385 + rv = -1;
386 + err = NULL;
387 + (void) asprintf(&err, "unknown keyword %s", tok);
388 + }
389 + if (rv != 0) {
390 + if (err) {
391 + test_failed(t, "%s:%d: %s", fname,
392 + lineno, err);
393 + free(err);
394 + } else {
395 + test_failed(t, "%s:%d: unknown error",
396 + fname, lineno);
397 + }
398 + (void) fclose(cfg);
399 + return (rv);
400 + }
401 +
402 + line[0] = 0;
403 + }
404 + (void) fclose(cfg);
405 + return (0);
206 406 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX