Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Rename testsuite to cunit (more sexy name); integrate it properly into SimGrid; use...
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Sat, 22 Oct 2005 22:45:23 +0000 (22:45 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Sat, 22 Oct 2005 22:45:23 +0000 (22:45 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@1800 48e7efb5-ca39-0410-a469-dd3cf9ba447f

ChangeLog
include/xbt.h
include/xbt/cunit.h [new file with mode: 0644]
include/xbt/testsuite.h [deleted file]
src/Makefile.am
src/xbt/cunit.c [new file with mode: 0644]
src/xbt/testsuite.c [deleted file]
testsuite/xbt/ex_test.c

index 0f61356..7e4d312 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,8 @@
 SimGrid (3.0.2) unstable; urgency=low
 
   XBT:
 SimGrid (3.0.2) unstable; urgency=low
 
   XBT:
-  * New module: testsuite [MQ]
+  * New module: cunit [MQ]
+  * New functions: xbt_dynar_getfirst_as() and xbt_dynar_getlast_as() [MQ]
 
  --
 
 
  --
 
index 75ef4df..64fbbc4 100644 (file)
@@ -25,6 +25,6 @@
 #include <xbt/heap.h>
 
 #include <xbt/config.h>
 #include <xbt/heap.h>
 
 #include <xbt/config.h>
-#include <xbt/testsuite.h>
+#include <xbt/cunit.h>
 
 #endif /* xbt_H */
 
 #endif /* xbt_H */
diff --git a/include/xbt/cunit.h b/include/xbt/cunit.h
new file mode 100644 (file)
index 0000000..bdffc53
--- /dev/null
@@ -0,0 +1,71 @@
+/* $Id$ */
+
+/* cunit - A little C Unit facility                                         */
+
+/* Copyright (c) 2005 Martin Quinson. All rights reserved.                  */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+/* This is partially inspirated from the OSSP ts (Test Suite Library)       */
+
+#ifndef _XBT_CUNIT_H_
+#define _XBT_CUNIT_H_
+
+#include "xbt/sysdep.h"    /* XBT_GNU_PRINTF */
+
+/* test suite object type */
+typedef struct s_xbt_test_suite *xbt_test_suite_t;
+
+/* test object type */
+typedef struct s_xbt_test_unit *xbt_test_unit_t;
+
+/* test callback function type */
+typedef void (*ts_test_cb_t)(xbt_test_unit_t);
+
+/* test suite operations */
+xbt_test_suite_t xbt_test_suite_new  (const char *fmt, ...);
+void             xbt_test_suite_dump (xbt_test_suite_t suite);
+void             xbt_test_suite_push (xbt_test_suite_t suite, 
+                                     ts_test_cb_t func, const char *fmt, ...);
+
+int xbt_test_run  (void);
+
+
+/* test operations */
+void    _xbt_test(xbt_test_unit_t u, const char*file,int line, const char *fmt, ...)_XBT_GNUC_PRINTF(4,5);
+#define xbt_test0(fmt)           _xbt_test(_unit,__FILE__,__LINE__,fmt)
+#define xbt_test1(fmt,a)         _xbt_test(_unit,__FILE__,__LINE__,fmt,a)
+#define xbt_test2(fmt,a,b)       _xbt_test(_unit,__FILE__,__LINE__,fmt,a,b)
+#define xbt_test3(fmt,a,b,c)     _xbt_test(_unit,__FILE__,__LINE__,fmt,a,b,c)
+#define xbt_test4(fmt,a,b,c,d)   _xbt_test(_unit,__FILE__,__LINE__,fmt,a,b,c,d)
+#define xbt_test5(fmt,a,b,c,d,e) _xbt_test(_unit,__FILE__,__LINE__,fmt,a,b,c,d,e)
+
+void    _xbt_test_fail(xbt_test_unit_t u, const char*file,int line, const char *fmt, ...) _XBT_GNUC_PRINTF(4,5);
+#define xbt_test_fail0(fmt)           _xbt_test_fail(_unit, __FILE__, __LINE__, fmt)
+#define xbt_test_fail1(fmt,a)         _xbt_test_fail(_unit, __FILE__, __LINE__, fmt,a)
+#define xbt_test_fail2(fmt,a,b)       _xbt_test_fail(_unit, __FILE__, __LINE__, fmt,a,b)
+#define xbt_test_fail3(fmt,a,b,c)     _xbt_test_fail(_unit, __FILE__, __LINE__, fmt,a,b,c)
+#define xbt_test_fail4(fmt,a,b,c,d)   _xbt_test_fail(_unit, __FILE__, __LINE__, fmt,a,b,c,d)
+#define xbt_test_fail5(fmt,a,b,c,d,e) _xbt_test_fail(_unit, __FILE__, __LINE__, fmt,a,b,c,d,e)
+
+void    _xbt_test_log (xbt_test_unit_t u, const char*file,int line, const char *fmt, ...)_XBT_GNUC_PRINTF(4,5);
+#define xbt_test_log0(fmt)           _xbt_test_log(_unit, __FILE__, __LINE__, fmt)
+#define xbt_test_log1(fmt,a)         _xbt_test_log(_unit, __FILE__, __LINE__, fmt,a)
+#define xbt_test_log2(fmt,a,b)       _xbt_test_log(_unit, __FILE__, __LINE__, fmt,a,b)
+#define xbt_test_log3(fmt,a,b,c)     _xbt_test_log(_unit, __FILE__, __LINE__, fmt,a,b,c)
+#define xbt_test_log4(fmt,a,b,c,d)   _xbt_test_log(_unit, __FILE__, __LINE__, fmt,a,b,c,d)
+#define xbt_test_log5(fmt,a,b,c,d,e) _xbt_test_log(_unit, __FILE__, __LINE__, fmt,a,b,c,d,e)
+
+void _xbt_test_expect_failure(xbt_test_unit_t unit);
+#define    xbt_test_expect_failure() _xbt_test_expect_failure(_unit)
+
+void _xbt_test_skip(xbt_test_unit_t unit);
+#define    xbt_test_skip() _xbt_test_skip(_unit)
+
+/* test suite short-cut macros */
+#define XBT_TEST_UNIT(name) \
+    static void name(xbt_test_unit_t _unit)
+
+#endif /* _TS_H_ */
+
diff --git a/include/xbt/testsuite.h b/include/xbt/testsuite.h
deleted file mode 100644 (file)
index 8d01123..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-**  OSSP ts - Test Suite Library
-**  Copyright (c) 2001-2004 Ralf S. Engelschall <rse@engelschall.com>
-**  Copyright (c) 2001-2004 The OSSP Project <http://www.ossp.org/>
-**  Copyright (c) 2001-2004 Cable & Wireless <http://www.cw.com/>
-**
-**  This file is part of OSSP ts, a small test suite library which
-**  can be found at http://www.ossp.org/pkg/lib/ts/.
-**
-**  Permission to use, copy, modify, and distribute this software for
-**  any purpose with or without fee is hereby granted, provided that
-**  the above copyright notice and this permission notice appear in all
-**  copies.
-**
-**  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
-**  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-**  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-**  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
-**  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-**  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-**  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-**  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-**  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-**  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-**  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-**  SUCH DAMAGE.
-**
-**  ts.h: test suite library API
-*/
-
-#ifndef _TS_H_
-#define _TS_H_
-
-/* test suite object type */
-struct ts_suite_st;
-typedef struct ts_suite_st ts_suite_t;
-
-/* test object type */
-struct ts_test_st;
-typedef struct ts_test_st ts_test_t;
-
-/* test callback function type */
-typedef void (*ts_test_cb_t)(ts_test_t *);
-
-/* test suite operations */
-ts_suite_t *ts_suite_new  (const char *fmt, ...);
-void        ts_suite_test (ts_suite_t *s, ts_test_cb_t func, const char *fmt, ...);
-int         ts_suite_run  (ts_suite_t *s);
-void        ts_suite_free (ts_suite_t *s);
-
-/* test operations */
-ts_test_t  *ts_test_ctx   (ts_test_t *t, const char *file, int line);
-void        ts_test_check (ts_test_t *t, const char *fmt, ...);
-void        ts_test_fail  (ts_test_t *t, const char *fmt, ...);
-void        ts_test_log   (ts_test_t *t, const char *fmt, ...);
-
-/* test suite short-cut macros */
-#define TS_TEST(name) \
-    static void name(ts_test_t *_t)
-#define TS_CTX \
-    ts_test_ctx(_t, __FILE__, __LINE__)
-
-#endif /* _TS_H_ */
-
index 09ca7f5..ddf0471 100644 (file)
@@ -114,7 +114,7 @@ COMMON_SRC=\
   xbt/set.c                                                                  \
   xbt/module.c                                                               \
   xbt/config.c                                                               \
   xbt/set.c                                                                  \
   xbt/module.c                                                               \
   xbt/config.c                                                               \
-  xbt/testsuite.c                                                            \
+  xbt/cunit.c                                                                \
   \
   gras/gras.c \
   \
   \
   gras/gras.c \
   \
diff --git a/src/xbt/cunit.c b/src/xbt/cunit.c
new file mode 100644 (file)
index 0000000..0f8b625
--- /dev/null
@@ -0,0 +1,511 @@
+/* $Id$ */
+
+/* cunit - A little C Unit facility                                         */
+
+/* Copyright (c) 2005 Martin Quinson. All rights reserved.                  */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+/* This is partially inspirated from the OSSP ts (Test Suite Library)       */
+
+#include "gras_config.h"
+
+#include "xbt/sysdep.h"    /* vasprintf */
+#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_nb_tests = 0;
+static int _xbt_test_test_failed = 0;
+static int _xbt_test_test_ignore = 0;
+static int _xbt_test_test_expect = 0;
+
+static int _xbt_test_nb_units    = 0;
+static int _xbt_test_unit_failed = 0;
+static int _xbt_test_unit_ignore = 0;
+
+static int _xbt_test_nb_suites    = 0;
+static int _xbt_test_suite_failed = 0;
+static int _xbt_test_suite_ignore = 0;
+
+
+/* test suite test log */
+typedef struct s_xbt_test_log {
+  char              *text;
+  const char        *file;
+  int                line;
+} *xbt_test_log_t;
+
+static void xbt_test_log_dump(xbt_test_log_t log) {
+  if (log)
+    fprintf(stderr,"      log %p(%s:%d)=%s\n",log,log->file,log->line,log->text);
+  else
+    fprintf(stderr,"      log=NULL\n");           
+}
+static void xbt_test_log_free(xbt_test_log_t log) {
+  if (!log)
+    return;
+  if (log->text)
+    free(log->text);
+  free(log);
+}
+
+/* test suite test check */
+typedef struct s_xbt_test_test {
+  char        *title;
+  int          failed;
+  int          expected_failure;
+  int          ignored;
+  const char  *file;
+  int          line;
+  xbt_dynar_t  logs;
+} *xbt_test_test_t;
+
+static void xbt_test_test_dump(xbt_test_test_t test){
+  if (test) {
+    xbt_test_log_t log;
+    int it_log;
+    fprintf(stderr,"    test %p(%s:%d)=%s (%s)\n",
+           test,test->file,test->line,test->title,
+           test->failed?"failed":"not failed");
+    xbt_dynar_foreach(test->logs,it_log,log)
+      xbt_test_log_dump(log);
+  }
+  else
+    fprintf(stderr,"    test=NULL\n");    
+}
+
+/* test suite test unit */
+struct s_xbt_test_unit {
+  char        *title;
+  ts_test_cb_t func;
+  const char  *file;
+  int          line;
+  xbt_dynar_t  tests; /* of xbt_test_test_t*/
+
+  int nb_tests;
+  int test_failed,test_ignore,test_expect;
+};
+
+static void xbt_test_unit_dump(xbt_test_unit_t unit) {
+  if (unit) {
+    xbt_test_test_t test;
+    int it_test;
+    fprintf(stderr,"  unit %p(%s:%d)=%s (func=%p)\n",
+           unit,unit->file,unit->line,unit->title,unit->file);
+    xbt_dynar_foreach(unit->tests,it_test,test)
+      xbt_test_test_dump(test);
+  } else {
+    fprintf(stderr,"  unit=NULL\n");
+  }
+}
+
+/* test suite */
+struct s_xbt_test_suite {
+  char       *title;
+  xbt_dynar_t units; /* of xbt_test_unit_t */
+
+  int nb_tests,nb_units;
+  int test_failed,test_ignore,test_expect;
+  int unit_failed,unit_ignore;
+};
+
+/* destroy test suite */
+static void xbt_test_suite_free(void *s) {
+  xbt_test_suite_t suite = *(xbt_test_suite_t*) s;
+
+  if (suite == NULL)
+    return;
+  xbt_dynar_free(&suite->units);
+  free(suite->title);
+  free(suite);
+}
+
+/** @brief create test suite */
+xbt_test_suite_t xbt_test_suite_new(const char *fmt, ...) {
+  xbt_test_suite_t suite = xbt_new0(struct s_xbt_test_suite,1);
+  va_list ap;
+
+  if (!_xbt_test_suites) 
+    _xbt_test_suites = xbt_dynar_new(sizeof(xbt_test_suite_t),&xbt_test_suite_free);
+
+  va_start(ap, fmt);
+  vasprintf(&suite->title,fmt, ap);
+  suite->units = xbt_dynar_new(sizeof(xbt_test_unit_t), NULL);
+  va_end(ap);
+
+  xbt_dynar_push(_xbt_test_suites,&suite);
+
+  return suite;
+}
+
+void xbt_test_suite_dump(xbt_test_suite_t suite) {
+  if (suite) {
+    xbt_test_unit_t unit;
+    int it_unit;
+    fprintf(stderr,"DUMP suite %s\n",suite->title);
+    xbt_dynar_foreach(suite->units,it_unit,unit)
+      xbt_test_unit_dump(unit);
+  } else {
+    fprintf(stderr,"suite=NULL\n");
+  }
+}
+
+/* add test case to test suite */
+void xbt_test_suite_push(xbt_test_suite_t suite, ts_test_cb_t func, const char *fmt, ...) {
+  xbt_test_unit_t unit;
+  va_list ap;
+  
+  xbt_assert(suite);
+  xbt_assert(func);
+  xbt_assert(fmt);
+
+  unit = xbt_new(struct s_xbt_test_unit,1);
+  va_start(ap, fmt);
+  vasprintf(&unit->title, fmt, ap);
+  va_end(ap);
+  unit->func = func;
+  unit->file = NULL;
+  unit->line = 0;
+  unit->tests = xbt_dynar_new(sizeof(xbt_test_test_t), NULL);
+  
+  xbt_dynar_push(suite->units, &unit);
+  return;
+}
+
+/* run test one suite */
+static int xbt_test_suite_run(xbt_test_suite_t suite) {
+  xbt_test_unit_t unit;
+  xbt_test_test_t test;
+  xbt_test_log_t log;
+
+  const char *file;
+  int line;
+  char *cp;
+  int it_unit,it_test,it_log;
+
+  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];
+    int suite_len=strlen(suite->title);
+    int i;
+
+    xbt_assert2(suite_len<70,"suite title \"%s\" too long (%d should be less than 70",
+               suite->title,suite_len);
+    
+    suite_title[0]=' ';
+    for (i=1;i<79;i++)
+      suite_title[i]='=';
+    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"));
+    
+  }
+  
+  /* iterate through all test cases to display details */
+  xbt_dynar_foreach(suite->units, it_unit, unit) {
+    asprintf(&cp," Unit: %s ........................................"
+            "........................................", unit->title);
+    cp[72] = '\0';
+    fprintf(stderr, "%s", cp);
+    free(cp);
+    
+    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) {
+       fprintf(stderr, " failed\n");
+      } else if (unit->nb_tests) {
+       fprintf(stderr, ".... ok\n"); /* successful, but show about expected */
+      } else {
+       fprintf(stderr, ".. skip\n"); /* shouldn't happen, but I'm a bit lost with this logic */
+      }
+      xbt_dynar_foreach(unit->tests,it_test, test) {
+       file = (test->file != NULL ? test->file : unit->file);
+       line = (test->line != 0    ? test->line : unit->line);
+       fprintf(stderr, "      %s: %s [%s:%d]\n", 
+               (test->ignored?" SKIP":(test->expected_failure?(test->failed?"EFAIL":"EPASS"):
+                                                                (test->failed?" FAIL":" PASS"))),
+               test->title, file, line);
+
+       xbt_dynar_foreach(test->logs,it_log,log) {
+         file = (log->file != NULL ? log->file : file);
+         line = (log->line != 0    ? log->line : line);
+           fprintf(stderr, "             %s:%d: %s\n", 
+                   file, line,log->text);
+
+       }
+      }
+      fprintf(stderr, "    Summary: %d of %d tests failed",unit->test_failed, unit->nb_tests);
+      if (unit->test_ignore) {
+       fprintf(stderr," (%d tests ignored)\n",unit->test_ignore);
+      } else {
+       fprintf(stderr,"\n");
+      }
+    } else if (unit->nb_tests) {
+      fprintf(stderr, ".... ok\n"); /* successful */
+    } else {
+      fprintf(stderr, ".. skip\n"); /* no test were run */
+    }
+  }
+  
+  /* print test suite summary */
+  fprintf(stderr, " ==============================================================================\n");
+  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;
+  }
+  if (suite->unit_failed) {
+    fprintf(stderr, "%s%d failed",(first?"":", "),suite->unit_failed);
+    first = 0;
+  }
+  if (suite->unit_ignore) {
+    fprintf(stderr, "%s%d ignored",(first?"":", "),suite->unit_ignore);
+    first = 0;
+  }
+  fprintf(stderr,")\n          Tests: %.0f%% ok (%d tests: ",
+         suite->nb_tests?((1-(double)suite->test_failed/(double)suite->nb_tests)*100.0):100.0,
+         suite->nb_tests);
+
+  first=1;
+  if (suite->nb_tests != suite->test_failed) {
+    fprintf(stderr, "%s%d ok",(first?"":", "),suite->nb_tests - suite->test_failed);
+    first = 0;
+  }
+  if (suite->test_failed) {
+    fprintf(stderr, "%s%d failed",(first?"":", "),suite->test_failed);
+    first = 0;
+  }
+  if (suite->test_ignore) {
+    fprintf(stderr, "%s%d ignored",(first?"":"; "),suite->test_ignore);
+    first = 0;
+  }
+  if (suite->test_expect) {
+    fprintf(stderr, "%s%d expected to fail",(first?"":"; "),suite->test_expect);
+    first = 0;
+  }
+  fprintf(stderr,")\n");
+
+  return suite->unit_failed;
+}
+
+int xbt_test_run(void) {
+  
+  if (_xbt_test_suites) {
+    int it_suite;
+    xbt_test_suite_t suite;
+    int first=1;
+    
+    /* Run all the suites */
+    xbt_dynar_foreach(_xbt_test_suites,it_suite,suite) 
+      xbt_test_suite_run(suite);
+
+    /* Display some more statistics */
+    fprintf(stderr,"\n\n TOTAL: Suites: %.0f%% ok (%d suites: ",
+           _xbt_test_nb_suites
+             ? ((1-(double)_xbt_test_suite_failed/(double)_xbt_test_nb_suites)*100.0)
+             : 100.0,
+           _xbt_test_nb_suites);
+    if (_xbt_test_nb_suites != _xbt_test_suite_failed) {
+      fprintf(stderr, "%d ok",_xbt_test_nb_suites - _xbt_test_suite_failed);
+      first = 0;
+    }
+    if (_xbt_test_suite_failed) {
+      fprintf(stderr, "%s%d failed",(first?"":", "),_xbt_test_suite_failed);
+      first = 0;
+    }
+    
+    if (_xbt_test_suite_ignore) {
+      fprintf(stderr, "%s%d ignored",(first?"":", "),_xbt_test_suite_ignore);
+      first = 0;
+    }
+    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;
+    if (_xbt_test_nb_units != _xbt_test_unit_failed) {
+      fprintf(stderr, "%s%d ok",(first?"":", "),_xbt_test_nb_units - _xbt_test_unit_failed);
+      first = 0;
+    }
+    if (_xbt_test_unit_failed) {
+      fprintf(stderr, "%s%d failed",(first?"":", "),_xbt_test_unit_failed);
+      first = 0;
+    }
+    if (_xbt_test_unit_ignore) {
+      fprintf(stderr, "%s%d ignored",(first?"":", "),_xbt_test_unit_ignore);
+      first = 0;
+    }
+    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;
+    if (_xbt_test_nb_tests != _xbt_test_test_failed) {
+      fprintf(stderr, "%s%d ok",(first?"":", "),_xbt_test_nb_tests - _xbt_test_test_failed);
+      first = 0;
+    }
+    if (_xbt_test_test_failed) {
+      fprintf(stderr, "%s%d failed",(first?"":", "),_xbt_test_test_failed);
+      first = 0;
+    }
+    if (_xbt_test_test_ignore) {
+      fprintf(stderr, "%s%d ignored",(first?"":", "),_xbt_test_test_ignore);
+      first = 0;
+    }
+    if (_xbt_test_test_expect) {
+      fprintf(stderr, "%s%d expected to fail",(first?"":", "),_xbt_test_test_expect);
+    }
+    
+    fprintf(stderr,")\n");
+  } else {
+    fprintf(stderr,"No unit to run!\n");
+    _xbt_test_unit_failed++;
+  }
+  return _xbt_test_unit_failed;
+}
+
+
+/* annotate test case with test */
+void _xbt_test(xbt_test_unit_t unit, const char*file,int line, const char *fmt, ...) {
+  xbt_test_test_t test;
+  va_list ap;
+  
+  xbt_assert(unit);
+  xbt_assert(fmt);
+
+  test = xbt_new(struct s_xbt_test_test,1);
+  va_start(ap, fmt);
+  vasprintf(&test->title, fmt, ap);
+  va_end(ap);
+  test->failed = 0;
+  test->expected_failure = 0;
+  test->ignored = 0;
+  test->file = file;
+  test->line = line;
+  test->logs = xbt_dynar_new(sizeof(xbt_test_log_t),NULL);
+  xbt_dynar_push(unit->tests,&test);
+  return;
+}
+
+/* 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, ...) {
+  xbt_test_test_t test;
+  xbt_test_log_t log;
+  va_list ap;
+  
+  xbt_assert(unit);
+  xbt_assert(fmt);
+
+  log = xbt_new(struct s_xbt_test_log,1);
+  va_start(ap, fmt);
+  vasprintf(&log->text,fmt, ap);
+  va_end(ap);
+  log->file = file;
+  log->line = line;
+
+  test = xbt_dynar_getlast_as(unit->tests, xbt_test_test_t);
+  xbt_dynar_push(test->logs, &log);
+
+  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);
+  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);
+  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, ...) {
+  xbt_test_test_t test;
+  xbt_test_log_t log;
+  va_list ap;
+
+  xbt_assert(unit);
+  xbt_assert(fmt);
+
+  log = xbt_new(struct s_xbt_test_log,1);
+  va_start(ap, fmt);
+  vasprintf(&log->text, fmt, ap);
+  va_end(ap);
+  log->file = file;
+  log->line = line;
+
+  test = xbt_dynar_getlast_as(unit->tests,xbt_test_test_t);
+  xbt_dynar_push(test->logs, &log);
+}
+
diff --git a/src/xbt/testsuite.c b/src/xbt/testsuite.c
deleted file mode 100644 (file)
index bc872ba..0000000
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
-**  OSSP ts - Test Suite Library
-**  Copyright (c) 2001-2004 Ralf S. Engelschall <rse@engelschall.com>
-**  Copyright (c) 2001-2004 The OSSP Project <http://www.ossp.org/>
-**  Copyright (c) 2001-2004 Cable & Wireless <http://www.cw.com/>
-**
-**  This file is part of OSSP ts, a small test suite library which
-**  can be found at http://www.ossp.org/pkg/lib/ts/.
-**
-**  Permission to use, copy, modify, and distribute this software for
-**  any purpose with or without fee is hereby granted, provided that
-**  the above copyright notice and this permission notice appear in all
-**  copies.
-**
-**  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
-**  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-**  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-**  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
-**  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-**  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-**  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-**  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-**  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-**  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-**  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-**  SUCH DAMAGE.
-**
-**  ts.c: test suite library
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include "gras_config.h"
-
-#include "xbt/testsuite.h"
-
-/* embedded ring data structure library */
-#define RING_ENTRY(elem) \
-    struct { elem *next; elem *prev; }
-#define RING_HEAD(elem) \
-    struct { elem *next; elem *prev; }
-#define RING_SENTINEL(hp, elem, link) \
-    (elem *)((char *)(hp) - ((size_t)(&((elem *)0)->link)))
-#define RING_FIRST(hp) \
-    (hp)->next
-#define RING_LAST(hp) \
-    (hp)->prev
-#define RING_NEXT(ep, link) \
-    (ep)->link.next
-#define RING_PREV(ep, link) \
-    (ep)->link.prev
-#define RING_INIT(hp, elem, link) \
-    do { RING_FIRST((hp)) = RING_SENTINEL((hp), elem, link); \
-         RING_LAST((hp))  = RING_SENTINEL((hp), elem, link); } while (0)
-#define RING_EMPTY(hp, elem, link) \
-    (RING_FIRST((hp)) == RING_SENTINEL((hp), elem, link))
-#define RING_ELEM_INIT(ep, link) \
-    do { RING_NEXT((ep), link) = (ep); \
-         RING_PREV((ep), link) = (ep); } while (0)
-#define RING_SPLICE_BEFORE(lep, ep1, epN, link) \
-    do { RING_NEXT((epN), link) = (lep); \
-         RING_PREV((ep1), link) = RING_PREV((lep), link); \
-         RING_NEXT(RING_PREV((lep), link), link) = (ep1); \
-         RING_PREV((lep), link) = (epN); } while (0)
-#define RING_SPLICE_TAIL(hp, ep1, epN, elem, link) \
-    RING_SPLICE_BEFORE(RING_SENTINEL((hp), elem, link), (ep1), (epN), link)
-#define RING_INSERT_TAIL(hp, nep, elem, link) \
-    RING_SPLICE_TAIL((hp), (nep), (nep), elem, link)
-#define RING_FOREACH(ep, hp, elem, link) \
-    for ((ep)  = RING_FIRST((hp)); \
-         (ep) != RING_SENTINEL((hp), elem, link); \
-         (ep)  = RING_NEXT((ep), link))
-#define RING_FOREACH_LA(ep, epT, hp, elem, link) \
-    for ((ep)  = RING_FIRST((hp)), (epT) = RING_NEXT((ep), link); \
-         (ep) != RING_SENTINEL((hp), elem, link); \
-         (ep)  = (epT), (epT) = RING_NEXT((epT), link))
-
-/* test suite test log */
-struct tstl_st;
-typedef struct tstl_st tstl_t;
-struct tstl_st {
-    RING_ENTRY(tstl_t) next;
-    char              *text;
-    const char        *file;
-    int                line;
-};
-
-/* test suite test check */
-struct tstc_st;
-typedef struct tstc_st tstc_t;
-struct tstc_st {
-    RING_ENTRY(tstc_t) next;
-    char              *title;
-    int                failed;
-    const char        *file;
-    int                line;
-    RING_HEAD(tstl_t)  logs;
-};
-
-/* test suite test */
-struct ts_test_st {
-    RING_ENTRY(ts_test_t)  next;
-    char              *title;
-    ts_test_cb_t         func;
-    const char        *file;
-    int                line;
-    RING_HEAD(tstc_t)  checks;
-};
-
-/* test suite */
-struct ts_suite_st {
-    char              *title;
-    RING_HEAD(ts_test_t)   tests;
-};
-
-/* minimal output-independent vprintf(3) variant which supports %{c,s,d,%} only */
-static int ts_suite_mvxprintf(char *buffer, size_t bufsize, const char *format, va_list ap)
-{
-    /* sufficient integer buffer: <available-bits> x log_10(2) + safety */
-    char ibuf[((sizeof(int)*8)/3)+10]; 
-    char *cp;
-    char c;
-    int d;
-    int n;
-    int bytes;
-
-    if (format == NULL)
-        return -1;
-    bytes = 0;
-    while (*format != '\0') {
-        if (*format == '%') {
-            c = *(format+1);
-            if (c == '%') {
-                /* expand "%%" */
-                cp = &c;
-                n = sizeof(char);
-            }
-            else if (c == 'c') {
-                /* expand "%c" */
-                c = (char)va_arg(ap, int);
-                cp = &c;
-                n = sizeof(char);
-            }
-            else if (c == 's') {
-                /* expand "%s" */
-                if ((cp = (char *)va_arg(ap, char *)) == NULL)
-                    cp = (char*)"(null)";
-                n = strlen(cp);
-            }
-            else if (c == 'd') {
-                /* expand "%d" */
-                d = (int)va_arg(ap, int);
-#ifdef HAVE_SNPRINTF
-                snprintf(ibuf, sizeof(ibuf), "%d", d); /* explicitly secure */
-#else
-                sprintf(ibuf, "%d", d);                /* implicitly secure */
-#endif
-                cp = ibuf;
-                n = strlen(cp);
-            }
-            else {
-                /* any other "%X" */
-                cp = (char *)format;
-                n  = 2;
-            }
-            format += 2;
-        }
-        else {
-            /* plain text */
-            cp = (char *)format;
-            if ((format = strchr(cp, '%')) == NULL)
-                format = strchr(cp, '\0');
-            n = format - cp;
-        }
-        /* perform output operation */
-        if (buffer != NULL) {
-            if (n > bufsize)
-                return -1;
-            memcpy(buffer, cp, n);
-            buffer  += n;
-            bufsize -= n;
-        }
-        bytes += n;
-    }
-    /* nul-terminate output */
-    if (buffer != NULL) {
-        if (bufsize == 0)
-            return -1;
-        *buffer = '\0';
-    }
-    return bytes;
-}
-
-/* minimal vasprintf(3) variant which supports %{c,s,d} only */
-static char *ts_suite_mvasprintf(const char *format, va_list ap)
-{
-    char *buffer;
-    int n;
-    va_list ap2;
-
-    if (format == NULL)
-        return NULL;
-    va_copy(ap2, ap);
-    if ((n = ts_suite_mvxprintf(NULL, 0, format, ap)) == -1)
-        return NULL;
-    if ((buffer = (char *)malloc(n+1)) == NULL)
-        return NULL;
-    ts_suite_mvxprintf(buffer, n+1, format, ap2);
-    return buffer;
-}
-
-/* minimal asprintf(3) variant which supports %{c,s,d} only */
-static char *ts_suite_masprintf(const char *format, ...)
-{
-    va_list ap;
-    char *cp;
-
-    va_start(ap, format);
-    cp = ts_suite_mvasprintf(format, ap);
-    va_end(ap);
-    return cp;
-}
-
-/* create test suite */
-ts_suite_t *ts_suite_new(const char *fmt, ...)
-{
-    ts_suite_t *ts;
-    va_list ap;
-
-    if ((ts = (ts_suite_t *)malloc(sizeof(ts_suite_t))) == NULL)
-        return NULL;
-    va_start(ap, fmt);
-    ts->title = ts_suite_mvasprintf(fmt, ap);
-    RING_INIT(&ts->tests, ts_test_t, next);
-    va_end(ap);
-    return ts;
-}
-
-/* add test case to test suite */
-void ts_suite_test(ts_suite_t *ts, ts_test_cb_t func, const char *fmt, ...)
-{
-    ts_test_t *tst;
-    va_list ap;
-
-    if (ts == NULL || func == NULL || fmt == NULL)
-        return;
-    if ((tst = (ts_test_t *)malloc(sizeof(ts_test_t))) == NULL)
-        return;
-    RING_ELEM_INIT(tst, next);
-    va_start(ap, fmt);
-    tst->title = ts_suite_mvasprintf(fmt, ap);
-    va_end(ap);
-    tst->func = func;
-    tst->file = NULL;
-    tst->line = 0;
-    RING_INIT(&tst->checks, tstc_t, next);
-    RING_INSERT_TAIL(&ts->tests, tst, ts_test_t, next);
-    return;
-}
-
-/* run test suite */
-int ts_suite_run(ts_suite_t *ts)
-{
-    ts_test_t *tst;
-    tstc_t *tstc;
-    tstl_t *tstl;
-    int total_tests, total_tests_suite_failed;
-    int total_checks, total_checks_failed;
-    int test_checks, test_checks_failed;
-    const char *file;
-    int line;
-    char *cp;
-
-    if (ts == NULL)
-        return 0;
-
-    /* init total counters */
-    total_tests         = 0;
-    total_tests_suite_failed  = 0;
-    total_checks        = 0;
-    total_checks_failed = 0;
-
-    fprintf(stdout, "\n");
-    fprintf(stdout, " Test Suite: %s\n", ts->title);
-    fprintf(stdout, " __________________________________________________________________\n");
-    fprintf(stdout, "\n");
-    fflush(stdout);
-
-    /* iterate through all test cases */
-    RING_FOREACH(tst, &ts->tests, ts_test_t, next) {
-        cp = ts_suite_masprintf(" Test: %s ........................................"
-                                "........................................", tst->title);
-        cp[60] = '\0';
-        fprintf(stdout, "%s", cp);
-        free(cp);
-        fflush(stdout);
-
-        /* init test case counters */
-        test_checks        = 0;
-        test_checks_failed = 0;
-
-        /* run the test case function */
-        tst->func(tst);
-
-        /* iterate through all performed checks to determine status */
-        RING_FOREACH(tstc, &tst->checks, tstc_t, next) {
-            test_checks++;
-            if (tstc->failed)
-                test_checks_failed++;
-        }
-
-        if (test_checks_failed > 0) {
-            /* some checks failed, so do detailed reporting of test case */
-            fprintf(stdout, " FAILED\n");
-            fprintf(stdout, "       Ops, %d/%d checks failed! Detailed report follows:\n",
-                    test_checks_failed, test_checks);
-            RING_FOREACH(tstc, &tst->checks, tstc_t, next) {
-                file = (tstc->file != NULL ? tstc->file : tst->file);
-                line = (tstc->line != 0    ? tstc->line : tst->line);
-                if (file != NULL)
-                    fprintf(stdout, "       Check: %s [%s:%d]\n", tstc->title, file, line);
-                else
-                    fprintf(stdout, "       Check: %s\n", tstc->title);
-                RING_FOREACH(tstl, &tstc->logs, tstl_t, next) {
-                    file = (tstl->file != NULL ? tstl->file : file);
-                    line = (tstl->line != 0    ? tstl->line : line);
-                    if (file != NULL)
-                        fprintf(stdout, "              Log: %s [%s:%d]\n", tstl->text, file, line);
-                    else
-                        fprintf(stdout, "              Log: %s\n", tstl->text);
-                }
-            }
-        }
-        else {
-            /* test case ran successfully */
-            fprintf(stdout, ".... OK\n");
-        }
-        fflush(stdout);
-
-        /* accumulate counters */
-        total_checks += test_checks;
-        total_tests++;
-        if (test_checks_failed > 0) {
-            total_checks_failed += test_checks_failed;
-            total_tests_suite_failed++;
-        }
-    }
-
-    /* print test suite summary */
-    fprintf(stdout, " __________________________________________________________________\n");
-    fprintf(stdout, "\n");
-    fprintf(stdout, " Test Summary: %d tests (%d ok, %d failed), %d checks (%d ok, %d failed)\n", 
-            total_tests, (total_tests - total_tests_suite_failed), total_tests_suite_failed, 
-            total_checks, (total_checks - total_checks_failed), total_checks_failed); 
-    if (total_tests_suite_failed > 0)
-        fprintf(stdout, " Test Suite: FAILED\n");
-    else
-        fprintf(stdout, " Test Suite: OK\n");
-    fprintf(stdout, "\n");
-    fflush(stdout);
-
-    return total_checks_failed;
-}
-
-/* destroy test suite */
-void ts_suite_free(ts_suite_t *ts)
-{
-    ts_test_t *tst, *tstT;
-    tstc_t *tstc, *tstcT;
-    tstl_t *tstl, *tstlT;
-
-    if (ts == NULL)
-        return;
-    RING_FOREACH_LA(tst, tstT, &ts->tests, ts_test_t, next) {
-        RING_FOREACH_LA(tstc, tstcT, &tst->checks, tstc_t, next) {
-            RING_FOREACH_LA(tstl, tstlT, &tstc->logs, tstl_t, next) {
-                free(tstl->text);
-            }
-            free(tstc->title);
-            free(tstc);
-        }
-        free(tst->title);
-        free(tst);
-    }
-    free(ts->title);
-    free(ts);
-    return;
-}
-
-/* annotate test case with file name and line number */
-ts_test_t *ts_test_ctx(ts_test_t *tst, const char *file, int line)
-{
-    if (tst != NULL && file != NULL) {
-        tst->file = file;
-        tst->line = line;
-    }
-    return tst;
-}
-
-/* annotate test case with check */
-void ts_test_check(ts_test_t *tst, const char *fmt, ...)
-{
-    tstc_t *tstc;
-    va_list ap;
-
-    if (tst == NULL || fmt == NULL)
-        return;
-    if ((tstc = (tstc_t *)malloc(sizeof(tstc_t))) == NULL)
-        return;
-    va_start(ap, fmt);
-    RING_ELEM_INIT(tstc, next);
-    tstc->title = ts_suite_mvasprintf(fmt, ap);
-    tstc->failed = 0;
-    tstc->file = tst->file;
-    tstc->line = tst->line;
-    RING_INIT(&tstc->logs, tstl_t, next);
-    RING_INSERT_TAIL(&tst->checks, tstc, tstc_t, next);
-    va_end(ap);
-    return;
-}
-
-/* annotate test case with log message and failure */
-void ts_test_fail(ts_test_t *tst, const char *fmt, ...)
-{
-    tstc_t *tstc;
-    tstl_t *tstl;
-    va_list ap;
-
-    if (tst == NULL || fmt == NULL)
-        return;
-    if ((tstl = (tstl_t *)malloc(sizeof(tstl_t))) == NULL)
-        return;
-    va_start(ap, fmt);
-    tstl->text = ts_suite_mvasprintf(fmt, ap);
-    tstl->file = tst->file;
-    tstl->line = tst->line;
-    RING_ELEM_INIT(tstl, next);
-    tstc = RING_LAST(&tst->checks);
-    RING_INSERT_TAIL(&tstc->logs, tstl, tstl_t, next);
-    tstc->failed = 1;
-    va_end(ap);
-    return;
-}
-
-/* annotate test case with log message only */
-void ts_test_log(ts_test_t *tst, const char *fmt, ...)
-{
-    tstc_t *tstc;
-    tstl_t *tstl;
-    va_list ap;
-
-    if (tst == NULL || fmt == NULL)
-        return;
-    if ((tstl = (tstl_t *)malloc(sizeof(tstl_t))) == NULL)
-        return;
-    va_start(ap, fmt);
-    tstl->text = ts_suite_mvasprintf(fmt, ap);
-    tstl->file = tst->file;
-    tstl->line = tst->line;
-    RING_ELEM_INIT(tstl, next);
-    tstc = RING_LAST(&tst->checks);
-    RING_INSERT_TAIL(&tstc->logs, tstl, tstl_t, next);
-    va_end(ap);
-    return;
-}
-
index 5bb4c92..21dbd89 100644 (file)
 #include <time.h>
 #include <string.h>
 
 #include <time.h>
 #include <string.h>
 
