Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / external / c-tap-harness / tests / tap / basic.c
CommitLineData
805e021f
CE
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 */
63unsigned 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 */
77static unsigned long _planned = 0;
78static unsigned long _failed = 0;
79static pid_t _process = 0;
80static 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 */
89static void
90finish(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 */
123void
124plan(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 */
142void
143plan_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 */
159void
160skip_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 */
180static void
181print_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 */
192void
193ok(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 */
213void
214okv(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 */
229void
230skip(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 */
249void
250ok_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 */
274void
275skip_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 */
299void
300is_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 */
325void
326is_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 */
355void
356is_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 */
381void
382bail(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 */
400void
401sysbail(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 */
420void
421diag(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 */
438void
439sysdiag(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 */
457void *
458bcalloc(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 */
472void *
473bmalloc(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 */
487void *
488brealloc(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 */
500char *
501bstrdup(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 */
520char *
521bstrndup(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 */
550char *
551test_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 */
580void
581test_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 */
598char *
599test_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 */
623void
624test_tmpdir_free(char *path)
625{
626 rmdir(path);
627 if (path != NULL)
628 free(path);
629}