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
↓ 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
↓ 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");
↓ 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)
↓ 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