-#include "xbt/testsuite.h"
+#include "xbt/cunit.h"
 #include "xbt/ex.h"
 #include "xbt/log.h"
 
 XBT_LOG_NEW_CATEGORY(test,"This test");
 
 #include "xbt/ex.h"
 #include "xbt/log.h"
 
 XBT_LOG_NEW_CATEGORY(test,"This test");
 
-TS_TEST(test_controlflow)
-{
+XBT_TEST_UNIT(test_expected_failure) {
+    xbt_test0("Skipped test");
+    xbt_test_skip();
+
+    xbt_test0("EXPECTED FAILURE");
+    xbt_test_expect_failure();
+    xbt_test_log2("%s %s","Test","log");
+    xbt_test_fail0("EXPECTED FAILURE");
+}
+
+XBT_TEST_UNIT(test_controlflow) {
     xbt_ex_t ex;
     xbt_ex_t ex;
-    volatile int n;
+    volatile int n=1;
+
+    xbt_test0("basic nested control flow");
 
 
-    ts_test_check(TS_CTX, "basic nested control flow");
-    n = 1;
     TRY {
         if (n != 1)
     TRY {
         if (n != 1)
-            ts_test_fail(TS_CTX, "M1: n=%d (!= 1)", n);
+            xbt_test_fail1("M1: n=%d (!= 1)", n);
         n++;
         TRY {
             if (n != 2)
         n++;
         TRY {
             if (n != 2)
-                ts_test_fail(TS_CTX, "M2: n=%d (!= 2)", n);
+                xbt_test_fail1("M2: n=%d (!= 2)", n);
             n++;
             THROW0(unknown_error,0,"something");
         } CATCH (ex) {
             if (n != 3)
             n++;
             THROW0(unknown_error,0,"something");
         } CATCH (ex) {
             if (n != 3)
-                ts_test_fail(TS_CTX, "M3: n=%d (!= 1)", n);
+                xbt_test_fail1("M3: n=%d (!= 1)", n);
             n++;
             RETHROW;
         }
             n++;
             RETHROW;
         }
-        ts_test_fail(TS_CTX, "MX: n=%d (expected: not reached)", n);
+        xbt_test_fail1("MX: n=%d (shouldn't reach this point)", n);
     }
     CATCH(ex) {
         if (n != 4)
     }
     CATCH(ex) {
         if (n != 4)
-            ts_test_fail(TS_CTX, "M4: n=%d (!= 4)", n);
+            xbt_test_fail1("M4: n=%d (!= 4)", n);
         n++;
         xbt_ex_free(ex);
     }
     if (n != 5)
         n++;
         xbt_ex_free(ex);
     }
     if (n != 5)
-        ts_test_fail(TS_CTX, "M5: n=%d (!= 5)", n);
+        xbt_test_fail1("M5: n=%d (!= 5)", n);
 }
 
 }
 
