diff options
Diffstat (limited to 'tap/tap.c')
| -rw-r--r-- | tap/tap.c | 140 |
1 files changed, 54 insertions, 86 deletions
| @@ -35,8 +35,8 @@ static int no_plan = 0; | |||
| 35 | static int skip_all = 0; | 35 | static int skip_all = 0; |
| 36 | static int have_plan = 0; | 36 | static int have_plan = 0; |
| 37 | static unsigned int test_count = 0; /* Number of tests that have been run */ | 37 | static unsigned int test_count = 0; /* Number of tests that have been run */ |
| 38 | static unsigned int e_tests = 0; /* Expected number of tests to run */ | 38 | static unsigned int e_tests = 0; /* Expected number of tests to run */ |
| 39 | static unsigned int failures = 0; /* Number of tests that failed */ | 39 | static unsigned int failures = 0; /* Number of tests that failed */ |
| 40 | static char *todo_msg = NULL; | 40 | static char *todo_msg = NULL; |
| 41 | static char *todo_msg_fixed = "libtap malloc issue"; | 41 | static char *todo_msg_fixed = "libtap malloc issue"; |
| 42 | static int todo = 0; | 42 | static int todo = 0; |
| @@ -45,13 +45,13 @@ static int test_died = 0; | |||
| 45 | /* Encapsulate the pthread code in a conditional. In the absence of | 45 | /* Encapsulate the pthread code in a conditional. In the absence of |
| 46 | libpthread the code does nothing */ | 46 | libpthread the code does nothing */ |
| 47 | #ifdef HAVE_LIBPTHREAD | 47 | #ifdef HAVE_LIBPTHREAD |
| 48 | #include <pthread.h> | 48 | # include <pthread.h> |
| 49 | static pthread_mutex_t M = PTHREAD_MUTEX_INITIALIZER; | 49 | static pthread_mutex_t M = PTHREAD_MUTEX_INITIALIZER; |
| 50 | # define LOCK pthread_mutex_lock(&M); | 50 | # define LOCK pthread_mutex_lock(&M); |
| 51 | # define UNLOCK pthread_mutex_unlock(&M); | 51 | # define UNLOCK pthread_mutex_unlock(&M); |
| 52 | #else | 52 | #else |
| 53 | # define LOCK | 53 | # define LOCK |
| 54 | # define UNLOCK | 54 | # define UNLOCK |
| 55 | #endif | 55 | #endif |
| 56 | 56 | ||
| 57 | static void _expected_tests(unsigned int); | 57 | static void _expected_tests(unsigned int); |
| @@ -65,10 +65,7 @@ static void _cleanup(void); | |||
| 65 | * test_name -- the name of the test, may be NULL | 65 | * test_name -- the name of the test, may be NULL |
| 66 | * test_comment -- a comment to print afterwards, may be NULL | 66 | * test_comment -- a comment to print afterwards, may be NULL |
| 67 | */ | 67 | */ |
| 68 | unsigned int | 68 | unsigned int _gen_result(int ok, const char *func, char *file, unsigned int line, char *test_name, ...) { |
| 69 | _gen_result(int ok, const char *func, char *file, unsigned int line, | ||
| 70 | char *test_name, ...) | ||
| 71 | { | ||
| 72 | va_list ap; | 69 | va_list ap; |
| 73 | char *local_test_name = NULL; | 70 | char *local_test_name = NULL; |
| 74 | char *c; | 71 | char *c; |
| @@ -80,7 +77,7 @@ _gen_result(int ok, const char *func, char *file, unsigned int line, | |||
| 80 | 77 | ||
| 81 | /* Start by taking the test name and performing any printf() | 78 | /* Start by taking the test name and performing any printf() |
| 82 | expansions on it */ | 79 | expansions on it */ |
| 83 | if(test_name != NULL) { | 80 | if (test_name != NULL) { |
| 84 | va_start(ap, test_name); | 81 | va_start(ap, test_name); |
| 85 | vasprintf(&local_test_name, test_name, ap); | 82 | vasprintf(&local_test_name, test_name, ap); |
| 86 | va_end(ap); | 83 | va_end(ap); |
| @@ -88,43 +85,43 @@ _gen_result(int ok, const char *func, char *file, unsigned int line, | |||
| 88 | /* Make sure the test name contains more than digits | 85 | /* Make sure the test name contains more than digits |
| 89 | and spaces. Emit an error message and exit if it | 86 | and spaces. Emit an error message and exit if it |
| 90 | does */ | 87 | does */ |
| 91 | if(local_test_name) { | 88 | if (local_test_name) { |
| 92 | name_is_digits = 1; | 89 | name_is_digits = 1; |
| 93 | for(c = local_test_name; *c != '\0'; c++) { | 90 | for (c = local_test_name; *c != '\0'; c++) { |
| 94 | if(!isdigit(*c) && !isspace(*c)) { | 91 | if (!isdigit(*c) && !isspace(*c)) { |
| 95 | name_is_digits = 0; | 92 | name_is_digits = 0; |
| 96 | break; | 93 | break; |
| 97 | } | 94 | } |
| 98 | } | 95 | } |
| 99 | 96 | ||
| 100 | if(name_is_digits) { | 97 | if (name_is_digits) { |
| 101 | diag(" You named your test '%s'. You shouldn't use numbers for your test names.", local_test_name); | 98 | diag(" You named your test '%s'. You shouldn't use numbers for your test names.", local_test_name); |
| 102 | diag(" Very confusing."); | 99 | diag(" Very confusing."); |
| 103 | } | 100 | } |
| 104 | } | 101 | } |
| 105 | } | 102 | } |
| 106 | 103 | ||
| 107 | if(!ok) { | 104 | if (!ok) { |
| 108 | printf("not "); | 105 | printf("not "); |
| 109 | failures++; | 106 | failures++; |
| 110 | } | 107 | } |
| 111 | 108 | ||
| 112 | printf("ok %d", test_count); | 109 | printf("ok %d", test_count); |
| 113 | 110 | ||
| 114 | if(test_name != NULL) { | 111 | if (test_name != NULL) { |
| 115 | printf(" - "); | 112 | printf(" - "); |
| 116 | 113 | ||
| 117 | /* Print the test name, escaping any '#' characters it | 114 | /* Print the test name, escaping any '#' characters it |
| 118 | might contain */ | 115 | might contain */ |
| 119 | if(local_test_name != NULL) { | 116 | if (local_test_name != NULL) { |
| 120 | flockfile(stdout); | 117 | flockfile(stdout); |
| 121 | for(c = local_test_name; *c != '\0'; c++) { | 118 | for (c = local_test_name; *c != '\0'; c++) { |
| 122 | if(*c == '#') | 119 | if (*c == '#') |
| 123 | fputc('\\', stdout); | 120 | fputc('\\', stdout); |
| 124 | fputc((int)*c, stdout); | 121 | fputc((int)*c, stdout); |
| 125 | } | 122 | } |
| 126 | funlockfile(stdout); | 123 | funlockfile(stdout); |
| 127 | } else { /* vasprintf() failed, use a fixed message */ | 124 | } else { /* vasprintf() failed, use a fixed message */ |
| 128 | printf("%s", todo_msg_fixed); | 125 | printf("%s", todo_msg_fixed); |
| 129 | } | 126 | } |
| 130 | } | 127 | } |
| @@ -136,17 +133,16 @@ _gen_result(int ok, const char *func, char *file, unsigned int line, | |||
| 136 | 133 | ||
| 137 | This is not counted as a failure, so decrement the counter if | 134 | This is not counted as a failure, so decrement the counter if |
| 138 | the test failed. */ | 135 | the test failed. */ |
| 139 | if(todo) { | 136 | if (todo) { |
| 140 | printf(" # TODO %s", todo_msg ? todo_msg : todo_msg_fixed); | 137 | printf(" # TODO %s", todo_msg ? todo_msg : todo_msg_fixed); |
| 141 | if(!ok) | 138 | if (!ok) |
| 142 | failures--; | 139 | failures--; |
| 143 | } | 140 | } |
| 144 | 141 | ||
| 145 | printf("\n"); | 142 | printf("\n"); |
| 146 | 143 | ||
| 147 | if(!ok) | 144 | if (!ok) |
| 148 | diag(" Failed %stest (%s:%s() at line %d)", | 145 | diag(" Failed %stest (%s:%s() at line %d)", todo ? "(TODO) " : "", file, func, line); |
| 149 | todo ? "(TODO) " : "", file, func, line); | ||
| 150 | 146 | ||
| 151 | free(local_test_name); | 147 | free(local_test_name); |
| 152 | 148 | ||
| @@ -161,18 +157,16 @@ _gen_result(int ok, const char *func, char *file, unsigned int line, | |||
| 161 | * Initialise the TAP library. Will only do so once, however many times it's | 157 | * Initialise the TAP library. Will only do so once, however many times it's |
| 162 | * called. | 158 | * called. |
| 163 | */ | 159 | */ |
| 164 | void | 160 | void _tap_init(void) { |
| 165 | _tap_init(void) | ||
| 166 | { | ||
| 167 | static int run_once = 0; | 161 | static int run_once = 0; |
| 168 | 162 | ||
| 169 | LOCK; | 163 | LOCK; |
| 170 | 164 | ||
| 171 | if(!run_once) { | 165 | if (!run_once) { |
| 172 | atexit(_cleanup); | 166 | atexit(_cleanup); |
| 173 | 167 | ||
| 174 | /* stdout needs to be unbuffered so that the output appears | 168 | /* stdout needs to be unbuffered so that the output appears |
| 175 | in the same place relative to stderr output as it does | 169 | in the same place relative to stderr output as it does |
| 176 | with Test::Harness */ | 170 | with Test::Harness */ |
| 177 | setbuf(stdout, 0); | 171 | setbuf(stdout, 0); |
| 178 | run_once = 1; | 172 | run_once = 1; |
| @@ -184,15 +178,13 @@ _tap_init(void) | |||
| 184 | /* | 178 | /* |
| 185 | * Note that there's no plan. | 179 | * Note that there's no plan. |
| 186 | */ | 180 | */ |
| 187 | int | 181 | int plan_no_plan(void) { |
| 188 | plan_no_plan(void) | ||
| 189 | { | ||
| 190 | 182 | ||
| 191 | LOCK; | 183 | LOCK; |
| 192 | 184 | ||
| 193 | _tap_init(); | 185 | _tap_init(); |
| 194 | 186 | ||
| 195 | if(have_plan != 0) { | 187 | if (have_plan != 0) { |
| 196 | fprintf(stderr, "You tried to plan twice!\n"); | 188 | fprintf(stderr, "You tried to plan twice!\n"); |
| 197 | test_died = 1; | 189 | test_died = 1; |
| 198 | UNLOCK; | 190 | UNLOCK; |
| @@ -210,9 +202,7 @@ plan_no_plan(void) | |||
| 210 | /* | 202 | /* |
| 211 | * Note that the plan is to skip all tests | 203 | * Note that the plan is to skip all tests |
| 212 | */ | 204 | */ |
| 213 | int | 205 | int plan_skip_all(char *reason) { |
| 214 | plan_skip_all(char *reason) | ||
| 215 | { | ||
| 216 | 206 | ||
| 217 | LOCK; | 207 | LOCK; |
| 218 | 208 | ||
| @@ -222,7 +212,7 @@ plan_skip_all(char *reason) | |||
| 222 | 212 | ||
| 223 | printf("1..0"); | 213 | printf("1..0"); |
| 224 | 214 | ||
| 225 | if(reason != NULL) | 215 | if (reason != NULL) |
| 226 | printf(" # Skip %s", reason); | 216 | printf(" # Skip %s", reason); |
| 227 | 217 | ||
| 228 | printf("\n"); | 218 | printf("\n"); |
| @@ -235,22 +225,20 @@ plan_skip_all(char *reason) | |||
| 235 | /* | 225 | /* |
| 236 | * Note the number of tests that will be run. | 226 | * Note the number of tests that will be run. |
| 237 | */ | 227 | */ |
| 238 | int | 228 | int plan_tests(unsigned int tests) { |
| 239 | plan_tests(unsigned int tests) | ||
| 240 | { | ||
| 241 | 229 | ||
| 242 | LOCK; | 230 | LOCK; |
| 243 | 231 | ||
| 244 | _tap_init(); | 232 | _tap_init(); |
| 245 | 233 | ||
| 246 | if(have_plan != 0) { | 234 | if (have_plan != 0) { |
| 247 | fprintf(stderr, "You tried to plan twice!\n"); | 235 | fprintf(stderr, "You tried to plan twice!\n"); |
| 248 | test_died = 1; | 236 | test_died = 1; |
| 249 | UNLOCK; | 237 | UNLOCK; |
| 250 | exit(255); | 238 | exit(255); |
| 251 | } | 239 | } |
| 252 | 240 | ||
| 253 | if(tests == 0) { | 241 | if (tests == 0) { |
| 254 | fprintf(stderr, "You said to run 0 tests! You've got to run something.\n"); | 242 | fprintf(stderr, "You said to run 0 tests! You've got to run something.\n"); |
| 255 | test_died = 1; | 243 | test_died = 1; |
| 256 | UNLOCK; | 244 | UNLOCK; |
| @@ -266,9 +254,7 @@ plan_tests(unsigned int tests) | |||
| 266 | return 0; | 254 | return 0; |
| 267 | } | 255 | } |
| 268 | 256 | ||
| 269 | unsigned int | 257 | unsigned int diag(char *fmt, ...) { |
| 270 | diag(char *fmt, ...) | ||
| 271 | { | ||
| 272 | va_list ap; | 258 | va_list ap; |
| 273 | 259 | ||
| 274 | LOCK; | 260 | LOCK; |
| @@ -286,9 +272,7 @@ diag(char *fmt, ...) | |||
| 286 | return 0; | 272 | return 0; |
| 287 | } | 273 | } |
| 288 | 274 | ||
| 289 | void | 275 | void _expected_tests(unsigned int tests) { |
| 290 | _expected_tests(unsigned int tests) | ||
| 291 | { | ||
| 292 | 276 | ||
| 293 | LOCK; | 277 | LOCK; |
| 294 | 278 | ||
| @@ -298,9 +282,7 @@ _expected_tests(unsigned int tests) | |||
| 298 | UNLOCK; | 282 | UNLOCK; |
| 299 | } | 283 | } |
| 300 | 284 | ||
| 301 | int | 285 | int skip(unsigned int n, char *fmt, ...) { |
| 302 | skip(unsigned int n, char *fmt, ...) | ||
| 303 | { | ||
| 304 | va_list ap; | 286 | va_list ap; |
| 305 | char *skip_msg; | 287 | char *skip_msg; |
| 306 | 288 | ||
| @@ -310,11 +292,9 @@ skip(unsigned int n, char *fmt, ...) | |||
| 310 | asprintf(&skip_msg, fmt, ap); | 292 | asprintf(&skip_msg, fmt, ap); |
| 311 | va_end(ap); | 293 | va_end(ap); |
| 312 | 294 | ||
| 313 | while(n-- > 0) { | 295 | while (n-- > 0) { |
| 314 | test_count++; | 296 | test_count++; |
| 315 | printf("ok %d # skip %s\n", test_count, | 297 | printf("ok %d # skip %s\n", test_count, skip_msg != NULL ? skip_msg : "libtap():malloc() failed"); |
| 316 | skip_msg != NULL ? | ||
| 317 | skip_msg : "libtap():malloc() failed"); | ||
| 318 | } | 298 | } |
| 319 | 299 | ||
| 320 | free(skip_msg); | 300 | free(skip_msg); |
| @@ -324,9 +304,7 @@ skip(unsigned int n, char *fmt, ...) | |||
| 324 | return 1; | 304 | return 1; |
| 325 | } | 305 | } |
| 326 | 306 | ||
| 327 | void | 307 | void todo_start(char *fmt, ...) { |
| 328 | todo_start(char *fmt, ...) | ||
| 329 | { | ||
| 330 | va_list ap; | 308 | va_list ap; |
| 331 | 309 | ||
| 332 | LOCK; | 310 | LOCK; |
| @@ -340,9 +318,7 @@ todo_start(char *fmt, ...) | |||
| 340 | UNLOCK; | 318 | UNLOCK; |
| 341 | } | 319 | } |
| 342 | 320 | ||
| 343 | void | 321 | void todo_end(void) { |
| 344 | todo_end(void) | ||
| 345 | { | ||
| 346 | 322 | ||
| 347 | LOCK; | 323 | LOCK; |
| 348 | 324 | ||
| @@ -352,28 +328,26 @@ todo_end(void) | |||
| 352 | UNLOCK; | 328 | UNLOCK; |
| 353 | } | 329 | } |
| 354 | 330 | ||
| 355 | int | 331 | int exit_status(void) { |
| 356 | exit_status(void) | ||
| 357 | { | ||
| 358 | int r; | 332 | int r; |
| 359 | 333 | ||
| 360 | LOCK; | 334 | LOCK; |
| 361 | 335 | ||
| 362 | /* If there's no plan, just return the number of failures */ | 336 | /* If there's no plan, just return the number of failures */ |
| 363 | if(no_plan || !have_plan) { | 337 | if (no_plan || !have_plan) { |
| 364 | UNLOCK; | 338 | UNLOCK; |
| 365 | return failures; | 339 | return failures; |
| 366 | } | 340 | } |
| 367 | 341 | ||
| 368 | /* Ran too many tests? Return the number of tests that were run | 342 | /* Ran too many tests? Return the number of tests that were run |
| 369 | that shouldn't have been */ | 343 | that shouldn't have been */ |
| 370 | if(e_tests < test_count) { | 344 | if (e_tests < test_count) { |
| 371 | r = test_count - e_tests; | 345 | r = test_count - e_tests; |
| 372 | UNLOCK; | 346 | UNLOCK; |
| 373 | return r; | 347 | return r; |
| 374 | } | 348 | } |
| 375 | 349 | ||
| 376 | /* Return the number of tests that failed + the number of tests | 350 | /* Return the number of tests that failed + the number of tests |
| 377 | that weren't run */ | 351 | that weren't run */ |
| 378 | r = failures + e_tests - test_count; | 352 | r = failures + e_tests - test_count; |
| 379 | UNLOCK; | 353 | UNLOCK; |
| @@ -385,51 +359,45 @@ exit_status(void) | |||
| 385 | * Cleanup at the end of the run, produce any final output that might be | 359 | * Cleanup at the end of the run, produce any final output that might be |
| 386 | * required. | 360 | * required. |
| 387 | */ | 361 | */ |
| 388 | void | 362 | void _cleanup(void) { |
| 389 | _cleanup(void) | ||
| 390 | { | ||
| 391 | 363 | ||
| 392 | LOCK; | 364 | LOCK; |
| 393 | 365 | ||
| 394 | /* If plan_no_plan() wasn't called, and we don't have a plan, | 366 | /* If plan_no_plan() wasn't called, and we don't have a plan, |
| 395 | and we're not skipping everything, then something happened | 367 | and we're not skipping everything, then something happened |
| 396 | before we could produce any output */ | 368 | before we could produce any output */ |
| 397 | if(!no_plan && !have_plan && !skip_all) { | 369 | if (!no_plan && !have_plan && !skip_all) { |
| 398 | diag("Looks like your test died before it could output anything."); | 370 | diag("Looks like your test died before it could output anything."); |
| 399 | UNLOCK; | 371 | UNLOCK; |
| 400 | return; | 372 | return; |
| 401 | } | 373 | } |
| 402 | 374 | ||
| 403 | if(test_died) { | 375 | if (test_died) { |
| 404 | diag("Looks like your test died just after %d.", test_count); | 376 | diag("Looks like your test died just after %d.", test_count); |
| 405 | UNLOCK; | 377 | UNLOCK; |
| 406 | return; | 378 | return; |
| 407 | } | 379 | } |
| 408 | 380 | ||
| 409 | |||
| 410 | /* No plan provided, but now we know how many tests were run, and can | 381 | /* No plan provided, but now we know how many tests were run, and can |
| 411 | print the header at the end */ | 382 | print the header at the end */ |
| 412 | if(!skip_all && (no_plan || !have_plan)) { | 383 | if (!skip_all && (no_plan || !have_plan)) { |
| 413 | printf("1..%d\n", test_count); | 384 | printf("1..%d\n", test_count); |
| 414 | } | 385 | } |
| 415 | 386 | ||
| 416 | if((have_plan && !no_plan) && e_tests < test_count) { | 387 | if ((have_plan && !no_plan) && e_tests < test_count) { |
| 417 | diag("Looks like you planned %d tests but ran %d extra.", | 388 | diag("Looks like you planned %d tests but ran %d extra.", e_tests, test_count - e_tests); |
| 418 | e_tests, test_count - e_tests); | ||
| 419 | UNLOCK; | 389 | UNLOCK; |
| 420 | return; | 390 | return; |
| 421 | } | 391 | } |
| 422 | 392 | ||
| 423 | if((have_plan || !no_plan) && e_tests > test_count) { | 393 | if ((have_plan || !no_plan) && e_tests > test_count) { |
| 424 | diag("Looks like you planned %d tests but only ran %d.", | 394 | diag("Looks like you planned %d tests but only ran %d.", e_tests, test_count); |
| 425 | e_tests, test_count); | ||
| 426 | UNLOCK; | 395 | UNLOCK; |
| 427 | return; | 396 | return; |
| 428 | } | 397 | } |
| 429 | 398 | ||
| 430 | if(failures) | 399 | if (failures) |
| 431 | diag("Looks like you failed %d tests of %d.", | 400 | diag("Looks like you failed %d tests of %d.", failures, test_count); |
| 432 | failures, test_count); | ||
| 433 | 401 | ||
| 434 | UNLOCK; | 402 | UNLOCK; |
| 435 | } | 403 | } |
