vaseboot/VasEBoot-core/tests/lib/test.c

240 lines
5.4 KiB
C

/*
* VasEBoot -- GRand Unified Bootloader
* Copyright (C) 2010 Free Software Foundation, Inc.
*
* VasEBoot is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VasEBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VasEBoot. If not, see <http://www.gnu.org/licenses/>.
*/
#include <VasEBoot/mm.h>
#include <VasEBoot/misc.h>
#include <VasEBoot/test.h>
struct VasEBoot_test_failure
{
/* The next failure. */
struct VasEBoot_test_failure *next;
struct VasEBoot_test_failure **prev;
/* The test source file name. */
char *file;
/* The test function name. */
char *funp;
/* The test call line number. */
VasEBoot_uint32_t line;
/* The test failure message. */
char *message;
};
typedef struct VasEBoot_test_failure *VasEBoot_test_failure_t;
VasEBoot_test_t VasEBoot_test_list;
static VasEBoot_test_failure_t failure_list;
static VasEBoot_test_failure_t
failure_start(const char *file, const char *funp, VasEBoot_uint32_t line);
static VasEBoot_test_failure_t
failure_start(const char *file, const char *funp, VasEBoot_uint32_t line)
{
VasEBoot_test_failure_t failure;
failure = (VasEBoot_test_failure_t) VasEBoot_malloc (sizeof (*failure));
if (!failure)
return NULL;
failure->file = VasEBoot_strdup (file ? : "<unknown_file>");
if (!failure->file)
{
VasEBoot_free(failure);
return NULL;
}
failure->funp = VasEBoot_strdup (funp ? : "<unknown_function>");
if (!failure->funp)
{
VasEBoot_free(failure->file);
VasEBoot_free(failure);
return NULL;
}
failure->line = line;
failure->message = NULL;
return failure;
}
static void
failure_append_vtext(VasEBoot_test_failure_t failure, const char *fmt, va_list args);
static void
failure_append_vtext(VasEBoot_test_failure_t failure, const char *fmt, va_list args)
{
char *msg = VasEBoot_xvasprintf(fmt, args);
if (failure->message)
{
char *oldmsg = failure->message;
failure->message = VasEBoot_xasprintf("%s%s", oldmsg, msg);
VasEBoot_free (oldmsg);
VasEBoot_free (msg);
}
else
{
failure->message = msg;
}
}
static void
failure_append_text(VasEBoot_test_failure_t failure, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
failure_append_vtext(failure, fmt, args);
va_end(args);
}
static void
add_failure (const char *file,
const char *funp,
VasEBoot_uint32_t line, const char *fmt, va_list args)
{
VasEBoot_test_failure_t failure = failure_start(file, funp, line);
failure_append_text(failure, fmt, args);
VasEBoot_list_push (VasEBoot_AS_LIST_P (&failure_list), VasEBoot_AS_LIST (failure));
}
static void
free_failures (void)
{
VasEBoot_test_failure_t item;
while (failure_list)
{
item = failure_list;
failure_list = item->next;
if (item->message)
VasEBoot_free (item->message);
if (item->funp)
VasEBoot_free (item->funp);
if (item->file)
VasEBoot_free (item->file);
VasEBoot_free (item);
}
failure_list = 0;
}
void
VasEBoot_test_nonzero (int cond,
const char *file,
const char *funp, VasEBoot_uint32_t line, const char *fmt, ...)
{
va_list ap;
if (cond)
return;
va_start (ap, fmt);
add_failure (file, funp, line, fmt, ap);
va_end (ap);
}
void
VasEBoot_test_assert_helper (int cond, const char *file, const char *funp,
VasEBoot_uint32_t line, const char *condstr,
const char *fmt, ...)
{
va_list ap;
VasEBoot_test_failure_t failure;
if (cond)
return;
failure = failure_start(file, funp, line);
failure_append_text(failure, "assert failed: %s ", condstr);
va_start(ap, fmt);
failure_append_vtext(failure, fmt, ap);
va_end(ap);
VasEBoot_list_push (VasEBoot_AS_LIST_P (&failure_list), VasEBoot_AS_LIST (failure));
}
void
VasEBoot_test_register (const char *name, void (*test_main) (void))
{
VasEBoot_test_t test;
test = (VasEBoot_test_t) VasEBoot_malloc (sizeof (*test));
if (!test)
return;
test->name = VasEBoot_strdup (name);
test->main = test_main;
VasEBoot_list_push (VasEBoot_AS_LIST_P (&VasEBoot_test_list), VasEBoot_AS_LIST (test));
}
void
VasEBoot_test_unregister (const char *name)
{
VasEBoot_test_t test;
test = (VasEBoot_test_t) VasEBoot_named_list_find
(VasEBoot_AS_NAMED_LIST (VasEBoot_test_list), name);
if (test)
{
VasEBoot_list_remove (VasEBoot_AS_LIST (test));
if (test->name)
VasEBoot_free (test->name);
VasEBoot_free (test);
}
}
int
VasEBoot_test_run (VasEBoot_test_t test)
{
VasEBoot_test_failure_t failure;
test->main ();
VasEBoot_printf ("%s:\n", test->name);
FOR_LIST_ELEMENTS (failure, failure_list)
VasEBoot_printf (" %s:%s:%u: %s\n",
(failure->file ? : "<unknown_file>"),
(failure->funp ? : "<unknown_function>"),
failure->line, (failure->message ? : "<no message>"));
if (!failure_list)
{
VasEBoot_printf ("%s: PASS\n", test->name);
return VasEBoot_ERR_NONE;
}
else
{
VasEBoot_printf ("%s: FAIL\n", test->name);
free_failures ();
return VasEBoot_ERR_TEST_FAILURE;
}
}