-TS_TEST(test_value)
-{
+XBT_TEST_UNIT(test_value) {
     xbt_ex_t ex;
 
     TRY {
         THROW0(unknown_error, 2, "toto");
     } CATCH(ex) {
     xbt_ex_t ex;
 
     TRY {
         THROW0(unknown_error, 2, "toto");
     } CATCH(ex) {
-        ts_test_check(TS_CTX, "exception value passing");
+        xbt_test0("exception value passing");
         if (ex.category != unknown_error)
         if (ex.category != unknown_error)
-            ts_test_fail(TS_CTX, "category=%d (!= 1)", ex.category);
+            xbt_test_fail1("category=%d (!= 1)", ex.category);
         if (ex.value != 2)
         if (ex.value != 2)
-            ts_test_fail(TS_CTX, "value=%d (!= 2)", ex.value);
+            xbt_test_fail1("value=%d (!= 2)", ex.value);
         if (strcmp(ex.msg,"toto"))
         if (strcmp(ex.msg,"toto"))
-            ts_test_fail(TS_CTX, "message=%s (!= toto)", ex.msg);
+            xbt_test_fail1("message=%s (!= toto)", ex.msg);
         xbt_ex_free(ex);
     }
 }
 
         xbt_ex_free(ex);
     }
 }
 
