Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
retrive -> retrieve
[simgrid.git] / src / xbt / cunit.c
index 0f8b625..61bb023 100644 (file)
@@ -15,8 +15,6 @@
 #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 */
@@ -34,6 +32,10 @@ static int _xbt_test_suite_failed = 0;
 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;
@@ -107,6 +109,7 @@ static void xbt_test_unit_dump(xbt_test_unit_t unit) {
 
 /* test suite */
 struct s_xbt_test_suite {
+  const char *name;
   char       *title;
   xbt_dynar_t units; /* of xbt_test_unit_t */
 
@@ -127,7 +130,7 @@ static void xbt_test_suite_free(void *s) {
 }
 
 /** @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;
 
@@ -138,12 +141,35 @@ xbt_test_suite_t xbt_test_suite_new(const char *fmt, ...) {
   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;
@@ -189,66 +215,11 @@ static int xbt_test_suite_run(xbt_test_suite_t suite) {
   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];
@@ -264,21 +235,44 @@ static int xbt_test_suite_run(xbt_test_suite_t suite) {
     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) {
@@ -315,14 +309,51 @@ static int xbt_test_suite_run(xbt_test_suite_t suite) {
     } 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;
@@ -391,7 +422,7 @@ int xbt_test_run(void) {
       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;
@@ -407,7 +438,7 @@ int xbt_test_run(void) {
       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;
@@ -437,7 +468,8 @@ int xbt_test_run(void) {
 
 
 /* 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;
   
@@ -459,7 +491,8 @@ void _xbt_test(xbt_test_unit_t unit, const char*file,int line, const char *fmt,
 }
 
 /* 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;
@@ -467,6 +500,10 @@ void _xbt_test_fail(xbt_test_unit_t unit,  const char*file,int line,const char *
   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);
@@ -480,17 +517,33 @@ void _xbt_test_fail(xbt_test_unit_t unit,  const char*file,int line,const char *
   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;
@@ -498,6 +551,9 @@ void _xbt_test_log(xbt_test_unit_t unit, const char*file,int line,const char *fm
   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);
@@ -509,3 +565,21 @@ void _xbt_test_log(xbt_test_unit_t unit, const char*file,int line,const char *fm
   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 */