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