-TS_TEST(test_variables)
-{
+XBT_TEST_UNIT(test_variables) {
     xbt_ex_t ex;
     int r1, r2;
     volatile int v1, v2;
     xbt_ex_t ex;
     int r1, r2;
     volatile int v1, v2;
@@ -103,25 +110,24 @@ TS_TEST(test_variables)
         v2 = 5678;
         THROW0(unknown_error, 0, "toto");
     } CATCH(ex) {
         v2 = 5678;
         THROW0(unknown_error, 0, "toto");
     } CATCH(ex) {
-        ts_test_check(TS_CTX, "variable preservation");
+        xbt_test0("variable preservation");
         if (r1 != 1234)
         if (r1 != 1234)
-            ts_test_fail(TS_CTX, "r1=%d (!= 1234)", r1);
+            xbt_test_fail1("r1=%d (!= 1234)", r1);
         if (v1 != 1234)
         if (v1 != 1234)
-            ts_test_fail(TS_CTX, "v1=%d (!= 1234)", v1);
+            xbt_test_fail1("v1=%d (!= 1234)", v1);
         /* r2 is allowed to be destroyed because not volatile */
         if (v2 != 5678)
         /* r2 is allowed to be destroyed because not volatile */
         if (v2 != 5678)
-            ts_test_fail(TS_CTX, "v2=%d (!= 5678)", v2);
+            xbt_test_fail1("v2=%d (!= 5678)", v2);
         xbt_ex_free(ex);
     }
 }
 
         xbt_ex_free(ex);
     }
 }
 
