Changeset 6816
- Timestamp:
- 09/09/10 22:40:57 (17 months ago)
- Location:
- trunk
- Files:
-
- 11 modified
- 2 copied
-
ARBDB/ad_save_load.cxx (modified) (3 diffs)
-
ARBDB/arb_assert.h (modified) (1 diff)
-
GDE/Makefile (modified) (1 diff)
-
SOURCE_TOOLS/arb_create_patch.sh (modified) (2 diffs)
-
SOURCE_TOOLS/generate_all_links.sh (modified) (1 diff)
-
UNIT_TESTER (modified) (1 prop)
-
UNIT_TESTER/Makefile (modified) (2 diffs)
-
UNIT_TESTER/Makefile.test (modified) (6 diffs)
-
UNIT_TESTER/TestEnvironment.cxx (copied) (copied from branches/refactor/UNIT_TESTER/TestEnvironment.cxx)
-
UNIT_TESTER/UnitTester.cxx (modified) (4 diffs)
-
UNIT_TESTER/UnitTester.hxx (modified) (2 diffs)
-
UNIT_TESTER/test_global.h (copied) (copied from branches/refactor/UNIT_TESTER/test_global.h) (2 diffs)
-
UNIT_TESTER/test_unit.h (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ARBDB/ad_save_load.cxx
r6682 r6816 1293 1293 #include <test_unit.h> 1294 1294 1295 static bool files_are_equal(const char *file1, const char *file2) {1296 GB_ERROR error = NULL;1297 FILE *fp1 = fopen(file1, "rb");1298 1299 // @@@ FIXME: use GB_IO_error() here later1300 if (!fp1) error = GBS_global_string("can't open '%s'", file1);1301 else {1302 FILE *fp2 = fopen(file2, "rb");1303 if (!fp2) error = GBS_global_string("can't open '%s'", file2);1304 else {1305 const int BLOCKSIZE = 4096;1306 char *buf1 = (char*)malloc(BLOCKSIZE);1307 char *buf2 = (char*)malloc(BLOCKSIZE);1308 1309 while (!error) {1310 int read1 = fread(buf1, 1, BLOCKSIZE, fp1);1311 int read2 = fread(buf2, 1, BLOCKSIZE, fp2);1312 1313 if (read1 != read2) error = "filesizes differ";1314 else {1315 if (!read1) break; // done1316 if (memcmp(buf1, buf2, read1) != 0) error = "content differs";1317 }1318 }1319 free(buf2);1320 free(buf1);1321 fclose(fp2);1322 }1323 fclose(fp1);1324 }1325 1326 if (error) TEST_WARNING("%s", GBS_global_string("files_are_equal(%s, %s): %s", file1, file2, error));1327 return !error;1328 }1329 1330 1295 #define SAVE_AND_COMPARE(gbd, save_as, savetype, compare_with) \ 1331 1296 TEST_ASSERT_NO_ERROR(GB_save_as(gbd, save_as, savetype)); \ 1332 TEST_ASSERT (files_are_equal(save_as, compare_with))1297 TEST_ASSERT_FILES_EQUAL(save_as, compare_with) 1333 1298 1334 1299 static GB_ERROR modify_db(GBDATA *gb_main) { … … 1342 1307 if (!gb_entry) error = GB_await_error(); 1343 1308 else error = GB_write_string(gb_entry, "text"); 1309 // else error = GB_write_string(gb_entry, "bla"); // provoke error in file compare 1344 1310 } 1345 1311 return error; … … 1425 1391 #endif // TEST_AUTO_UPDATE 1426 1392 1427 TEST_ASSERT (files_are_equal("TEST_loadsave_quick.a00", "a2b.a00"));1428 TEST_ASSERT (files_are_equal("a2b.a00", "b2b.a00"));1393 TEST_ASSERT_FILES_EQUAL("TEST_loadsave_quick.a00", "a2b.a00"); 1394 TEST_ASSERT_FILES_EQUAL("a2b.a00", "b2b.a00"); 1429 1395 1430 1396 TEST_ASSERT_NO_ERROR(GB_save_quick_as(gb_a2b, "a2b.arb")); -
trunk/ARBDB/arb_assert.h
r6813 r6816 180 180 181 181 #if (UNIT_TESTS == 1) 182 # if defined(DEVEL_RELEASE) 183 # error Unit testing not allowed in release 184 # else 185 186 # ifdef __cplusplus 187 188 #ifndef _CPP_CSTDLIB 189 #include <cstdlib> 190 #endif 191 192 namespace arb_test { 193 class GlobalTestData { 194 GlobalTestData() 195 : show_warnings(true), 196 assertion_failed(false), 197 warnings(0) 198 {} 199 200 static GlobalTestData *instance(bool erase) { 201 static GlobalTestData *data = 0; // singleton 202 if (erase) { 203 delete data; 204 data = 0; 205 } 206 else { 207 if (!data) data = new GlobalTestData; 208 } 209 return data; 210 } 211 212 public: 213 bool show_warnings; 214 bool assertion_failed; 215 216 // counters 217 size_t warnings; 218 219 static GlobalTestData& get_instance() { return *instance(false); } 220 static void erase_instance() { instance(true); } 221 }; 222 223 inline GlobalTestData& test_data() { return GlobalTestData::get_instance(); } 224 }; 225 226 # define ASSERTION_HAS_FAILED() arb_test::test_data().assertion_failed = true 227 228 # else 229 # define ASSERTION_HAS_FAILED() // impossible in C 230 # endif 231 232 # define test_assert(cond) \ 233 do { \ 234 if (!(cond)) { \ 235 fflush(stdout); \ 236 fflush(stderr); \ 237 fprintf(stderr, "%s:%i: Assertion '%s' failed\n", \ 238 __FILE__, __LINE__, #cond); \ 239 fflush(stderr); \ 240 ASSERTION_HAS_FAILED(); \ 241 ARB_SIGSEGV(0); \ 242 } \ 243 } while(0) 244 245 # if defined(ASSERTION_USED) 246 # undef arb_assert 247 # define arb_assert(cond) test_assert(cond) 248 # endif 249 250 # endif 182 #ifndef TEST_GLOBAL_H 183 #include <test_global.h> // overrides arb_assert()! 184 #endif 251 185 #endif 252 186 -
trunk/GDE/Makefile
r5872 r6816 39 39 40 40 # -------------------------------------------------------------------------------- 41 # no warnings in this subtree41 # modify cflags for submakefiles 42 42 43 RAISE_WARNINGS=0 43 RAISE_WARNINGS=0# no warnings in this subtree 44 UNIT_TESTS=0# no warnings in this subtree 45 46 sub_cflags:=$(cflags) 44 47 45 48 ifeq ('$(RAISE_WARNINGS)','0') 46 sub_cflags:=$(subst -W -Wall,-w,$(cflags)) 47 else 48 sub_cflags:=$(cflags) 49 sub_cflags:=$(subst -W -Wall,-w,$(sub_cflags)) 50 endif 51 ifeq ('$(UNIT_TESTS)','0') 52 sub_cflags:=$(subst -DUNIT_TESTS,,$(sub_cflags)) 49 53 endif 50 54 -
trunk/SOURCE_TOOLS/arb_create_patch.sh
r6718 r6816 17 17 PATCHNAME=${NAME}_$DATE 18 18 PATCH=$PATCHDIR/$PATCHNAME.patch 19 FAKEPATCH=$PATCHDIR/fake.patch 20 RECENT_PATCH=$ARBHOME/latest.patch 19 21 20 22 cd $ARBHOME … … 24 26 if [ ! -s $PATCH ]; then 25 27 rm $PATCH 28 if [ ! -e $FAKEPATCH ]; then 29 echo "Index: No changes" > $FAKEPATCH 30 echo "===================================================================" >> $FAKEPATCH 31 fi 32 ln --force $FAKEPATCH $RECENT_PATCH 33 touch $FAKEPATCH 26 34 echo "No patch generated (no diff)" 27 35 else 28 RECENT_PATCH=$ARBHOME/latest.patch29 36 ln --force $PATCH $RECENT_PATCH 30 37 ls -alh $PATCH $RECENT_PATCH -
trunk/SOURCE_TOOLS/generate_all_links.sh
r6813 r6816 254 254 symlink_file ../STAT/st_window.hxx INCLUDE/st_window.hxx && 255 255 symlink_file ../UNIT_TESTER/test_unit.h INCLUDE/test_unit.h && 256 symlink_file ../UNIT_TESTER/test_global.h INCLUDE/test_global.h && 256 257 symlink_file ../WINDOW/aw_advice.hxx INCLUDE/aw_advice.hxx && 257 258 symlink_file ../WINDOW/aw_awars.hxx INCLUDE/aw_awars.hxx && -
trunk/UNIT_TESTER
- Property svn:ignore
-
old new 5 5 *.gcno 6 6 logs 7 test_environment
-
- Property svn:ignore
-
trunk/UNIT_TESTER/Makefile
r6699 r6816 2 2 .SUFFIXES: .o .cxx .depend 3 3 4 CPP_OBJECTS = \4 TESTER_OBJECTS = \ 5 5 UnitTester.o \ 6 6 7 GLOBAL_OBJECTS = \ 8 TestEnvironment.o \ 7 9 8 $(MAIN): $(CPP_OBJECTS) 9 $(LINK_STATIC_LIB) $(MAIN) $(CPP_OBJECTS) 10 CPP_OBJECTS = $(TESTER_OBJECTS) $(GLOBAL_OBJECTS) 11 12 $(MAIN): $(TESTER_OBJECTS) test_environment 13 $(LINK_STATIC_LIB) $(MAIN) $(TESTER_OBJECTS) 14 15 test_environment: $(GLOBAL_OBJECTS) $(TESTER_OBJECTS) 16 $(LINK_EXECUTABLE) test_environment $(GLOBAL_OBJECTS) $(TESTER_OBJECTS) $(LIBPATH) $(ARBDB_LIB) 17 10 18 .cxx.o: 11 19 $(CPP) $(cflags) -c $< $(CPPINCLUDES) 12 20 13 21 clean: 14 rm -f $(CPP_OBJECTS) 22 rm -f $(CPP_OBJECTS) *.a test_environment 15 23 $(MAKE) -f Makefile.test clean 24 16 25 17 26 DEPENDS = $(CPP_OBJECTS:.o=.depend) … … 32 41 # For formatting issues see SOURCE_TOOLS/fix_depends.pl 33 42 43 TestEnvironment.o: test_global.h 44 TestEnvironment.o: test_unit.h 45 TestEnvironment.o: UnitTester.hxx 46 TestEnvironment.o: $(ARBHOME)/INCLUDE/ad_k_prot.h 47 TestEnvironment.o: $(ARBHOME)/INCLUDE/ad_prot.h 48 TestEnvironment.o: $(ARBHOME)/INCLUDE/arb_assert.h 49 TestEnvironment.o: $(ARBHOME)/INCLUDE/arb_core.h 50 TestEnvironment.o: $(ARBHOME)/INCLUDE/arb_defs.h 51 TestEnvironment.o: $(ARBHOME)/INCLUDE/arb_error.h 52 TestEnvironment.o: $(ARBHOME)/INCLUDE/arb_str.h 53 TestEnvironment.o: $(ARBHOME)/INCLUDE/arbdb.h 54 TestEnvironment.o: $(ARBHOME)/INCLUDE/arbdb_base.h 55 TestEnvironment.o: $(ARBHOME)/INCLUDE/arbtools.h 56 TestEnvironment.o: $(ARBHOME)/INCLUDE/attributes.h 57 TestEnvironment.o: $(ARBHOME)/INCLUDE/dupstr.h 58 TestEnvironment.o: $(ARBHOME)/INCLUDE/smartptr.h 59 60 UnitTester.o: test_global.h 34 61 UnitTester.o: test_unit.h 35 62 UnitTester.o: UnitTester.hxx -
trunk/UNIT_TESTER/Makefile.test
r6812 r6816 15 15 # ---------------------------------------------------------- 16 16 17 # @@@ valgrind makes tests fail atm 18 # (most likely two pt-servers try to start parallel on the same port) 19 17 20 VALGRIND=0# only test 18 21 #VALGRIND=1# run valgrind after sucessful test 19 22 #VALGRIND=2# run valgrind before test (useful if test traps w/o any helpful information) 23 24 #CHECK_LEAKS=0# check no leaks 25 CHECK_LEAKS=1# check definite leaks 26 #CHECK_LEAKS=2# check reachable leaks 20 27 21 28 # ---------------------------------------------------------- … … 29 36 # 30 37 RESTRICT_LIB=# run all tests 38 #RESTRICT_LIB=AWTC# test only this library 31 39 #RESTRICT_LIB=mkptypes# test only these libraries 32 40 #RESTRICT_LIB=client:arb_probe:AWTC# test only these libraries … … 81 89 82 90 DESTDIR=tests 83 RUNDIR=run 84 RUN2HERE=..# prefix from RUNDIR to here (UNIT_TESTER) 91 RUNDIR=run# see also UnitTester.cxx@chdir 85 92 86 93 SYMLIST=$(DESTDIR)/$(UNIQUE_NAME).sym … … 152 159 @echo "LINKDEPS ='$(LINKDEPS)'" 153 160 161 ifeq ($(CHECK_LEAKS),0) 162 LEAKS:= 163 else 164 ifeq ($(CHECK_LEAKS),1) 165 LEAKS:=-l 166 else 167 LEAKS:=-l -r 168 endif 169 endif 170 154 171 valgrind: 155 172 echo "Valgrinding.." 156 cd $(RUNDIR);$(ARBHOME)/SOURCE_TOOLS/arb_valgrind -q -l -r -c 15 $(RUN2HERE)/$(TEST_EXE)173 $(ARBHOME)/SOURCE_TOOLS/arb_valgrind -q $(LEAKS) -c 15 $(TEST_EXE) 157 174 158 175 perform_test: $(TEST_EXE) … … 161 178 $(MAKE) -f Makefile.test valgrind 162 179 endif 163 cd $(RUNDIR);$(RUN2HERE)/$(TEST_EXE)180 $(TEST_EXE) 164 181 ifeq ($(COVERAGE),1) 165 182 @echo "-------------------- test-coverage for $(UNITLIBNAME)" … … 173 190 174 191 skip_test: 175 @echo " unit-tests completely skipped for '$(UNITLIBNAME)'"192 @echo "UnitTester: $(UNITLIBNAME) tests=0 (skipped via RESTRICT_LIB)" 176 193 177 194 # -------------------- -
trunk/UNIT_TESTER/UnitTester.cxx
r6743 r6816 51 51 // -------------------------------------------------------------------------------- 52 52 53 enum UnitTestResult {54 TEST_OK,55 TEST_TRAPPED,56 };57 58 53 static const char *readable_result[] = { 59 54 "OK", … … 79 74 #define SECOND 1000000 80 75 81 staticUnitTestResult execute_guarded(UnitTest_function fun, long *duration_usec) {76 UnitTestResult execute_guarded(UnitTest_function fun, long *duration_usec) { 82 77 SigHandler old_handler = INSTALL_SIGHANDLER(SIGSEGV, UNITTEST_sigsegv_handler, "execute_guarded"); 83 78 … … 215 210 // it is invoked from code generated by sym2testcode.pl@InvokeUnitTester 216 211 212 TEST_ASSERT_ZERO_OR_SHOW_ERRNO(chdir("run")); 213 217 214 size_t tests = 0; 218 215 size_t passed = 0; … … 238 235 duration_ms, global.warnings)); 239 236 } 240 237 241 238 arb_test::GlobalTestData::erase_instance(); 242 239 exit(tests == passed ? EXIT_SUCCESS : EXIT_FAILURE); -
trunk/UNIT_TESTER/UnitTester.hxx
r6743 r6816 24 24 const char *location; 25 25 }; 26 enum UnitTestResult { 27 TEST_OK, 28 TEST_TRAPPED, 29 }; 26 30 27 31 struct UnitTester { … … 29 33 }; 30 34 35 UnitTestResult execute_guarded(UnitTest_function fun, long *duration_usec); 36 31 37 #else 32 38 #error UnitTester.hxx included twice -
trunk/UNIT_TESTER/test_global.h
r6791 r6816 20 20 #include <cstdio> 21 21 #endif 22 #ifndef _CPP_CERRNO 23 #include <cerrno> 24 #endif 25 #ifndef _CPP_CSTRING 26 #include <cstring> 27 #endif 22 28 29 #if (UNIT_TESTS == 1) 30 31 # if defined(DEVEL_RELEASE) 32 # error Unit testing not allowed in release 33 # endif 34 35 # ifdef __cplusplus 36 37 # define SET_ASSERTION_FAILED_FLAG() arb_test::test_data().assertion_failed = true 38 # define PRINT_ASSERTION_FAILED_MSG(cond) arb_test::GlobalTestData::assertfailmsg(__FILE__, __LINE__, #cond) 39 40 # else 41 # define SET_ASSERTION_FAILED_FLAG() // impossible in C (assertions in C code will be handled like normal SEGV) 42 # define PRINT_ASSERTION_FAILED_MSG(cond) \ 43 do { \ 44 fflush(stdout); \ 45 fflush(stderr); \ 46 fprintf(stderr, "%s:%i: Assertion '%s' failed [C]\n", \ 47 __FILE__, __LINE__, #cond); \ 48 fflush(stderr); \ 49 } while(0) 50 # endif 51 52 # define TRIGGER_ASSERTION() \ 53 do { \ 54 SET_ASSERTION_FAILED_FLAG(); \ 55 ARB_SIGSEGV(0); \ 56 } while(0) 23 57 24 58 namespace arb_test { 59 class FlushedOutputNoLF { 60 inline void flushall() { fflush(stdout); fflush(stderr); } 61 public: 62 FlushedOutputNoLF() { flushall(); } 63 ~FlushedOutputNoLF() { flushall(); } 64 }; 65 struct FlushedOutput : public FlushedOutputNoLF { 66 ~FlushedOutput() { fputc('\n', stderr); } 67 }; 68 25 69 class GlobalTestData { 26 70 GlobalTestData() … … 51 95 static GlobalTestData& get_instance() { return *instance(false); } 52 96 static void erase_instance() { instance(true); } 97 98 static void assertfailmsg(const char *filename, int lineno, const char *condition) { 99 FlushedOutput yes; 100 fprintf(stderr, "%s:%i: Assertion '%s' failed", filename, lineno, condition); 101 } 53 102 }; 54 103 55 104 inline GlobalTestData& test_data() { return GlobalTestData::get_instance(); } 105 }; 56 106 57 58 class FlushedOutput { 59 inline void flushall() { fflush(stdout); fflush(stderr); } 60 public: 61 FlushedOutput() { flushall(); } 62 ~FlushedOutput() { flushall(); } 63 64 #define VPRINTFORMAT(format) do { va_list parg; va_start(parg, format); vfprintf(stderr, format, parg); va_end(parg); } while(0) 65 66 static void printf(const char *format, ...) __attribute__((format(printf, 1, 2))) { 67 FlushedOutput yes; 68 VPRINTFORMAT(format); 69 } 70 static void messagef(const char *filename, int lineno, const char *format, ...) __attribute__((format(printf, 3, 4))) { 71 FlushedOutput yes; 72 fprintf(stderr, "%s:%i: ", filename, lineno); 73 fputc('\n', stderr); 74 VPRINTFORMAT(format); 75 } 76 static void warningf(const char *filename, int lineno, const char *format, ...) __attribute__((format(printf, 3, 4))) { 77 GlobalTestData& global = test_data(); 78 if (global.show_warnings) { 79 FlushedOutput yes; 80 fprintf(stderr, "%s:%i: Warning: ", filename, lineno); 81 VPRINTFORMAT(format); 82 fputc('\n', stderr); 83 global.warnings++; 84 } 85 } 86 static void errorf(const char *filename, int lineno, const char *format, ...) __attribute__((format(printf, 3, 4))) { 87 FlushedOutput yes; 88 fprintf(stderr, "%s:%i: Error: ", filename, lineno); 89 VPRINTFORMAT(format); 90 fputc('\n', stderr); 91 } 92 #undef VPRINTFORMAT 93 }; 107 // -------------------------------------------------------------------------------- 94 108 95 }; 109 // special assert for unit tests (additionally to SEGV it sets a global flag) 110 # define test_assert(cond) \ 111 do { \ 112 if (!(cond)) { \ 113 PRINT_ASSERTION_FAILED_MSG(cond); \ 114 TRIGGER_ASSERTION(); \ 115 } \ 116 } while(0) 117 118 119 // redefine arb_assert with test_assert when compiling for unit tests 120 # if defined(ASSERTION_USED) 121 # undef arb_assert 122 # define arb_assert(cond) test_assert(cond) 123 # endif 124 125 #else // UNIT_TESTS != 1 126 #error test_global.h may only be included if UNIT_TESTS is 1 127 #endif 96 128 97 129 #else -
trunk/UNIT_TESTER/test_unit.h
r6750 r6816 19 19 #include <cstdarg> 20 20 #endif 21 #ifndef ERRNO_H 22 #include <errno.h> 23 #endif 21 24 22 25 #define ENABLE_CRASH_TESTS // comment out this line to get rid of provoked SEGVs (e.g. while debugging test-code) … … 33 36 34 37 namespace arb_test { 35 class FlushedOutput { 36 inline void flushall() { fflush(stdout); fflush(stderr); } 38 39 class StaticCode { 40 static void vcompiler_msg(const char *filename, int lineno, const char *message_type, const char *format, va_list parg) { 41 fprintf(stderr, "%s:%i: ", filename, lineno); 42 if (message_type) fprintf(stderr, "%s: ", message_type); 43 vfprintf(stderr, format, parg); 44 } 45 46 #define WITHVALISTFROM(format,CODE) do { va_list parg; va_start(parg, format); CODE; va_end(parg); } while(0) 47 #define VPRINTFORMAT(format) WITHVALISTFROM(format, vfprintf(stderr, format, parg)) 48 #define VCOMPILERMSG(file,line,msgtype,format) WITHVALISTFROM(format, vcompiler_msg(file, line, msgtype, format, parg)) 49 37 50 public: 38 FlushedOutput() { flushall(); } 39 ~FlushedOutput() { flushall(); } 40 41 #define VPRINTFORMAT(format) do { va_list parg; va_start(parg, format); vfprintf(stderr, format, parg); va_end(parg); } while(0) 42 51 43 52 static void printf(const char *format, ...) __attribute__((format(printf, 1, 2))) { 44 FlushedOutput yes; 45 VPRINTFORMAT(format); 46 } 47 static void messagef(const char *filename, int lineno, const char *format, ...) __attribute__((format(printf, 3, 4))) { 48 FlushedOutput yes; 49 fprintf(stderr, "%s:%i: ", filename, lineno); 53 FlushedOutputNoLF yes; 50 54 VPRINTFORMAT(format); 51 55 } … … 54 58 if (global.show_warnings) { 55 59 FlushedOutput yes; 56 fprintf(stderr, "%s:%i: Warning: ", filename, lineno); 57 VPRINTFORMAT(format); 60 VCOMPILERMSG(filename, lineno, "Warning", format); 58 61 global.warnings++; 59 62 } … … 61 64 static void errorf(const char *filename, int lineno, const char *format, ...) __attribute__((format(printf, 3, 4))) { 62 65 FlushedOutput yes; 63 fprintf(stderr, "%s:%i: Error: ", filename, lineno); 64 VPRINTFORMAT(format); 66 VCOMPILERMSG(filename, lineno, "Error", format); 67 TRIGGER_ASSERTION(); // fake an assertion failure 68 } 69 static void ioerrorf(const char *filename, int lineno, const char *format, ...) __attribute__((format(printf, 3, 4))) { 70 FlushedOutput yes; 71 VCOMPILERMSG(filename, lineno, "Error", format); 72 fprintf(stderr, " (errno=%i='%s')", errno, strerror(errno)); 73 TRIGGER_ASSERTION(); // fake an assertion failure 65 74 } 66 75 #undef VPRINTFORMAT 76 #undef VCOMPILERMSG 77 #undef WITHVALISTFROM 67 78 }; 68 79 … … 75 86 inline void print(size_t z) { fprintf(stderr, "%zu", z); } 76 87 inline void print_hex(size_t z) { fprintf(stderr, "0x%zx", z); } 88 89 inline void print(unsigned char c) { fprintf(stderr, "'%c'", c); } 90 inline void print_hex(unsigned char c) { print_hex(size_t(c)); } 91 92 inline void print(char c) { print((unsigned char)c); } 93 inline void print_hex(char c) { print_hex((unsigned char)c); } 94 95 // dont dup size_t: 77 96 #ifdef ARB_64 78 97 inline void print(unsigned u) { fprintf(stderr, "%u", u); } … … 82 101 inline void print_hex(long unsigned u) { fprintf(stderr, "0x%lux", u); } 83 102 #endif 84 103 85 104 template <typename T1, typename T2> void print_pair(T1 t1, T2 t2) { 86 105 print(t1); … … 94 113 } 95 114 template <typename T1, typename T2> void print_failed_equal(T1 t1, T2 t2) { 96 FlushedOutput yes;115 FlushedOutputNoLF yes; 97 116 fputs("is_equal(", stderr); 98 117 print_pair(t1, t2); … … 108 127 #define NAMEOFTYPE(type) template <> inline const char * nameoftype<>(type) { return #type; } 109 128 NAMEOFTYPE(bool); 129 NAMEOFTYPE(char); 130 NAMEOFTYPE(unsigned char); 110 131 NAMEOFTYPE(int); 111 132 NAMEOFTYPE(unsigned int); … … 135 156 bool equal = strnullequal(s1, s2); 136 157 if (!equal) { 137 FlushedOutput::printf("str_equal('%s',\n"138 " '%s') returns false\n", s1, s2);158 StaticCode::printf("str_equal('%s',\n" 159 " '%s') returns false\n", s1, s2); 139 160 } 140 161 return equal; … … 158 179 bool different = !strnullequal(s1, s2); 159 180 if (!different) { 160 FlushedOutput::printf("str_different('%s', ..) returns false\n", s1);181 StaticCode::printf("str_different('%s', ..) returns false\n", s1); 161 182 } 162 183 return different; … … 169 190 bool in_epsilon_range = diff < epsilon; 170 191 if (!in_epsilon_range) { 171 FlushedOutput::printf("is_similar(%f,%f,%f) returns false\n", d1, d2, epsilon);192 StaticCode::printf("is_similar(%f,%f,%f) returns false\n", d1, d2, epsilon); 172 193 } 173 194 return in_epsilon_range; … … 178 199 } 179 200 201 202 203 inline bool files_are_equal(const char *file1, const char *file2) { 204 const char *error = NULL; 205 FILE *fp1 = fopen(file1, "rb"); 206 FlushedOutputNoLF yes; 207 208 if (!fp1) { 209 StaticCode::printf("can't open '%s'", file1); 210 error = "i/o error"; 211 } 212 else { 213 FILE *fp2 = fopen(file2, "rb"); 214 if (!fp2) { 215 StaticCode::printf("can't open '%s'", file2); 216 error = "i/o error"; 217 } 218 else { 219 const int BLOCKSIZE = 4096; 220 unsigned char *buf1 = (unsigned char*)malloc(BLOCKSIZE); 221 unsigned char *buf2 = (unsigned char*)malloc(BLOCKSIZE); 222 int equal_bytes = 0; 223 bool repositioned = false; 224 225 while (!error) { 226 int read1 = fread(buf1, 1, BLOCKSIZE, fp1); 227 int read2 = fread(buf2, 1, BLOCKSIZE, fp2); 228 int common = read1<read2 ? read1 : read2; 229 230 if (!common) { 231 if (read1 != read2) error = "filesize differs"; 232 break; 233 } 234 235 if (memcmp(buf1, buf2, common) == 0) { 236 equal_bytes += common; 237 } 238 else { 239 int x = 0; 240 while (buf1[x] == buf2[x]) { 241 x++; 242 equal_bytes++; 243 } 244 error = "content differs"; 245 246 // x is the position inside the current block 247 const int DUMP = 7; 248 int y1 = x >= DUMP ? x-DUMP : 0; 249 int y2 = (x+DUMP)>common ? common : (x+DUMP); 250 int blockstart = equal_bytes-x; 251 252 for (int y = y1; y <= y2; y++) { 253 fprintf(stderr, "[0x%04x]", blockstart+y); 254 print_pair(buf1[y], buf2[y]); 255 fputc(' ', stderr); 256 print_hex_pair(buf1[y], buf2[y]); 257 if (x == y) fputs(" <- diff", stderr); 258 fputc('\n', stderr); 259 } 260 if (y2 == common) { 261 fputs("[end of block - truncated]\n", stderr); 262 } 263 } 264 } 265 266 if (error) StaticCode::printf("files_are_equal: equal_bytes=%i\n", equal_bytes); 267 test_assert(error || equal_bytes); // comparing empty files is nonsense 268 269 free(buf2); 270 free(buf1); 271 fclose(fp2); 272 } 273 fclose(fp1); 274 } 275 276 if (error) StaticCode::printf("files_are_equal(%s, %s) fails: %s\n", file1, file2, error); 277 return !error; 278 } 279 180 280 }; 181 281 182 282 // -------------------------------------------------------------------------------- 183 283 184 #define TEST_MSG(format,strarg) arb_test::FlushedOutput::messagef(__FILE__, __LINE__, format, (strarg)) 185 #define TEST_MSG2(format,strarg1,strarg2) arb_test::FlushedOutput::messagef(__FILE__, __LINE__, format, (strarg1), (strarg2)) 186 187 #define TEST_WARNING(format,strarg) arb_test::FlushedOutput::warningf(__FILE__, __LINE__, format, (strarg)) 188 #define TEST_WARNING2(format,strarg1,strarg2) arb_test::FlushedOutput::warningf(__FILE__, __LINE__, format, (strarg1), (strarg2)) 189 190 #define TEST_ERROR(format,strarg) do { arb_test::FlushedOutput::errorf(__FILE__, __LINE__, format, (strarg)); TEST_ASSERT(0); } while(0) 191 #define TEST_ERROR2(format,strarg1,strarg2) do { arb_test::FlushedOutput::errorf(__FILE__, __LINE__, format, (strarg1), (strarg2)); TEST_ASSERT(0); } while(0) 284 #define TEST_WARNING(format,strarg) arb_test::StaticCode::warningf(__FILE__, __LINE__, format, (strarg)) 285 #define TEST_WARNING2(format,strarg1,strarg2) arb_test::StaticCode::warningf(__FILE__, __LINE__, format, (strarg1), (strarg2)) 286 287 #define TEST_ERROR(format,strarg) arb_test::StaticCode::errorf(__FILE__, __LINE__, format, (strarg)) 288 #define TEST_ERROR2(format,strarg1,strarg2) arb_test::StaticCode::errorf(__FILE__, __LINE__, format, (strarg1), (strarg2)) 289 #define TEST_IOERROR(format,strarg) arb_test::StaticCode::ioerrorf(__FILE__, __LINE__, format, (strarg)) 192 290 193 291 // -------------------------------------------------------------------------------- … … 206 304 #define TEST_ASSERT_ZERO(cond) TEST_ASSERT((cond) == 0) 207 305 #define TEST_ASSERT_ZERO__BROKEN(cond) TEST_ASSERT__BROKEN((cond) == 0) 306 307 #define TEST_ASSERT_ZERO_OR_SHOW_ERRNO(iocond) \ 308 do { \ 309 if ((iocond)) \ 310 TEST_IOERROR("I/O-failure in '%s'", #iocond); \ 311 } while(0) 208 312 209 313 // -------------------------------------------------------------------------------- … … 350 454 #define TEST_ASSERT_SIMILAR__BROKEN(t1,t2,epsilon) TEST_ASSERT__BROKEN(arb_test::is_similar(t1, t2, epsilon)) 351 455 456 #define TEST_ASSERT_FILES_EQUAL(f1,f2) TEST_ASSERT(arb_test::files_are_equal(f1,f2)) 457 #define TEST_ASSERT_FILES_EQUAL__BROKEN(f1,f2) TEST_ASSERT__BROKEN(arb_test::files_are_equal(f1,f2)) 458 352 459 #else 353 460 #error test_unit.h included twice
