00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 # include <config.h>
00022 #endif
00023
00024
00025
00026
00027
00028 #include <test.h>
00029
00030 #include <fors_utils.h>
00031
00032 #include <cpl.h>
00033 #include <math.h>
00034 #include <string.h>
00035
00036
00040
00041
00042
00043
00044
00045
00049 static unsigned long test_nfail = 0;
00050 static cpl_errorstate error_init;
00051
00052
00061
00062 static void
00063 _test(int expression, const char *message,
00064 const char *function, const char *file, unsigned line)
00065 {
00066 const char *error_state = (cpl_error_get_code() != CPL_ERROR_NONE) ?
00067 cpl_sprintf(" (CPL-error state: '%s' at %s)",
00068 cpl_error_get_message(), cpl_error_get_where()) :
00069 NULL;
00070
00071 if (expression) {
00072 cpl_msg_debug(function,
00073 "OK at %s:%u%s: %s",
00074 file, line, error_state != NULL ? error_state : "",
00075 message);
00076 } else {
00077 if (test_nfail + 1 > test_nfail) {
00078 test_nfail++;
00079 }
00080 else {
00081 cpl_msg_error(function, "Number of errors (%lu) overflow!",
00082 test_nfail);
00083 }
00084
00085 cpl_msg_error(function,
00086 "Failure at %s:%u%s: %s",
00087 file, line, error_state != NULL ? error_state : "",
00088 message);
00089 }
00090
00091 if (error_state != NULL)
00092 {
00093 cpl_free((char *)error_state);
00094 }
00095
00096 return;
00097 }
00098
00099
00100
00110
00111 void
00112 test_macro(int expression, const char *expr_string,
00113 const char *function, const char *file, unsigned line)
00114 {
00115 const char *message = cpl_sprintf("(%s) = %d", expr_string, expression);
00116
00117 _test(expression, message,
00118 function, file, line);
00119
00120 cpl_free((char *)message);
00121
00122 return;
00123 }
00124
00125
00137
00138 void
00139 test_eq_macro(int first, const char *first_string,
00140 int second, const char *second_string,
00141 const char *function, const char *file, unsigned line)
00142 {
00143 const char *message =
00144 cpl_sprintf("(%s) = %d; (%s) = %d",
00145 first_string, first,
00146 second_string, second);
00147
00148 _test(first == second, message,
00149 function, file, line);
00150
00151 cpl_free((char *)message);
00152
00153 return;
00154 }
00155
00156
00168
00169 void
00170 test_eq_string_macro(const char *first, const char *first_string,
00171 const char *second, const char *second_string,
00172 const char *function,
00173 const char *file, unsigned line)
00174 {
00175 const char *message;
00176
00177 message = cpl_sprintf("%s = '%s'; %s = '%s'",
00178 first_string, first != NULL ? first : "NULL",
00179 second_string, second != NULL ? second : "NULL");
00180
00181 _test(first != NULL && second != NULL && strcmp(first, second) == 0,
00182 message,
00183 function, file, line);
00184
00185 cpl_free((char *)message);
00186
00187 return;
00188 }
00189
00190
00206
00207 void
00208 test_abs_macro(double first, const char *first_string,
00209 double second, const char *second_string,
00210 double tolerance, const char *tolerance_string,
00211 const char *function, const char *file, unsigned line)
00212 {
00213 const char *message =
00214 cpl_sprintf("|%s - (%s)| = |%g - (%g)| <= %g = %s",
00215 first_string, second_string, first, second,
00216 tolerance, tolerance_string);
00217
00218 _test(fabs(first - second) <= tolerance, message,
00219 function, file, line);
00220
00221
00222 cpl_free((char *)message);
00223
00224 return;
00225 }
00226
00227
00243
00244 void
00245 test_rel_macro(double first, const char *first_string,
00246 double second, const char *second_string,
00247 double tolerance, const char *tolerance_string,
00248 const char *function, const char *file, unsigned line)
00249 {
00250 const char *message;
00251
00252 if (first == 0 || second == 0) {
00253
00254 message = cpl_sprintf("%s = %g; %s = %g (division by zero)",
00255 first_string, first,
00256 second_string, second);
00257 _test(0, message,
00258 function, file, line);
00259 }
00260 else {
00261 message =
00262 cpl_sprintf("|%s - (%s)|/|%s| = |%g - (%g)|/|%g| <= %g = %s and "
00263 "|%s - (%s)|/|%s| = |%g - (%g)|/|%g| <= %g = %s",
00264 first_string, second_string, first_string,
00265 first, second, first, tolerance, tolerance_string,
00266 first_string, second_string, second_string,
00267 first, second, second, tolerance, tolerance_string);
00268
00269 _test(fabs((first - second)/first ) <= tolerance &&
00270 fabs((first - second)/second) <= tolerance, message,
00271 function, file, line);
00272
00273 }
00274
00275 cpl_free((char *)message);
00276
00277 return;
00278 }
00279
00280
00281
00288
00289 void
00290 test_init_macro(const char *file)
00291 {
00292
00293
00294
00295 unsigned len = strlen(file);
00296 int able_to_parse_filename;
00297
00298 cpl_init(CPL_INIT_DEFAULT);
00299 error_init = cpl_errorstate_get();
00300 srand(0);
00301
00302 if (len < strlen("s.c") || strcmp(file + len - strlen(".c"), ".c") != 0)
00303 {
00304 able_to_parse_filename = 0;
00305
00306
00307 }
00308 else
00309 {
00310
00311
00312
00313 const char dir_delimiter = '/';
00314 unsigned path_length = 0;
00315
00316 int i;
00317
00318 for (i = len - strlen(".c") - 1; i >= 0; i--)
00319 {
00320 if (file[i] == dir_delimiter && path_length == 0)
00321 {
00322 path_length = i + 1;
00323 }
00324 }
00325
00326 able_to_parse_filename = (len - path_length - strlen(".c") >= 1);
00327 if (able_to_parse_filename)
00328 {
00329 const char *logfile;
00330 char *domain;
00331
00332 domain = cpl_strdup(file + path_length);
00333 domain[len - path_length - strlen(".c")] = '\0';
00334
00335 cpl_msg_set_domain(domain);
00336
00337 logfile = cpl_sprintf("%s.log", domain);
00338 cpl_msg_set_log_name(logfile);
00339
00340 cpl_free((char *)logfile);
00341 cpl_free(domain);
00342 }
00343
00344 }
00345
00346
00347
00348
00349 cpl_msg_set_level(CPL_MSG_WARNING);
00350 cpl_msg_set_log_level(CPL_MSG_DEBUG);
00351
00352 if (!able_to_parse_filename)
00353 {
00354 cpl_msg_warning(cpl_func,
00355 "Source file name '%s' does not match [base].c. ",
00356 file);
00357 }
00358
00359 if (cpl_error_get_code() != CPL_ERROR_NONE)
00360 {
00361 cpl_msg_error(cpl_func,
00362 "Failure during initialization: %s at %s",
00363 cpl_error_get_message(), cpl_error_get_where());
00364 }
00365
00366 return;
00367 }
00368
00369
00379
00380 unsigned
00381 test_end_macro(const char *function, const char *file, unsigned line)
00382 {
00383 const int memory_is_empty = cpl_memory_is_empty();
00384
00385 test_eq_macro(cpl_error_get_code(), "cpl_error_get_code()",
00386 CPL_ERROR_NONE, "CPL_ERROR_NONE",
00387 function, file, line);
00388
00389 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00390 cpl_errorstate_dump(error_init, CPL_FALSE, NULL);
00391 }
00392
00393 test_macro(memory_is_empty,
00394 "memory_is_empty",
00395 function, file, line);
00396
00397 if (!memory_is_empty) {
00398 cpl_msg_error(function, "Memory leak detected:");
00399 cpl_memory_dump();
00400 }
00401
00402 cpl_end();
00403
00404 return test_nfail;
00405 }
00406
00407
00408
00409
00410
00411 #undef cleanup
00412 #define cleanup \
00413 do { \
00414 cpl_propertylist_delete(product_header); \
00415 } while(0)
00416
00426
00427 void
00428 test_recipe_output(const cpl_frameset *frames,
00429 const char *const product_tags[], int n_prod,
00430 const char *main_product,
00431 const char *const qc[], int n_qc)
00432 {
00433 cpl_propertylist *product_header = NULL;
00434
00435 int i;
00436 for (i = 0; i < n_prod; i++) {
00437 const cpl_frame *product = cpl_frameset_find_const(frames, product_tags[i]);
00438 test( product != NULL );
00439 test_eq( cpl_frame_get_group(product), CPL_FRAME_GROUP_PRODUCT );
00440
00441 cpl_propertylist_delete(product_header);
00442 product_header = cpl_propertylist_load(cpl_frame_get_filename(product), 0);
00443
00444 assure( !cpl_error_get_code(), return,
00445 "Failed to load product header" );
00446
00447
00448 if (strcmp(product_tags[i], main_product) == 0) {
00449
00450 test( cpl_propertylist_has(product_header,
00451 "ESO QC DID") );
00452 }
00453 else {
00454 test( !cpl_propertylist_has(product_header,
00455 "ESO QC DID") );
00456 }
00457
00458 int j;
00459 for (j = 0; j < n_qc; j++) {
00460
00461 const char *full_qc_name = cpl_sprintf("ESO %s", qc[j]);
00462
00463 cpl_msg_debug(cpl_func,
00464 "Looking for '%s' in '%s'",
00465 qc[j], product_tags[i]);
00466
00467 if (strcmp(product_tags[i], main_product) == 0) {
00468 test( cpl_propertylist_has(product_header,
00469 full_qc_name) );
00470 }
00471 else {
00472 test( !cpl_propertylist_has(product_header,
00473 full_qc_name) );
00474 }
00475
00476 cpl_free((void *)full_qc_name);
00477 }
00478 }
00479
00480 cleanup;
00481 return;
00482 }
00483