#include "xbt/cunit.h"
#include "xbt/dynar.h"
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(testsuite,xbt,"Test infrastructure");
-
/* collection of all suites */
static xbt_dynar_t _xbt_test_suites = NULL;
/* global statistics */
static int _xbt_test_suite_ignore = 0;
+/* Context */
+xbt_test_unit_t _xbt_test_current_unit = NULL;
+
+
/* test suite test log */
typedef struct s_xbt_test_log {
char *text;
/* test suite */
struct s_xbt_test_suite {
+ const char *name;
char *title;
xbt_dynar_t units; /* of xbt_test_unit_t */
}
/** @brief create test suite */
-xbt_test_suite_t xbt_test_suite_new(const char *fmt, ...) {
+xbt_test_suite_t xbt_test_suite_new(const char *name, const char *fmt, ...) {
xbt_test_suite_t suite = xbt_new0(struct s_xbt_test_suite,1);
va_list ap;
vasprintf(&suite->title,fmt, ap);
suite->units = xbt_dynar_new(sizeof(xbt_test_unit_t), NULL);
va_end(ap);
+ suite->name=name;
xbt_dynar_push(_xbt_test_suites,&suite);
return suite;
}
+/** @brief retrieve a testsuite from name, or create a new one */
+xbt_test_suite_t xbt_test_suite_by_name(const char *name,const char *fmt, ...) {
+ xbt_test_suite_t suite;
+ int it_suite;
+
+ char *bufname;
+ va_list ap;
+
+ if (_xbt_test_suites)
+ xbt_dynar_foreach(_xbt_test_suites, it_suite, suite)
+ if (!strcmp(suite->name,name))
+ return suite;
+
+ va_start(ap, fmt);
+ vasprintf(&bufname,fmt, ap);
+ va_end(ap);
+ suite = xbt_test_suite_new(name,bufname,NULL);
+ free(bufname);
+
+ return suite;
+}
+
void xbt_test_suite_dump(xbt_test_suite_t suite) {
if (suite) {
xbt_test_unit_t unit;
char *cp;
int it_unit,it_test,it_log;
+ int first=1; /* for result pretty printing */
+
if (suite == NULL)
return 0;
- /* iterate through all tests to see how much failed */
- xbt_dynar_foreach(suite->units, it_unit, unit) {
- /* init unit case counters */
- unit->nb_tests = 0;
- unit->test_ignore = 0;
- unit->test_failed = 0;
- unit->test_expect = 0;
-
- /* run the test case function */
- unit->func(unit);
-
- /* iterate through all performed tests to determine status */
- xbt_dynar_foreach(unit->tests,it_test, test) {
- if (test->ignored) {
- unit->test_ignore++;
- } else {
- unit->nb_tests++;
-
- if ( test->failed && !test->expected_failure) unit->test_failed++;
- if (!test->failed && test->expected_failure) unit->test_failed++;
- if (test->expected_failure)
- unit->test_expect++;
- }
- }
-
- /* Accumulate test counts into the suite */
- suite->nb_tests += unit->nb_tests;
- suite->test_failed += unit->test_failed;
- suite->test_ignore += unit->test_ignore;
- suite->test_expect += unit->test_expect;
-
- _xbt_test_nb_tests += unit->nb_tests;
- _xbt_test_test_failed += unit->test_failed;
- _xbt_test_test_ignore += unit->test_ignore;
- _xbt_test_test_expect += unit->test_expect;
-
- /* What's the conclusion of this test anyway? */
- if (unit->nb_tests) {
- suite->nb_units++;
- if (unit->test_failed)
- suite->unit_failed++;
- } else {
- suite->unit_ignore++;
- }
- }
- _xbt_test_nb_units += suite->nb_units;
- _xbt_test_unit_failed += suite->unit_failed;
- _xbt_test_unit_ignore += suite->unit_ignore;
-
- if (suite->nb_units) {
- _xbt_test_nb_suites++;
- if (suite->test_failed)
- _xbt_test_suite_failed++;
- } else {
- _xbt_test_suite_ignore++;
- }
-
/* suite title pretty-printing */
{
char suite_title[80];
suite_title[i]='\0';
sprintf(suite_title + 40 - (suite_len+4)/2, "[ %s ]", suite->title);
- suite_title[40 + (suite_len+4)/2] = '=';
-
- fprintf(stderr, "\n%s %s\n",suite_title,
- (suite->nb_units?(suite->unit_failed?"FAILED":"OK"):"SKIP"));
-
+ suite_title[40 + (suite_len+5)/2] = '=';
+ fprintf(stderr, "\n%s\n",suite_title);
}
-
- /* iterate through all test cases to display details */
+
+ /* iterate through all tests */
xbt_dynar_foreach(suite->units, it_unit, unit) {
+ /* init unit case counters */
+ unit->nb_tests = 0;
+ unit->test_ignore = 0;
+ unit->test_failed = 0;
+ unit->test_expect = 0;
+
+ /* display unit title */
asprintf(&cp," Unit: %s ........................................"
"........................................", unit->title);
cp[72] = '\0';
fprintf(stderr, "%s", cp);
free(cp);
+
+ /* run the test case function */
+ _xbt_test_current_unit = unit;
+ unit->func();
+ /* iterate through all performed tests to determine status */
+ xbt_dynar_foreach(unit->tests,it_test, test) {
+ if (test->ignored) {
+ unit->test_ignore++;
+ } else {
+ unit->nb_tests++;
+
+ if ( test->failed && !test->expected_failure) unit->test_failed++;
+ if (!test->failed && test->expected_failure) unit->test_failed++;
+ if (test->expected_failure)
+ unit->test_expect++;
+ }
+ }
+
+ /* Display whether this unit went well */
if (unit->test_failed > 0 || unit->test_expect) {
/* some tests failed (or were supposed to), so do detailed reporting of test case */
if (unit->test_failed > 0) {
} else {
fprintf(stderr, ".. skip\n"); /* no test were run */
}
+
+
+
+
+ /* Accumulate test counts into the suite */
+ suite->nb_tests += unit->nb_tests;
+ suite->test_failed += unit->test_failed;
+ suite->test_ignore += unit->test_ignore;
+ suite->test_expect += unit->test_expect;
+
+ _xbt_test_nb_tests += unit->nb_tests;
+ _xbt_test_test_failed += unit->test_failed;
+ _xbt_test_test_ignore += unit->test_ignore;
+ _xbt_test_test_expect += unit->test_expect;
+
+ /* What's the conclusion of this test anyway? */
+ if (unit->nb_tests) {
+ suite->nb_units++;
+ if (unit->test_failed)
+ suite->unit_failed++;
+ } else {
+ suite->unit_ignore++;
+ }
+ }
+ _xbt_test_nb_units += suite->nb_units;
+ _xbt_test_unit_failed += suite->unit_failed;
+ _xbt_test_unit_ignore += suite->unit_ignore;
+
+ if (suite->nb_units) {
+ _xbt_test_nb_suites++;
+ if (suite->test_failed)
+ _xbt_test_suite_failed++;
+ } else {
+ _xbt_test_suite_ignore++;
}
+
/* print test suite summary */
- fprintf(stderr, " ==============================================================================\n");
+ fprintf(stderr,
+ " =======================================================================%s\n",
+ (suite->nb_units?(suite->unit_failed?" FAILED":"==== OK"):"== SKIP"));
fprintf(stderr, " Summary: Units: %.0f%% ok (%d units: ",
suite->nb_units?((1-(double)suite->unit_failed/(double)suite->nb_units)*100.0):100.0,
suite->nb_units);
- int first=1;
+
if (suite->nb_units != suite->unit_failed) {
fprintf(stderr, "%s%d ok",(first?"":", "),suite->nb_units - suite->unit_failed);
first = 0;
fprintf(stderr, "%s%d ignored",(first?"":", "),_xbt_test_suite_ignore);
first = 0;
}
- fprintf(stderr,")\n Units: %.0f%% ok (%d units: ",
+ fprintf(stderr,")\n Units: %.0f%% ok (%d units: ",
_xbt_test_nb_units?((1-(double)_xbt_test_unit_failed/(double)_xbt_test_nb_units)*100.0):100.0,
_xbt_test_nb_units);
first=1;
fprintf(stderr, "%s%d ignored",(first?"":", "),_xbt_test_unit_ignore);
first = 0;
}
- fprintf(stderr,")\n Tests: %.0f%% ok (%d tests: ",
+ fprintf(stderr,")\n Tests: %.0f%% ok (%d tests: ",
_xbt_test_nb_tests?((1-(double)_xbt_test_test_failed/(double)_xbt_test_nb_tests)*100.0):100.0,
_xbt_test_nb_tests);
first=1;
/* annotate test case with test */
-void _xbt_test(xbt_test_unit_t unit, const char*file,int line, const char *fmt, ...) {
+void _xbt_test_add(const char*file,int line, const char *fmt, ...) {
+ xbt_test_unit_t unit=_xbt_test_current_unit;
xbt_test_test_t test;
va_list ap;
}
/* annotate test case with log message and failure */
-void _xbt_test_fail(xbt_test_unit_t unit, const char*file,int line,const char *fmt, ...) {
+void _xbt_test_fail(const char*file,int line,const char *fmt, ...) {
+ xbt_test_unit_t unit = _xbt_test_current_unit;
xbt_test_test_t test;
xbt_test_log_t log;
va_list ap;
xbt_assert(unit);
xbt_assert(fmt);
+ xbt_assert1(xbt_dynar_length(_xbt_test_current_unit->tests),
+ "Test failed even before being declared (broken unit: %s)",
+ unit->title);
+
log = xbt_new(struct s_xbt_test_log,1);
va_start(ap, fmt);
vasprintf(&log->text,fmt, ap);
test->failed = 1;
}
-void _xbt_test_expect_failure(xbt_test_unit_t unit) {
- xbt_test_test_t test = xbt_dynar_getlast_as(unit->tests,xbt_test_test_t);
+void xbt_test_exception(xbt_ex_t e) {
+ _xbt_test_fail(e.file,e.line,"Exception %s raised: %s",xbt_ex_catname(e.category),e.msg);
+}
+
+void xbt_test_expect_failure(void) {
+ xbt_test_test_t test;
+ xbt_assert1(xbt_dynar_length(_xbt_test_current_unit->tests),
+ "Cannot expect the failure of a test before declaring it (broken unit: %s)",
+ _xbt_test_current_unit->title);
+ test = xbt_dynar_getlast_as(_xbt_test_current_unit->tests,xbt_test_test_t);
test->expected_failure = 1;
}
-void _xbt_test_skip(xbt_test_unit_t unit) {
- xbt_test_test_t test = xbt_dynar_getlast_as(unit->tests,xbt_test_test_t);
+void xbt_test_skip(void) {
+ xbt_test_test_t test;
+
+ xbt_assert1(xbt_dynar_length(_xbt_test_current_unit->tests),
+ "Test skiped even before being declared (broken unit: %s)",
+ _xbt_test_current_unit->title);
+
+ test = xbt_dynar_getlast_as(_xbt_test_current_unit->tests,
+ xbt_test_test_t);
test->ignored = 1;
}
/* annotate test case with log message only */
-void _xbt_test_log(xbt_test_unit_t unit, const char*file,int line,const char *fmt, ...) {
+void _xbt_test_log(const char*file,int line,const char *fmt, ...) {
+ xbt_test_unit_t unit=_xbt_test_current_unit;
xbt_test_test_t test;
xbt_test_log_t log;
va_list ap;
xbt_assert(unit);
xbt_assert(fmt);
+ xbt_assert1(xbt_dynar_length(_xbt_test_current_unit->tests),
+ "Test logged into even before being declared (broken test unit: %s)",unit->title);
+
log = xbt_new(struct s_xbt_test_log,1);
va_start(ap, fmt);
vasprintf(&log->text, fmt, ap);
xbt_dynar_push(test->logs, &log);
}
+
+
+
+#ifdef SIMGRID_TEST
+
+XBT_TEST_SUITE("cuint","Testsuite Autotest %d",0);
+
+XBT_TEST_UNIT("expect",test_expected_failure,"expected failures") {
+ xbt_test_add0("Skipped test");
+ xbt_test_skip();
+
+ xbt_test_add2("%s %s","EXPECTED","FAILURE");
+ xbt_test_expect_failure();
+ xbt_test_log2("%s %s","Test","log");
+ xbt_test_fail0("EXPECTED FAILURE");
+}
+
+#endif /* SIMGRID_TEST */