Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / external / c-tap-harness / tests / tap / basic.c
1 /*
2 * Some utility routines for writing tests.
3 *
4 * Here are a variety of utility routines for writing tests compatible with
5 * the TAP protocol. All routines of the form ok() or is*() take a test
6 * number and some number of appropriate arguments, check to be sure the
7 * results match the expected output using the arguments, and print out
8 * something appropriate for that test number. Other utility routines help in
9 * constructing more complex tests, skipping tests, reporting errors, setting
10 * up the TAP output format, or finding things in the test environment.
11 *
12 * This file is part of C TAP Harness. The current version plus supporting
13 * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
14 *
15 * Copyright 2009, 2010, 2011, 2012 Russ Allbery <rra@stanford.edu>
16 * Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012
17 * The Board of Trustees of the Leland Stanford Junior University
18 *
19 * Permission is hereby granted, free of charge, to any person obtaining a
20 * copy of this software and associated documentation files (the "Software"),
21 * to deal in the Software without restriction, including without limitation
22 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
23 * and/or sell copies of the Software, and to permit persons to whom the
24 * Software is furnished to do so, subject to the following conditions:
25 *
26 * The above copyright notice and this permission notice shall be included in
27 * all copies or substantial portions of the Software.
28 *
29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
32 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
34 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
35 * DEALINGS IN THE SOFTWARE.
36 */
37
38 #include <errno.h>
39 #include <stdarg.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #ifdef _WIN32
44 # include <direct.h>
45 #else
46 # include <sys/stat.h>
47 #endif
48 #include <sys/types.h>
49 #include <unistd.h>
50
51 #include <tests/tap/basic.h>
52
53 /* Windows provides mkdir and rmdir under different names. */
54 #ifdef _WIN32
55 # define mkdir(p, m) _mkdir(p)
56 # define rmdir(p) _rmdir(p)
57 #endif
58
59 /*
60 * The test count. Always contains the number that will be used for the next
61 * test status.
62 */
63 unsigned long testnum = 1;
64
65 /*
66 * Status information stored so that we can give a test summary at the end of
67 * the test case. We store the planned final test and the count of failures.
68 * We can get the highest test count from testnum.
69 *
70 * We also store the PID of the process that called plan() and only summarize
71 * results when that process exits, so as to not misreport results in forked
72 * processes.
73 *
74 * If _lazy is true, we're doing lazy planning and will print out the plan
75 * based on the last test number at the end of testing.
76 */
77 static unsigned long _planned = 0;
78 static unsigned long _failed = 0;
79 static pid_t _process = 0;
80 static int _lazy = 0;
81
82
83 /*
84 * Our exit handler. Called on completion of the test to report a summary of
85 * results provided we're still in the original process. This also handles
86 * printing out the plan if we used plan_lazy(), although that's suppressed if
87 * we never ran a test (due to an early bail, for example).
88 */
89 static void
90 finish(void)
91 {
92 unsigned long highest = testnum - 1;
93
94 if (_planned == 0 && !_lazy)
95 return;
96 fflush(stderr);
97 if (_process != 0 && getpid() == _process) {
98 if (_lazy && highest > 0) {
99 printf("1..%lu\n", highest);
100 _planned = highest;
101 }
102 if (_planned > highest)
103 printf("# Looks like you planned %lu test%s but only ran %lu\n",
104 _planned, (_planned > 1 ? "s" : ""), highest);
105 else if (_planned < highest)
106 printf("# Looks like you planned %lu test%s but ran %lu extra\n",
107 _planned, (_planned > 1 ? "s" : ""), highest - _planned);
108 else if (_failed > 0)
109 printf("# Looks like you failed %lu test%s of %lu\n", _failed,
110 (_failed > 1 ? "s" : ""), _planned);
111 else if (_planned > 1)
112 printf("# All %lu tests successful or skipped\n", _planned);
113 else
114 printf("# %lu test successful or skipped\n", _planned);
115 }
116 }
117
118
119 /*
120 * Initialize things. Turns on line buffering on stdout and then prints out
121 * the number of tests in the test suite.
122 */
123 void
124 plan(unsigned long count)
125 {
126 if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0)
127 fprintf(stderr, "# cannot set stdout to line buffered: %s\n",
128 strerror(errno));
129 fflush(stderr);
130 printf("1..%lu\n", count);
131 testnum = 1;
132 _planned = count;
133 _process = getpid();
134 atexit(finish);
135 }
136
137
138 /*
139 * Initialize things for lazy planning, where we'll automatically print out a
140 * plan at the end of the program. Turns on line buffering on stdout as well.
141 */
142 void
143 plan_lazy(void)
144 {
145 if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0)
146 fprintf(stderr, "# cannot set stdout to line buffered: %s\n",
147 strerror(errno));
148 testnum = 1;
149 _process = getpid();
150 _lazy = 1;
151 atexit(finish);
152 }
153
154
155 /*
156 * Skip the entire test suite and exits. Should be called instead of plan(),
157 * not after it, since it prints out a special plan line.
158 */
159 void
160 skip_all(const char *format, ...)
161 {
162 fflush(stderr);
163 printf("1..0 # skip");
164 if (format != NULL) {
165 va_list args;
166
167 putchar(' ');
168 va_start(args, format);
169 vprintf(format, args);
170 va_end(args);
171 }
172 putchar('\n');
173 exit(0);
174 }
175
176
177 /*
178 * Print the test description.
179 */
180 static void
181 print_desc(const char *format, va_list args)
182 {
183 printf(" - ");
184 vprintf(format, args);
185 }
186
187
188 /*
189 * Takes a boolean success value and assumes the test passes if that value
190 * is true and fails if that value is false.
191 */
192 void
193 ok(int success, const char *format, ...)
194 {
195 fflush(stderr);
196 printf("%sok %lu", success ? "" : "not ", testnum++);
197 if (!success)
198 _failed++;
199 if (format != NULL) {
200 va_list args;
201
202 va_start(args, format);
203 print_desc(format, args);
204 va_end(args);
205 }
206 putchar('\n');
207 }
208
209
210 /*
211 * Same as ok(), but takes the format arguments as a va_list.
212 */
213 void
214 okv(int success, const char *format, va_list args)
215 {
216 fflush(stderr);
217 printf("%sok %lu", success ? "" : "not ", testnum++);
218 if (!success)
219 _failed++;
220 if (format != NULL)
221 print_desc(format, args);
222 putchar('\n');
223 }
224
225
226 /*
227 * Skip a test.
228 */
229 void
230 skip(const char *reason, ...)
231 {
232 fflush(stderr);
233 printf("ok %lu # skip", testnum++);
234 if (reason != NULL) {
235 va_list args;
236
237 va_start(args, reason);
238 putchar(' ');
239 vprintf(reason, args);
240 va_end(args);
241 }
242 putchar('\n');
243 }
244
245
246 /*
247 * Report the same status on the next count tests.
248 */
249 void
250 ok_block(unsigned long count, int status, const char *format, ...)
251 {
252 unsigned long i;
253
254 fflush(stderr);
255 for (i = 0; i < count; i++) {
256 printf("%sok %lu", status ? "" : "not ", testnum++);
257 if (!status)
258 _failed++;
259 if (format != NULL) {
260 va_list args;
261
262 va_start(args, format);
263 print_desc(format, args);
264 va_end(args);
265 }
266 putchar('\n');
267 }
268 }
269
270
271 /*
272 * Skip the next count tests.
273 */
274 void
275 skip_block(unsigned long count, const char *reason, ...)
276 {
277 unsigned long i;
278
279 fflush(stderr);
280 for (i = 0; i < count; i++) {
281 printf("ok %lu # skip", testnum++);
282 if (reason != NULL) {
283 va_list args;
284
285 va_start(args, reason);
286 putchar(' ');
287 vprintf(reason, args);
288 va_end(args);
289 }
290 putchar('\n');
291 }
292 }
293
294
295 /*
296 * Takes an expected integer and a seen integer and assumes the test passes
297 * if those two numbers match.
298 */
299 void
300 is_int(long wanted, long seen, const char *format, ...)
301 {
302 fflush(stderr);
303 if (wanted == seen)
304 printf("ok %lu", testnum++);
305 else {
306 printf("# wanted: %ld\n# seen: %ld\n", wanted, seen);
307 printf("not ok %lu", testnum++);
308 _failed++;
309 }
310 if (format != NULL) {
311 va_list args;
312
313 va_start(args, format);
314 print_desc(format, args);
315 va_end(args);
316 }
317 putchar('\n');
318 }
319
320
321 /*
322 * Takes a string and what the string should be, and assumes the test passes
323 * if those strings match (using strcmp).
324 */
325 void
326 is_string(const char *wanted, const char *seen, const char *format, ...)
327 {
328 if (wanted == NULL)
329 wanted = "(null)";
330 if (seen == NULL)
331 seen = "(null)";
332 fflush(stderr);
333 if (strcmp(wanted, seen) == 0)
334 printf("ok %lu", testnum++);
335 else {
336 printf("# wanted: %s\n# seen: %s\n", wanted, seen);
337 printf("not ok %lu", testnum++);
338 _failed++;
339 }
340 if (format != NULL) {
341 va_list args;
342
343 va_start(args, format);
344 print_desc(format, args);
345 va_end(args);
346 }
347 putchar('\n');
348 }
349
350
351 /*
352 * Takes an expected unsigned long and a seen unsigned long and assumes the
353 * test passes if the two numbers match. Otherwise, reports them in hex.
354 */
355 void
356 is_hex(unsigned long wanted, unsigned long seen, const char *format, ...)
357 {
358 fflush(stderr);
359 if (wanted == seen)
360 printf("ok %lu", testnum++);
361 else {
362 printf("# wanted: %lx\n# seen: %lx\n", (unsigned long) wanted,
363 (unsigned long) seen);
364 printf("not ok %lu", testnum++);
365 _failed++;
366 }
367 if (format != NULL) {
368 va_list args;
369
370 va_start(args, format);
371 print_desc(format, args);
372 va_end(args);
373 }
374 putchar('\n');
375 }
376
377
378 /*
379 * Bail out with an error.
380 */
381 void
382 bail(const char *format, ...)
383 {
384 va_list args;
385
386 fflush(stderr);
387 fflush(stdout);
388 printf("Bail out! ");
389 va_start(args, format);
390 vprintf(format, args);
391 va_end(args);
392 printf("\n");
393 exit(1);
394 }
395
396
397 /*
398 * Bail out with an error, appending strerror(errno).
399 */
400 void
401 sysbail(const char *format, ...)
402 {
403 va_list args;
404 int oerrno = errno;
405
406 fflush(stderr);
407 fflush(stdout);
408 printf("Bail out! ");
409 va_start(args, format);
410 vprintf(format, args);
411 va_end(args);
412 printf(": %s\n", strerror(oerrno));
413 exit(1);
414 }
415
416
417 /*
418 * Report a diagnostic to stderr.
419 */
420 void
421 diag(const char *format, ...)
422 {
423 va_list args;
424
425 fflush(stderr);
426 fflush(stdout);
427 printf("# ");
428 va_start(args, format);
429 vprintf(format, args);
430 va_end(args);
431 printf("\n");
432 }
433
434
435 /*
436 * Report a diagnostic to stderr, appending strerror(errno).
437 */
438 void
439 sysdiag(const char *format, ...)
440 {
441 va_list args;
442 int oerrno = errno;
443
444 fflush(stderr);
445 fflush(stdout);
446 printf("# ");
447 va_start(args, format);
448 vprintf(format, args);
449 va_end(args);
450 printf(": %s\n", strerror(oerrno));
451 }
452
453
454 /*
455 * Allocate cleared memory, reporting a fatal error with bail on failure.
456 */
457 void *
458 bcalloc(size_t n, size_t size)
459 {
460 void *p;
461
462 p = calloc(n, size);
463 if (p == NULL)
464 sysbail("failed to calloc %lu", (unsigned long)(n * size));
465 return p;
466 }
467
468
469 /*
470 * Allocate memory, reporting a fatal error with bail on failure.
471 */
472 void *
473 bmalloc(size_t size)
474 {
475 void *p;
476
477 p = malloc(size);
478 if (p == NULL)
479 sysbail("failed to malloc %lu", (unsigned long) size);
480 return p;
481 }
482
483
484 /*
485 * Reallocate memory, reporting a fatal error with bail on failure.
486 */
487 void *
488 brealloc(void *p, size_t size)
489 {
490 p = realloc(p, size);
491 if (p == NULL)
492 sysbail("failed to realloc %lu bytes", (unsigned long) size);
493 return p;
494 }
495
496
497 /*
498 * Copy a string, reporting a fatal error with bail on failure.
499 */
500 char *
501 bstrdup(const char *s)
502 {
503 char *p;
504 size_t len;
505
506 len = strlen(s) + 1;
507 p = malloc(len);
508 if (p == NULL)
509 sysbail("failed to strdup %lu bytes", (unsigned long) len);
510 memcpy(p, s, len);
511 return p;
512 }
513
514
515 /*
516 * Copy up to n characters of a string, reporting a fatal error with bail on
517 * failure. Don't use the system strndup function, since it may not exist and
518 * the TAP library doesn't assume any portability support.
519 */
520 char *
521 bstrndup(const char *s, size_t n)
522 {
523 const char *p;
524 char *copy;
525 size_t length;
526
527 /* Don't assume that the source string is nul-terminated. */
528 for (p = s; (size_t) (p - s) < n && *p != '\0'; p++)
529 ;
530 length = p - s;
531 copy = malloc(length + 1);
532 if (p == NULL)
533 sysbail("failed to strndup %lu bytes", (unsigned long) length);
534 memcpy(copy, s, length);
535 copy[length] = '\0';
536 return copy;
537 }
538
539
540 /*
541 * Locate a test file. Given the partial path to a file, look under BUILD and
542 * then SOURCE for the file and return the full path to the file. Returns
543 * NULL if the file doesn't exist. A non-NULL return should be freed with
544 * test_file_path_free().
545 *
546 * This function uses sprintf because it attempts to be independent of all
547 * other portability layers. The use immediately after a memory allocation
548 * should be safe without using snprintf or strlcpy/strlcat.
549 */
550 char *
551 test_file_path(const char *file)
552 {
553 char *base;
554 char *path = NULL;
555 size_t length;
556 const char *envs[] = { "BUILD", "SOURCE", NULL };
557 int i;
558
559 for (i = 0; envs[i] != NULL; i++) {
560 base = getenv(envs[i]);
561 if (base == NULL)
562 continue;
563 length = strlen(base) + 1 + strlen(file) + 1;
564 path = bmalloc(length);
565 sprintf(path, "%s/%s", base, file);
566 if (access(path, R_OK) == 0)
567 break;
568 free(path);
569 path = NULL;
570 }
571 return path;
572 }
573
574
575 /*
576 * Free a path returned from test_file_path(). This function exists primarily
577 * for Windows, where memory must be freed from the same library domain that
578 * it was allocated from.
579 */
580 void
581 test_file_path_free(char *path)
582 {
583 if (path != NULL)
584 free(path);
585 }
586
587
588 /*
589 * Create a temporary directory, tmp, under BUILD if set and the current
590 * directory if it does not. Returns the path to the temporary directory in
591 * newly allocated memory, and calls bail on any failure. The return value
592 * should be freed with test_tmpdir_free.
593 *
594 * This function uses sprintf because it attempts to be independent of all
595 * other portability layers. The use immediately after a memory allocation
596 * should be safe without using snprintf or strlcpy/strlcat.
597 */
598 char *
599 test_tmpdir(void)
600 {
601 const char *build;
602 char *path = NULL;
603 size_t length;
604
605 build = getenv("BUILD");
606 if (build == NULL)
607 build = ".";
608 length = strlen(build) + strlen("/tmp") + 1;
609 path = bmalloc(length);
610 sprintf(path, "%s/tmp", build);
611 if (access(path, X_OK) < 0)
612 if (mkdir(path, 0777) < 0)
613 sysbail("error creating temporary directory %s", path);
614 return path;
615 }
616
617
618 /*
619 * Free a path returned from test_tmpdir() and attempt to remove the
620 * directory. If we can't delete the directory, don't worry; something else
621 * that hasn't yet cleaned up may still be using it.
622 */
623 void
624 test_tmpdir_free(char *path)
625 {
626 rmdir(path);
627 if (path != NULL)
628 free(path);
629 }