-TS_TEST(test_cleanup)
-{
+XBT_TEST_UNIT(test_cleanup) {
     xbt_ex_t ex;
     volatile int v1;
     int c;
 
     xbt_ex_t ex;
     volatile int v1;
     int c;
 
-    ts_test_check(TS_CTX, "cleanup handling");
+    xbt_test0("cleanup handling");
 
     v1 = 1234;
     c = 0;
 
     v1 = 1234;
     c = 0;
@@ -130,32 +136,32 @@ TS_TEST(test_cleanup)
         THROW0(1, 2, "blah");
     } CLEANUP {
         if (v1 != 5678)
         THROW0(1, 2, "blah");
     } CLEANUP {
         if (v1 != 5678)
-            ts_test_fail(TS_CTX, "v1 = %d (!= 5678)", v1);
+            xbt_test_fail1("v1 = %d (!= 5678)", v1);
         c = 1;
     } CATCH(ex) {
         if (v1 != 5678)
         c = 1;
     } CATCH(ex) {
         if (v1 != 5678)
-            ts_test_fail(TS_CTX, "v1 = %d (!= 5678)", v1);
+            xbt_test_fail1("v1 = %d (!= 5678)", v1);
         if (!(ex.category == 1 && ex.value == 2 && !strcmp(ex.msg,"blah")))
         if (!(ex.category == 1 && ex.value == 2 && !strcmp(ex.msg,"blah")))
-            ts_test_fail(TS_CTX, "unexpected exception contents");
+            xbt_test_fail0("unexpected exception contents");
         xbt_ex_free(ex);
     }
     if (!c)
         xbt_ex_free(ex);
     }
     if (!c)
