|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* Copyright (c) 2013, Red Hat Inc.
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit Service |
6d40f9 |
* modification, are permitted provided that the following conditions
|
|
Packit Service |
6d40f9 |
* are met:
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* * Redistributions of source code must retain the above
|
|
Packit Service |
6d40f9 |
* copyright notice, this list of conditions and the
|
|
Packit Service |
6d40f9 |
* following disclaimer.
|
|
Packit Service |
6d40f9 |
* * Redistributions in binary form must reproduce the
|
|
Packit Service |
6d40f9 |
* above copyright notice, this list of conditions and
|
|
Packit Service |
6d40f9 |
* the following disclaimer in the documentation and/or
|
|
Packit Service |
6d40f9 |
* other materials provided with the distribution.
|
|
Packit Service |
6d40f9 |
* * The names of contributors to this software may not be
|
|
Packit Service |
6d40f9 |
* used to endorse or promote products derived from this
|
|
Packit Service |
6d40f9 |
* software without specific prior written permission.
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit Service |
6d40f9 |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit Service |
6d40f9 |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
Packit Service |
6d40f9 |
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
Packit Service |
6d40f9 |
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
Packit Service |
6d40f9 |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
Packit Service |
6d40f9 |
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
Packit Service |
6d40f9 |
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
Packit Service |
6d40f9 |
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
Packit Service |
6d40f9 |
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
Packit Service |
6d40f9 |
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|
Packit Service |
6d40f9 |
* DAMAGE.
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* Author: Stef Walter <stefw@redhat.com>
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#include "config.h"
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#define TEST_SOURCE 1
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#include "test.h"
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#include <assert.h>
|
|
Packit Service |
6d40f9 |
#include <setjmp.h>
|
|
Packit Service |
6d40f9 |
#include <stdarg.h>
|
|
Packit Service |
6d40f9 |
#include <stdio.h>
|
|
Packit Service |
6d40f9 |
#include <stdlib.h>
|
|
Packit Service |
6d40f9 |
#include <string.h>
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enum {
|
|
Packit Service |
6d40f9 |
FIXTURE,
|
|
Packit Service |
6d40f9 |
TEST,
|
|
Packit Service |
6d40f9 |
};
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
typedef void (*func_with_arg) (void *);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
typedef struct _test_item {
|
|
Packit Service |
6d40f9 |
int type;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
union {
|
|
Packit Service |
6d40f9 |
struct {
|
|
Packit Service |
6d40f9 |
char name[1024];
|
|
Packit Service |
6d40f9 |
func_with_arg func;
|
|
Packit Service |
6d40f9 |
void *argument;
|
|
Packit Service |
6d40f9 |
int failed;
|
|
Packit Service |
6d40f9 |
} test;
|
|
Packit Service |
6d40f9 |
struct {
|
|
Packit Service |
6d40f9 |
func_with_arg setup;
|
|
Packit Service |
6d40f9 |
func_with_arg teardown;
|
|
Packit Service |
6d40f9 |
} fix;
|
|
Packit Service |
6d40f9 |
} x;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
struct _test_item *next;
|
|
Packit Service |
6d40f9 |
} test_item;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
struct {
|
|
Packit Service |
6d40f9 |
test_item *suite;
|
|
Packit Service |
6d40f9 |
test_item *last;
|
|
Packit Service |
6d40f9 |
int number;
|
|
Packit Service |
6d40f9 |
jmp_buf jump;
|
|
Packit Service |
6d40f9 |
} gl = { NULL, NULL, 0, };
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
test_fail (const char *filename,
|
|
Packit Service |
6d40f9 |
int line,
|
|
Packit Service |
6d40f9 |
const char *function,
|
|
Packit Service |
6d40f9 |
const char *message,
|
|
Packit Service |
6d40f9 |
...)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
const char *pos;
|
|
Packit Service |
6d40f9 |
char *output;
|
|
Packit Service |
6d40f9 |
char *from;
|
|
Packit Service |
6d40f9 |
char *next;
|
|
Packit Service |
6d40f9 |
va_list va;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (gl.last != NULL);
|
|
Packit Service |
6d40f9 |
assert (gl.last->type == TEST);
|
|
Packit Service |
6d40f9 |
gl.last->x.test.failed = 1;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
printf ("not ok %d %s\n", gl.number, gl.last->x.test.name);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
va_start (va, message);
|
|
Packit Service |
6d40f9 |
if (vasprintf (&output, message, va) < 0)
|
|
Packit Service |
6d40f9 |
assert (0 && "vasprintf() failed");
|
|
Packit Service |
6d40f9 |
va_end (va);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (from = output; from != NULL; ) {
|
|
Packit Service |
6d40f9 |
next = strchr (from, '\n');
|
|
Packit Service |
6d40f9 |
if (next) {
|
|
Packit Service |
6d40f9 |
next[0] = '\0';
|
|
Packit Service |
6d40f9 |
next += 1;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
printf ("# %s\n", from);
|
|
Packit Service |
6d40f9 |
from = next;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
pos = strrchr (filename, '/');
|
|
Packit Service |
6d40f9 |
if (pos != NULL && pos[1] != '\0')
|
|
Packit Service |
6d40f9 |
filename = pos + 1;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
printf ("# in %s() at %s:%d\n", function, filename, line);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (output);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static void
|
|
Packit Service |
6d40f9 |
test_push (test_item *it)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
test_item *item;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
item = calloc (1, sizeof (test_item));
|
|
Packit Service |
6d40f9 |
assert (item != NULL);
|
|
Packit Service |
6d40f9 |
memcpy (item, it, sizeof (test_item));
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!gl.suite)
|
|
Packit Service |
6d40f9 |
gl.suite = item;
|
|
Packit Service |
6d40f9 |
if (gl.last)
|
|
Packit Service |
6d40f9 |
gl.last->next = item;
|
|
Packit Service |
6d40f9 |
gl.last = item;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
test_func (void (* function) (void),
|
|
Packit Service |
6d40f9 |
const char *name,
|
|
Packit Service |
6d40f9 |
...)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
test_item item = { TEST, };
|
|
Packit Service |
6d40f9 |
va_list va;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
item.x.test.func = (func_with_arg)function;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
va_start (va, name);
|
|
Packit Service |
6d40f9 |
vsnprintf (item.x.test.name, sizeof (item.x.test.name), name, va);
|
|
Packit Service |
6d40f9 |
va_end (va);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
test_push (&item);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
test_funcx (void (* function) (void *),
|
|
Packit Service |
6d40f9 |
void *argument,
|
|
Packit Service |
6d40f9 |
const char *name,
|
|
Packit Service |
6d40f9 |
...)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
test_item item = { TEST, };
|
|
Packit Service |
6d40f9 |
va_list va;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
item.type = TEST;
|
|
Packit Service |
6d40f9 |
item.x.test.func = function;
|
|
Packit Service |
6d40f9 |
item.x.test.argument = argument;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
va_start (va, name);
|
|
Packit Service |
6d40f9 |
vsnprintf (item.x.test.name, sizeof (item.x.test.name), name, va);
|
|
Packit Service |
6d40f9 |
va_end (va);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
test_push (&item);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
test_fixture (void (* setup) (void *),
|
|
Packit Service |
6d40f9 |
void (* teardown) (void *))
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
test_item item;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
item.type = FIXTURE;
|
|
Packit Service |
6d40f9 |
item.x.fix.setup = setup;
|
|
Packit Service |
6d40f9 |
item.x.fix.teardown = teardown;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
test_push (&item);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
int
|
|
Packit Service |
6d40f9 |
test_run (int argc,
|
|
Packit Service |
6d40f9 |
char **argv)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
test_item *fixture = NULL;
|
|
Packit Service |
6d40f9 |
test_item *item;
|
|
Packit Service |
6d40f9 |
test_item *next;
|
|
Packit Service |
6d40f9 |
int count;
|
|
Packit Service |
6d40f9 |
int ret = 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (gl.number == 0);
|
|
Packit Service |
6d40f9 |
gl.last = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (item = gl.suite, count = 0; item != NULL; item = item->next) {
|
|
Packit Service |
6d40f9 |
if (item->type == TEST)
|
|
Packit Service |
6d40f9 |
count++;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (count == 0) {
|
|
Packit Service |
6d40f9 |
printf ("1..0 # No tests\n");
|
|
Packit Service |
6d40f9 |
return 0;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
printf ("1..%d\n", count);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (item = gl.suite, gl.number = 0; item != NULL; item = item->next) {
|
|
Packit Service |
6d40f9 |
if (item->type == FIXTURE) {
|
|
Packit Service |
6d40f9 |
fixture = item;
|
|
Packit Service |
6d40f9 |
continue;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (item->type == TEST);
|
|
Packit Service |
6d40f9 |
gl.last = item;
|
|
Packit Service |
6d40f9 |
gl.number++;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (setjmp (gl.jump) == 0) {
|
|
Packit Service |
6d40f9 |
if (fixture && fixture->x.fix.setup)
|
|
Packit Service |
6d40f9 |
(fixture->x.fix.setup) (item->x.test.argument);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (item->x.test.func);
|
|
Packit Service |
6d40f9 |
(item->x.test.func)(item->x.test.argument);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (fixture && fixture->x.fix.teardown)
|
|
Packit Service |
6d40f9 |
(fixture->x.fix.teardown) (item->x.test.argument);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
printf ("ok %d %s\n", gl.number, item->x.test.name);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
gl.last = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (item = gl.suite; item != NULL; item = next) {
|
|
Packit Service |
6d40f9 |
if (item->type == TEST) {
|
|
Packit Service |
6d40f9 |
if (item->x.test.failed)
|
|
Packit Service |
6d40f9 |
ret++;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
next = item->next;
|
|
Packit Service |
6d40f9 |
free (item);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
gl.suite = NULL;
|
|
Packit Service |
6d40f9 |
gl.last = 0;
|
|
Packit Service |
6d40f9 |
gl.number = 0;
|
|
Packit Service |
6d40f9 |
return ret;
|
|
Packit Service |
6d40f9 |
}
|