typedef void (*ts_test_cb_t)(xbt_test_unit_t);
/* test suite operations */
-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 xbt_test_suite_by_name(const char *name,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, ...);
/* 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_add(xbt_test_unit_t u, const char*file,int line, const char *fmt, ...)_XBT_GNUC_PRINTF(4,5);
+#define xbt_test_add0(fmt) _xbt_test_add(_unit,__FILE__,__LINE__,fmt)
+#define xbt_test_add1(fmt,a) _xbt_test_add(_unit,__FILE__,__LINE__,fmt,a)
+#define xbt_test_add2(fmt,a,b) _xbt_test_add(_unit,__FILE__,__LINE__,fmt,a,b)
+#define xbt_test_add3(fmt,a,b,c) _xbt_test_add(_unit,__FILE__,__LINE__,fmt,a,b,c)
+#define xbt_test_add4(fmt,a,b,c,d) _xbt_test_add(_unit,__FILE__,__LINE__,fmt,a,b,c,d)
+#define xbt_test_add5(fmt,a,b,c,d,e) _xbt_test_add(_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_skip() _xbt_test_skip(_unit)
/* test suite short-cut macros */
-#define XBT_TEST_UNIT(name) \
- static void name(xbt_test_unit_t _unit)
+#define XBT_TEST_UNIT(name,func,title) \
+ void func(xbt_test_unit_t _unit); /*prototype*/ \
+ void func(xbt_test_unit_t _unit)
#endif /* _TS_H_ */
stamp-h.in stamp-h stamp-h1
*.loT
ucontext_stack.h
+*_unit.c simgrid_units_main.c testall*
# using this trick is ready for a "stable" release (say, in Debian).
lib_LTLIBRARIES= libsimgrid.la libgras.la
+noinst_PROGRAMS=testall
COMMON_SRC=\
\
amok/base.c \
amok/Bandwidth/bandwidth.c amok/Bandwidth/saturate.c
+###
+### Testing infrastructure
+###
+
+TEST_CFILES=xbt/cunit.c xbt/ex.c
+TEST_UNITS= cunit_unit.c ex_unit.c
+
BUILT_SOURCES=../include/surf/surfxml.h surf/surfxml.c \
- gras/DataDesc/ddt_parse.yy.c
+ gras/DataDesc/ddt_parse.yy.c \
+ $(TEST_UNITS) simgrid_units_main.c
+
+testall_SOURCES= $(TEST_UNITS) simgrid_units_main.c
+testall_LDADD=libgras.la
+
+if MAINTAINER_MODE
+%_unit.c: $(TEST_CFILES) @top_srcdir@/tools/sg_unit_extractor.pl
+ @echo TEST_UNITS=$(TEST_UNITS)
+ @echo testall_SOURCES=$(testall_SOURCES)
+ @lookfor=`echo $@ | sed 's/_unit.c$$/.c/'`; \
+ for s in $(TEST_CFILES) ; do \
+ if echo $$s | grep $$lookfor >/dev/null; then \
+ src="$$src $$s"; \
+ fi; \
+ done; \
+ echo "Generate Testing Suite $@ from$$src"; \
+ @top_srcdir@/tools/sg_unit_extractor.pl $$src
+
+simgrid_units_main.c: $(TEST_UNITS)
+endif
+
+###
+### Regenerate what needs to with flex & flexml
+###
+
gras/DataDesc/ddt_parse.yy.c: gras/DataDesc/ddt_parse.yy.l
@LEX@ -o$@ -Pgras_ddt_parse_ $^
endif
endif
+###
+### Declare the library content
+###
+
libgras_la_SOURCES= $(COMMON_SRC) $(RL_SRC) $(AMOK_SRC)
libgras_la_LDFLAGS = $(VERSION_INFO) @GRAS_DEP@ @LD_DYNAMIC_FLAGS@ -lm
libsimgrid_la_LDFLAGS = $(VERSION_INFO) @SIMGRID_DEP@ @LD_DYNAMIC_FLAGS@ -lm
+
include $(top_srcdir)/acmacro/dist-files.mk
/* 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 retrive 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;
/* 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(xbt_test_unit_t unit, const char*file,int line, const char *fmt, ...) {
xbt_test_test_t test;
va_list 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 */
}
#endif
+
+#ifdef SIMGRID_TEST
+#include "xbt/ex.h"
+
+XBT_TEST_SUITE("xbt_ex","Exception Handling");
+
+XBT_TEST_UNIT("controlflow",test_controlflow, "basic nested control flow") {
+ xbt_ex_t ex;
+ volatile int n=1;
+
+ xbt_test_add0("basic nested control flow");
+
+ TRY {
+ if (n != 1)
+ xbt_test_fail1("M1: n=%d (!= 1)", n);
+ n++;
+ TRY {
+ if (n != 2)
+ xbt_test_fail1("M2: n=%d (!= 2)", n);
+ n++;
+ THROW0(unknown_error,0,"something");
+ } CATCH (ex) {
+ if (n != 3)
+ xbt_test_fail1("M3: n=%d (!= 1)", n);
+ n++;
+ RETHROW;
+ }
+ xbt_test_fail1("MX: n=%d (shouldn't reach this point)", n);
+ }
+ CATCH(ex) {
+ if (n != 4)
+ xbt_test_fail1("M4: n=%d (!= 4)", n);
+ n++;
+ xbt_ex_free(ex);
+ }
+ if (n != 5)
+ xbt_test_fail1("M5: n=%d (!= 5)", n);
+}
+
+XBT_TEST_UNIT("value",test_value,"exception value passing") {
+ xbt_ex_t ex;
+
+ TRY {
+ THROW0(unknown_error, 2, "toto");
+ } CATCH(ex) {
+ xbt_test_add0("exception value passing");
+ if (ex.category != unknown_error)
+ xbt_test_fail1("category=%d (!= 1)", ex.category);
+ if (ex.value != 2)
+ xbt_test_fail1("value=%d (!= 2)", ex.value);
+ if (strcmp(ex.msg,"toto"))
+ xbt_test_fail1("message=%s (!= toto)", ex.msg);
+ xbt_ex_free(ex);
+ }
+}
+
+XBT_TEST_UNIT("variables",test_variables,"variable value preservation") {
+ xbt_ex_t ex;
+ int r1, r2;
+ volatile int v1, v2;
+
+ r1 = r2 = v1 = v2 = 1234;
+ TRY {
+ r2 = 5678;
+ v2 = 5678;
+ THROW0(unknown_error, 0, "toto");
+ } CATCH(ex) {
+ xbt_test_add0("variable preservation");
+ if (r1 != 1234)
+ xbt_test_fail1("r1=%d (!= 1234)", r1);
+ if (v1 != 1234)
+ xbt_test_fail1("v1=%d (!= 1234)", v1);
+ /* r2 is allowed to be destroyed because not volatile */
+ if (v2 != 5678)
+ xbt_test_fail1("v2=%d (!= 5678)", v2);
+ xbt_ex_free(ex);
+ }
+}
+
+XBT_TEST_UNIT("cleanup",test_cleanup,"cleanup handling") {
+ xbt_ex_t ex;
+ volatile int v1;
+ int c;
+
+ xbt_test_add0("cleanup handling");
+
+ v1 = 1234;
+ c = 0;
+ TRY {
+ v1 = 5678;
+ THROW0(1, 2, "blah");
+ } CLEANUP {
+ if (v1 != 5678)
+ xbt_test_fail1("v1 = %d (!= 5678)", v1);
+ c = 1;
+ } CATCH(ex) {
+ if (v1 != 5678)
+ xbt_test_fail1("v1 = %d (!= 5678)", v1);
+ if (!(ex.category == 1 && ex.value == 2 && !strcmp(ex.msg,"blah")))
+ xbt_test_fail0("unexpected exception contents");
+ xbt_ex_free(ex);
+ }
+ if (!c)
+ xbt_test_fail0("xbt_ex_free not executed");
+}
+#endif /* SIMGRID_TEST */
** ex_test.c: exception handling test suite
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <string.h>
-
#include "xbt/cunit.h"
#include "xbt/ex.h"
#include "xbt/log.h"
--- /dev/null
+#! /usr/bin/perl
+
+use strict;
+
+my $progname="sg_unit_extractor";
+# Get the args
+die "USAGE: $progname infile [outfile]\n"
+ if (scalar @ARGV == 0 || scalar @ARGV > 2);
+my ($infile,$outfile) = @ARGV;
+
+if (not defined($outfile)) {
+ $outfile = $infile;
+ $outfile =~ s/\.c$/_unit.c/;
+ $outfile =~ s|.*/([^/]*)$|$1| if $outfile =~ m|/|;
+}
+
+# Get the unit data
+my ($unit_source,$suite_name,$suite_title)=("","","");
+my (%tests); # to detect multiple definition
+my (@tests); # actual content
+
+open IN, "$infile" || die "$progname: Cannot open input file '$infile': $!\n";
+
+my $takeit=0;
+while (<IN>) {
+ if (m/ifdef +SIMGRID_TEST/) {
+ $takeit = 1;
+ next;
+ }
+ if (m/endif.*SIMGRID_TEST/) {
+ $takeit = 0;
+ next
+ }
+
+ if (m/XBT_TEST_SUITE\(\w*"([^"]*)"\w*,(.*?)\);/) { #"
+ die "$progname: Multiple suites in the same file ($infile) are not supported yet\n"
+ if length($suite_name);
+ ($suite_name,$suite_title)=($1,$2);
+ next;
+ }
+
+ if (m/XBT_TEST_UNIT\(\w*"([^"]*)"\w*,([^,]*),(.*?)\)/) { #"
+ die "$progname: multiply defined test in file $infile: $1\n"
+ if (defined($tests{$1}));
+
+ my @t=($1,$2,$3);
+ push @tests,\@t;
+ $tests{$1} = 1;
+ }
+ $unit_source .= $_ if $takeit;
+}
+close IN || die "$progname: cannot close input file '$infile': $!\n";
+
+
+if ($takeit) {
+ die "$progname: end of file reached in SIMGRID_TEST block.\n".
+ "You should end each of the with a line matching: /endif.*SIMGRID_TEST/\n".
+ "Example:\n".
+ "#endif /* SIMGRID_TEST */\n"
+}
+
+die "$progname: no suite defined in $infile\n"
+ unless (length($suite_name));
+
+# Write the test
+
+my ($GENERATED)=("/*******************************/\n".
+ "/* GENERATED FILE, DO NOT EDIT */\n".
+ "/*******************************/\n\n");
+
+open OUT,">$outfile" || die "$progname: Cannot open output file '$outfile': $!\n";
+print OUT $GENERATED;
+print OUT "#include \"xbt.h\"\n";
+print OUT $GENERATED;
+print OUT "$unit_source";
+print OUT $GENERATED;
+close OUT || die "$progname: Cannot close output file '$outfile': $!\n";
+
+# write the main skeleton if needed
+if (! -e "simgrid_units_main.c") {
+ open OUT,">simgrid_units_main.c" || die "$progname: Cannot open main file 'simgrid_units_main.c': $!\n";
+ print OUT $GENERATED;
+ print OUT "#include \"xbt.h\"\n\n";
+ print OUT "/* SGU: BEGIN PROTOTYPES */\n";
+ print OUT "/* SGU: END PROTOTYPES */\n\n";
+ print OUT $GENERATED;
+ print OUT "int main(int argc, char *argv[]) {\n";
+ print OUT " xbt_test_suite_t suite;\n\n";
+ print OUT " /* SGU: BEGIN SUITES DECLARATION */\n";
+ print OUT " /* SGU: END SUITES DECLARATION */\n\n";
+ print OUT " return xbt_test_run();\n";
+ print OUT "}\n";
+ print OUT $GENERATED;
+ close OUT || die "$progname: Cannot close main file 'simgrid_units_main.c': $!\n";
+}
+
+print " Suite $suite_name: $suite_title (".(scalar @tests)." tests)\n";
+map {
+ my ($name,$func,$title) = @{$_};
+ print " test $name: func=$func; title=$title\n";
+} @tests;
+
+#while (my $t = shift @tests) {
+
+# add this suite to the main
+my $newmain="";
+open IN,"simgrid_units_main.c" || die "$progname: Cannot open main file 'simgrid_units_main.c': $!\n";
+ # search prototypes
+ while (<IN>) {
+ $newmain .= $_;
+# print "Look for proto: $_";
+ last if /SGU: BEGIN PROTOTYPES/;
+ }
+
+ # search my prototype
+ while (<IN>) {
+# print "Seek protos: $_";
+ last if (/SGU: END PROTOTYPES/ || /SGU: BEGIN FILE $infile/);
+ $newmain .= $_;
+ }
+ if (/SGU: BEGIN FILE $infile/) { # found an old section for this file. Kill it
+ while (<IN>) {
+ last if /SGU: END FILE/;
+ }
+ $_ = <IN>; # pass extra blank line
+ chomp;
+ die "this line should be blank ($_). Did you edit the file?" if /\W/;
+ }
+ my ($old_)=($_);
+ # add my section
+ $newmain .= " /* SGU: BEGIN FILE $infile */\n";
+ map {
+ my ($name,$func,$title) = @{$_};
+ $newmain .= " void $func(xbt_test_unit_t _unit);\n"
+ } @tests;
+
+ $newmain .= " /* SGU: END FILE */\n\n";
+ if ($old_ =~ /SGU: BEGIN FILE/ || $old_ =~ /SGU: END PROTOTYPES/) {
+ $newmain .= $old_;
+ }
+
+ # pass remaining prototypes, search declarations
+ while (<IN>) {
+ $newmain .= $_ unless /SGU: END PROTOTYPES/;
+ last if /SGU: BEGIN SUITES DECLARATION/;
+ }
+
+ ### Done with prototypes. And now, the actual code
+
+ # search my prototype
+ while (<IN>) {
+ last if (/SGU: END SUITES DECLARATION/ || /SGU: BEGIN FILE $infile/);
+ $newmain .= $_;
+ }
+ if (/SGU: BEGIN FILE $infile/) { # found an old section for this file. Kill it
+ while (<IN>) {
+ last if /SGU: END FILE/;
+ }
+ $_ = <IN>; # pass extra blank line
+ chomp;
+ die "this line should be blank ($_). Did you edit the file?" if /\W/;
+ }
+ my ($old_)=($_);
+ # add my section
+ $newmain .= " /* SGU: BEGIN FILE $infile */\n";
+ $newmain .= " suite = xbt_test_suite_by_name(\"$suite_name\",$suite_title);\n";
+ map {
+ my ($name,$func,$title) = @{$_};
+ $newmain .= " xbt_test_suite_push(suite, $func, $title);\n";
+ } @tests;
+
+ $newmain .= " /* SGU: END FILE */\n\n";
+ if ($old_ =~ /SGU: BEGIN FILE/ || $old_ =~ /SGU: END SUITES DECLARATION/) {
+ $newmain .= $old_;
+ }
+
+ # pass the remaining
+ while (<IN>) {
+ $newmain .= $_;
+ }
+close IN || die "$progname: Cannot close main file 'simgrid_units_main.c': $!\n";
+
+# write it back to main
+open OUT,">simgrid_units_main.c" || die "$progname: Cannot open main file 'simgrid_units_main.c': $!\n";
+print OUT $newmain;
+close OUT || die "$progname: Cannot close main file 'simgrid_units_main.c': $!\n";
+
+0;
\ No newline at end of file