Print this page
5293 desire symbol visibility test
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: TBD

*** 8,34 **** * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* ! * Copyright 2014 Garrett D'Amore <garrett@damore.org> */ /* * Common handling for test programs. */ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <pthread.h> #include "test_common.h" static int debug = 0; static int force = 0; static pthread_mutex_t lk; struct test { char *name; int ntids; pthread_t *tids; int fails; --- 8,42 ---- * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* ! * Copyright 2015 Garrett D'Amore <garrett@damore.org> */ /* * Common handling for test programs. */ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> + #include <string.h> + #include <errno.h> #include <pthread.h> + #include <ctype.h> + #include <unistd.h> + #include <sys/param.h> #include "test_common.h" static int debug = 0; static int force = 0; static pthread_mutex_t lk; + static int passes; + static int tests; + struct test { char *name; int ntids; pthread_t *tids; int fails;
*** 74,95 **** test_debugf(t, NULL); test_failed(t, NULL); test_passed(t); test_set_debug(); test_set_force(); #endif return (t); - } void test_failed(test_t t, const char *format, ...) { va_list args; (void) pthread_mutex_lock(&lk); if (force || (t->ntids > 0)) { (void) printf("TEST FAILING %s: ", t->name); } else { (void) printf("TEST FAILED %s: ", t->name); } --- 82,115 ---- test_debugf(t, NULL); test_failed(t, NULL); test_passed(t); test_set_debug(); test_set_force(); + test_summary(); + (void) test_load_config(t, NULL, NULL); #endif + tests++; return (t); } void test_failed(test_t t, const char *format, ...) { va_list args; (void) pthread_mutex_lock(&lk); + if (t == NULL) { + (void) printf("FAILURE: "); + va_start(args, format); + (void) vprintf(format, args); + va_end(args); + (void) printf("\n"); + (void) fflush(stdout); + (void) pthread_mutex_unlock(&lk); + return; + } if (force || (t->ntids > 0)) { (void) printf("TEST FAILING %s: ", t->name); } else { (void) printf("TEST FAILED %s: ", t->name); }
*** 112,121 **** --- 132,144 ---- } void test_passed(test_t t) { + if (t == NULL) { + return; + } if (t->ntids > 0) { if (debug) { (void) pthread_mutex_lock(&lk); (void) printf("TEST PASSING: %s\n", t->name); (void) pthread_mutex_unlock(&lk);
*** 122,131 **** --- 145,155 ---- } return; } (void) pthread_mutex_lock(&lk); if (t->fails == 0) { + passes++; (void) printf("TEST PASS: %s\n", t->name); } else { (void) printf("TEST FAILED: %d failures\n", t->fails); } (void) fflush(stdout);
*** 136,155 **** } free(t); } void test_debugf(test_t t, const char *format, ...) { va_list args; if (!debug) return; (void) pthread_mutex_lock(&lk); (void) printf("TEST DEBUG %s: ", t->name); ! va_start(args, format); (void) vprintf(format, args); va_end(args); (void) printf("\n"); (void) fflush(stdout); --- 160,193 ---- } free(t); } void + test_summary(void) + { + if (passes == tests) { + (void) printf("TEST SUMMARY: %d / %d (ok)\n", passes, tests); + } else { + (void) printf("TEST SUMMARY: %d / %d (%d failing)\n", + passes, tests, tests - passes); + } + } + + void test_debugf(test_t t, const char *format, ...) { va_list args; if (!debug) return; (void) pthread_mutex_lock(&lk); + if (t) { (void) printf("TEST DEBUG %s: ", t->name); ! } else { ! (void) printf("TEST DEBUG: "); ! } va_start(args, format); (void) vprintf(format, args); va_end(args); (void) printf("\n"); (void) fflush(stdout);
*** 201,206 **** --- 239,406 ---- (void) pthread_join(t->tids[i], NULL); test_debugf(t, "thread %d joined", i); t->ntids--; } test_passed(t); + } + + void + test_trim(char **ptr) + { + char *p = *ptr; + while (isspace(*p)) { + p++; + } + *ptr = p; + p += strlen(p); + while ((--p >= *ptr) && (isspace(*p))) { + *p = 0; + } + } + + #define MAXCB 20 + #define MAXFIELD 20 + + int + test_load_config(test_t t, const char *fname, ...) + { + va_list va; + const char *keyws[MAXCB]; + test_cfg_func_t callbs[MAXCB]; + char *fields[MAXFIELD]; + int nfields; + + FILE *cfg; + char line[1024]; + char buf[1024]; + int done; + char *ptr; + char *tok; + char *err; + int lineno; + int rv; + int found; + char path[MAXPATHLEN]; + int i; + + va_start(va, fname); + for (i = 0; i < MAXCB; i++) { + keyws[i] = (const char *)va_arg(va, const char *); + if (keyws[i] == NULL) + break; + callbs[i] = (test_cfg_func_t)va_arg(va, test_cfg_func_t); + } + va_end(va); + if (i == MAXCB) { + test_debugf(t, "too many arguments to function >= %d", MAXCB); + } + + found = 0; + + if (access(fname, F_OK) == 0) { + found++; + } + if (!found && fname[0] != '/') { + char *stf = getenv("STF_SUITE"); + if (stf == NULL) { + stf = "../.."; + } + (void) snprintf(path, sizeof (path), "%s/cfg/%s", stf, fname); + if (access(path, F_OK) == 0) { + fname = path; + found++; + } else { + (void) snprintf(path, sizeof (path), "cfg/%s", fname); + if (access(path, F_OK) == 0) { + fname = path; + found++; + } + } + } + + if ((cfg = fopen(fname, "r")) == NULL) { + test_failed(t, "open(%s): %s", fname, strerror(errno)); + return (-1); + } + + line[0] = 0; + done = 0; + lineno = 0; + + while (!done) { + + lineno++; + + if (fgets(buf, sizeof (buf), cfg) == NULL) { + done++; + } else { + (void) strtok(buf, "\n"); + if ((*buf != 0) && (buf[strlen(buf)-1] == '\\')) { + /* + * Continuation. This isn't quite right, + * as it doesn't allow for a "\" at the + * end of line (no escaping). + */ + buf[strlen(buf)-1] = 0; + (void) strlcat(line, buf, sizeof (line)); + continue; + } + (void) strlcat(line, buf, sizeof (line)); + } + + /* got a line */ + ptr = line; + test_trim(&ptr); + + /* skip comments and empty lines */ + if (ptr[0] == 0 || ptr[0] == '#') { + line[0] = 0; + continue; + } + + tok = strsep(&ptr, "|"); + if (tok == NULL) { + break; + } + test_trim(&tok); + + for (nfields = 0; nfields < MAXFIELD; nfields++) { + fields[nfields] = strsep(&ptr, "|"); + if (fields[nfields] == NULL) { + break; + } + test_trim(&fields[nfields]); + } + + found = 0; + rv = 0; + + for (int i = 0; keyws[i] != NULL; i++) { + if (strcmp(tok, keyws[i]) == 0) { + found++; + err = NULL; + rv = callbs[i](fields, nfields, &err); + } + } + if (!found) { + rv = -1; + err = NULL; + (void) asprintf(&err, "unknown keyword %s", tok); + } + if (rv != 0) { + if (err) { + test_failed(t, "%s:%d: %s", fname, + lineno, err); + free(err); + } else { + test_failed(t, "%s:%d: unknown error", + fname, lineno); + } + (void) fclose(cfg); + return (rv); + } + + line[0] = 0; + } + (void) fclose(cfg); + return (0); }