Changeset 6816 for trunk/UNIT_TESTER/test_unit.h
- Timestamp:
- 09/09/10 22:40:57 (21 months ago)
- Location:
- trunk/UNIT_TESTER
- Files:
-
- 2 modified
-
. (modified) (1 prop)
-
test_unit.h (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/UNIT_TESTER
- Property svn:ignore
-
old new 5 5 *.gcno 6 6 logs 7 test_environment
-
- Property svn:ignore
-
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