-        ts_test_fail(TS_CTX, "ex_cleanup not executed");
+        xbt_test_fail0("xbt_ex_free not executed");
 }
 
 }
 
-int main(int argc, char *argv[])
-{
-    ts_suite_t *ts;
-    int n;
-
-    ts = ts_suite_new("OSSP ex (Exception Handling)");
-    ts_suite_test(ts, test_controlflow, "basic nested control flow");
-    ts_suite_test(ts, test_value,       "exception value passing");
-    ts_suite_test(ts, test_variables,   "variable value preservation");
-    ts_suite_test(ts, test_cleanup,     "cleanup handling");
-    n = ts_suite_run(ts);
-    ts_suite_free(ts);
-    return n;
+int main(int argc, char *argv[]) {
+    xbt_test_suite_t suite;
+
+    suite = xbt_test_suite_new("Testsuite Autotest");
+    xbt_test_suite_push(suite, test_expected_failure, "expected failures");
+    
+    suite = xbt_test_suite_new("Exception Handling");
+    xbt_test_suite_push(suite, test_controlflow, "basic nested control flow");
+    xbt_test_suite_push(suite, test_value,       "exception value passing");
+    xbt_test_suite_push(suite, test_variables,   "variable value preservation");
+    xbt_test_suite_push(suite, test_cleanup,     "cleanup handling");
+
+    return xbt_test_run();
 }
 
 
 }