Back to index

nagios-plugins  1.4.16
Defines | Functions | Variables
tap.c File Reference
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "tap.h"

Go to the source code of this file.

Defines

#define LOCK
#define UNLOCK

Functions

static void _expected_tests (unsigned int)
static void _tap_init (void)
static void _cleanup (void)
unsigned int _gen_result (int ok, const char *func, char *file, unsigned int line, char *test_name,...)
int plan_no_plan (void)
int plan_skip_all (char *reason)
int plan_tests (unsigned int tests)
unsigned int diag (char *fmt,...)
int skip (unsigned int n, char *fmt,...)
void todo_start (char *fmt,...)
void todo_end (void)
int exit_status (void)

Variables

static int no_plan = 0
static int skip_all = 0
static int have_plan = 0
static unsigned int test_count = 0
static unsigned int e_tests = 0
static unsigned int failures = 0
static char * todo_msg = NULL
static char * todo_msg_fixed = "libtap malloc issue"
static int todo = 0
static int test_died = 0

Define Documentation

#define LOCK

Definition at line 53 of file tap.c.

#define UNLOCK

Definition at line 54 of file tap.c.


Function Documentation

void _cleanup ( void  ) [static]

Definition at line 389 of file tap.c.

{

       LOCK;

       /* If plan_no_plan() wasn't called, and we don't have a plan,
          and we're not skipping everything, then something happened
          before we could produce any output */
       if(!no_plan && !have_plan && !skip_all) {
              diag("Looks like your test died before it could output anything.");
              UNLOCK;
              return;
       }

       if(test_died) {
              diag("Looks like your test died just after %d.", test_count);
              UNLOCK;
              return;
       }


       /* No plan provided, but now we know how many tests were run, and can
          print the header at the end */
       if(!skip_all && (no_plan || !have_plan)) {
              printf("1..%d\n", test_count);
       }

       if((have_plan && !no_plan) && e_tests < test_count) {
              diag("Looks like you planned %d tests but ran %d extra.",
                   e_tests, test_count - e_tests);
              UNLOCK;
              return;
       }

       if((have_plan || !no_plan) && e_tests > test_count) {
              diag("Looks like you planned %d tests but only ran %d.",
                   e_tests, test_count);
              UNLOCK;
              return;
       }

       if(failures)
              diag("Looks like you failed %d tests of %d.", 
                   failures, test_count);

       UNLOCK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _expected_tests ( unsigned int  tests) [static]

Definition at line 290 of file tap.c.

{

       LOCK;

       printf("1..%d\n", tests);
       e_tests = tests;

       UNLOCK;
}

Here is the caller graph for this function:

unsigned int _gen_result ( int  ok,
const char *  func,
char *  file,
unsigned int  line,
char *  test_name,
  ... 
)

Definition at line 69 of file tap.c.

{
       va_list ap;
       char *local_test_name = NULL;
       char *c;
       int name_is_digits;

       LOCK;

       test_count++;

       /* Start by taking the test name and performing any printf()
          expansions on it */
       if(test_name != NULL) {
              va_start(ap, test_name);
              vasprintf(&local_test_name, test_name, ap);
              va_end(ap);

              /* Make sure the test name contains more than digits
                 and spaces.  Emit an error message and exit if it
                 does */
              if(local_test_name) {
                     name_is_digits = 1;
                     for(c = local_test_name; *c != '\0'; c++) {
                            if(!isdigit(*c) && !isspace(*c)) {
                                   name_is_digits = 0;
                                   break;
                            }
                     }

                     if(name_is_digits) {
                            diag("    You named your test '%s'.  You shouldn't use numbers for your test names.", local_test_name);
                            diag("    Very confusing.");
                     }
              }
       }

       if(!ok) {
              printf("not ");
              failures++;
       }

       printf("ok %d", test_count);

       if(test_name != NULL) {
              printf(" - ");

              /* Print the test name, escaping any '#' characters it
                 might contain */
              if(local_test_name != NULL) {
                     flockfile(stdout);
                     for(c = local_test_name; *c != '\0'; c++) {
                            if(*c == '#')
                                   fputc('\\', stdout);
                            fputc((int)*c, stdout);
                     }
                     funlockfile(stdout);
              } else {      /* vasprintf() failed, use a fixed message */
                     printf("%s", todo_msg_fixed);
              }
       }

       /* If we're in a todo_start() block then flag the test as being
          TODO.  todo_msg should contain the message to print at this
          point.  If it's NULL then asprintf() failed, and we should
          use the fixed message.

          This is not counted as a failure, so decrement the counter if
          the test failed. */
       if(todo) {
              printf(" # TODO %s", todo_msg ? todo_msg : todo_msg_fixed);
              if(!ok)
                     failures--;
       }

       printf("\n");

       if(!ok)
              diag("    Failed %stest (%s:%s() at line %d)", 
                   todo ? "(TODO) " : "", file, func, line);

       free(local_test_name);

       UNLOCK;

       /* We only care (when testing) that ok is positive, but here we
          specifically only want to return 1 or 0 */
       return ok ? 1 : 0;
}

Here is the call graph for this function:

void _tap_init ( void  ) [static]

Definition at line 165 of file tap.c.

{
       static int run_once = 0;

       LOCK;

       if(!run_once) {
              atexit(_cleanup);

              /* stdout needs to be unbuffered so that the output appears
                 in the same place relative to stderr output as it does 
                 with Test::Harness */
              setbuf(stdout, 0);
              run_once = 1;
       }

       UNLOCK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned int diag ( char *  fmt,
  ... 
)

Definition at line 270 of file tap.c.

{
       va_list ap;

       LOCK;

       fputs("# ", stderr);

       va_start(ap, fmt);
       vfprintf(stderr, fmt, ap);
       va_end(ap);

       fputs("\n", stderr);

       UNLOCK;

       return 0;
}

Here is the caller graph for this function:

int exit_status ( void  )

Definition at line 356 of file tap.c.

{
       int r;

       LOCK;

       /* If there's no plan, just return the number of failures */
       if(no_plan || !have_plan) {
              UNLOCK;
              return failures;
       }

       /* Ran too many tests?  Return the number of tests that were run
          that shouldn't have been */
       if(e_tests < test_count) {
              r = test_count - e_tests;
              UNLOCK;
              return r;
       }

       /* Return the number of tests that failed + the number of tests 
          that weren't run */
       r = failures + e_tests - test_count;
       UNLOCK;

       return r;
}

Here is the caller graph for this function:

int plan_no_plan ( void  )

Definition at line 188 of file tap.c.

{

       LOCK;

       _tap_init();

       if(have_plan != 0) {
              fprintf(stderr, "You tried to plan twice!\n");
              test_died = 1;
              UNLOCK;
              exit(255);
       }

       have_plan = 1;
       no_plan = 1;

       UNLOCK;

       return 0;
}

Here is the call graph for this function:

int plan_skip_all ( char *  reason)

Definition at line 214 of file tap.c.

{

       LOCK;

       _tap_init();

       skip_all = 1;

       printf("1..0");

       if(reason != NULL)
              printf(" # Skip %s", reason);

       printf("\n");

       UNLOCK;

       exit(0);
}

Here is the call graph for this function:

int plan_tests ( unsigned int  tests)

Definition at line 239 of file tap.c.

{

       LOCK;

       _tap_init();

       if(have_plan != 0) {
              fprintf(stderr, "You tried to plan twice!\n");
              test_died = 1;
              UNLOCK;
              exit(255);
       }

       if(tests == 0) {
              fprintf(stderr, "You said to run 0 tests!  You've got to run something.\n");
              test_died = 1;
              UNLOCK;
              exit(255);
       }

       have_plan = 1;

       _expected_tests(tests);

       UNLOCK;

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int skip ( unsigned int  n,
char *  fmt,
  ... 
)

Definition at line 302 of file tap.c.

{
       va_list ap;
       char *skip_msg;

       LOCK;

       va_start(ap, fmt);
       asprintf(&skip_msg, fmt, ap);
       va_end(ap);

       while(n-- > 0) {
              test_count++;
              printf("ok %d # skip %s\n", test_count, 
                     skip_msg != NULL ? 
                     skip_msg : "libtap():malloc() failed");
       }

       free(skip_msg);

       UNLOCK;

       return 1;
}

Here is the call graph for this function:

void todo_end ( void  )

Definition at line 344 of file tap.c.

{

       LOCK;

       todo = 0;
       free(todo_msg);

       UNLOCK;
}
void todo_start ( char *  fmt,
  ... 
)

Definition at line 328 of file tap.c.

{
       va_list ap;

       LOCK;

       va_start(ap, fmt);
       vasprintf(&todo_msg, fmt, ap);
       va_end(ap);

       todo = 1;

       UNLOCK;
}

Here is the call graph for this function:


Variable Documentation

unsigned int e_tests = 0 [static]

Definition at line 38 of file tap.c.

unsigned int failures = 0 [static]

Definition at line 39 of file tap.c.

int have_plan = 0 [static]

Definition at line 36 of file tap.c.

int no_plan = 0 [static]

Definition at line 34 of file tap.c.

int skip_all = 0 [static]

Definition at line 35 of file tap.c.

unsigned int test_count = 0 [static]

Definition at line 37 of file tap.c.

int test_died = 0 [static]

Definition at line 43 of file tap.c.

int todo = 0 [static]

Definition at line 42 of file tap.c.

char* todo_msg = NULL [static]

Definition at line 40 of file tap.c.

char* todo_msg_fixed = "libtap malloc issue" [static]

Definition at line 41 of file tap.c.