9#include "tpcclibConfig.h"
22double ROUGH_TEST_LIMIT=0.01;
23double AROUND_TEST_LIMIT=0.05;
27static char *info[] = {
28 "Verify that two result files do have matching contents;",
29 "this can be used for automating software and analysis tool testing.",
30 "Programs return code is 0, if files were matching, 10, if the files did",
31 "not match, and 1-9 in case of error.",
33 "Usage: @P [Options] file1 file2",
37 " Header fields are verified (y) or not verified (n, default)",
38 " -param[eters]=<y|N>",
39 " Parameter names are verified (y) or not verified (n, default)",
41 " Region names are verified (y) or not verified (n, default)",
42 " -res[ults]=<List of result column numbers (e.g. -res=1-2 or -res=1,3)>",
43 " By default all result values are verified. With this option,",
44 " only selected columns (or none with -res=0) are verified.",
46 " Result values are required to match roughly (<2% difference allowed).",
48 " Results are required to be around the same (<10% difference allowed).",
50 " Absolute result differences must not exceed the specified limit value",
52 " Result errors (SD, CL) are verified (y, default) or not verified (n)",
55 "See also: reslist, res2html, resdel, pardiff, fit2res, tacmatch, imgmatch",
57 "Keywords: results, tool, software testing",
76int main(
int argc,
char **argv)
78 int ai, help=0, version=0, verbose=1;
79 int pi, ri, n, test_nr=0, ret, ok=0;
80 char *cptr, resfile1[FILENAME_MAX], resfile2[FILENAME_MAX];
89 double test_limit=1.0E-15;
96 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
97 resfile1[0]=resfile2[0]=(char)0;
100 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
103 if(strncasecmp(cptr,
"HEADER=", 7)==0) {
105 if(strncasecmp(cptr,
"YES", 1)==0) {header=1;
continue;}
106 else if(strncasecmp(cptr,
"NO", 1)==0) {header=0;
continue;}
107 }
else if(strncasecmp(cptr,
"PARAMETERS=", 11)==0) {
109 if(strncasecmp(cptr,
"YES", 1)==0) {parameters=1;
continue;}
110 else if(strncasecmp(cptr,
"NO", 1)==0) {parameters=0;
continue;}
111 }
else if(strncasecmp(cptr,
"PARAM=", 6)==0) {
113 if(strncasecmp(cptr,
"YES", 1)==0) {parameters=1;
continue;}
114 else if(strncasecmp(cptr,
"NO", 1)==0) {parameters=0;
continue;}
115 }
else if(strncasecmp(cptr,
"REGIONS=", 8)==0) {
117 if(strncasecmp(cptr,
"YES", 1)==0) {regions=1;
continue;}
118 else if(strncasecmp(cptr,
"NO", 1)==0) {regions=0;
continue;}
119 }
else if(strncasecmp(cptr,
"ROUGHLY", 5)==0) {
120 rough_test=1; test_limit=ROUGH_TEST_LIMIT;
121 if(test_abs<0.0)
continue;
122 }
else if(strncasecmp(cptr,
"AROUND", 5)==0) {
123 rough_test=2; test_limit=AROUND_TEST_LIMIT;
continue;
124 }
else if(strncasecmp(cptr,
"RESULTS=", 8)==0) {
127 if(ret==0 && parlist.
nr>0 && parlist.
i[0]>=0)
continue;
129 }
else if(strncasecmp(cptr,
"RES=", 4)==0) {
132 if(ret==0 && parlist.
nr>0 && parlist.
i[0]>=0)
continue;
134 }
else if(strncasecmp(cptr,
"ABS=", 4)==0) {
136 if(test_abs>=0.0 && rough_test==0)
continue;
137 }
else if(strncasecmp(cptr,
"ERRORS=", 7)==0) {
139 if(strncasecmp(cptr,
"YES", 1)==0) {test_errors=1;
continue;}
140 else if(strncasecmp(cptr,
"NO", 1)==0) {test_errors=0;
continue;}
142 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
143 if(parlist.
nr>0) free(parlist.
i);
148 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
153 for(; ai<argc; ai++) {
155 strlcpy(resfile1, argv[ai], FILENAME_MAX);
continue;
156 }
else if(!resfile2[0]) {
157 strlcpy(resfile2, argv[ai], FILENAME_MAX);
continue;
159 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
160 if(parlist.
nr>0) free(parlist.
i);
166 fprintf(stderr,
"Error: missing result file name.\n");
167 if(parlist.
nr>0) free(parlist.
i);
173 printf(
"resfile1 := %s\n", resfile1);
174 printf(
"resfile2 := %s\n", resfile2);
175 printf(
"header := %d\n", header);
176 printf(
"parameters := %d\n", parameters);
177 printf(
"regions := %d\n", regions);
178 printf(
"rough_test := %d\n", rough_test);
179 printf(
"test_limit := %g\n", test_limit);
180 printf(
"test_abs := %g\n", test_abs);
181 printf(
"test_errors := %d\n", test_errors);
182 printf(
"results :=");
183 for(pi=0; pi<parlist.
nr; pi++) printf(
" %d", parlist.
i[pi]);
192 if(verbose>0) printf(
"reading results\n");
193 if(
resRead(resfile1, &res1, verbose-2)) {
194 fprintf(stderr,
"Error in reading '%s': %s\n", resfile1,
reserrmsg);
198 if(
resRead(resfile2, &res2, verbose-2)) {
199 fprintf(stderr,
"Error in reading '%s': %s\n", resfile2,
reserrmsg);
204 if(parlist.
nr>0 && parlist.
i[0]>0) {
205 for(pi=0; pi<parlist.
nr; pi++)
if(parlist.
i[pi]>res1.
parNr) {
206 fprintf(stderr,
"Error: results do not contain required column %d\n",
214 printf(
"file1 := %s\n", resfile1);
215 printf(
"file2 := %s\n", resfile2);
221 if(verbose>0) printf(
"testing number of regions\n");
223 if(verbose>=0) fprintf(stdout,
"result := no match\n");
232 if(verbose>0) printf(
"testing number of parameters\n");
235 if(parlist.
nr<=0) ok=0;
236 else if(parlist.
nr==1 && parlist.
i[0]==0) ok=1;
237 else for(pi=0, ok=1; pi<parlist.
nr; pi++)
238 if(parlist.
i[pi]>res1.
parNr || parlist.
i[pi]>res2.
parNr) {ok=0;
break;}
240 if(verbose>=0) fprintf(stdout,
"result := no match\n");
251 if(verbose>0) printf(
"testing header\n");
254 fprintf(stdout,
"result := no match in header field (%d)\n", ret);
267 if(verbose>0) printf(
"testing regions\n");
269 if(verbose>=0) fprintf(stdout,
"result := no match in regions\n");
280 if(verbose>0) printf(
"testing regions\n");
282 if(verbose>=0) fprintf(stdout,
"result := no match in parameter names\n");
292 if(parlist.
nr==1 && parlist.
i[0]==0) {
293 if(verbose>0) printf(
"parameter values are NOT tested\n");
295 if(verbose>0) printf(
"testing parameter values\n");
296 for(ri=0, n=0; ri<res1.
parNr; ri++) {
298 for(pi=ok=0; pi<parlist.
nr; pi++)
if(ri==parlist.
i[pi]-1) {ok=1;
break;}
302 if(verbose>2) printf(
" test parameter values for col %d\n", ri+1);
308 if(verbose>1) printf(
" ret:=%d\n", ret);
309 if(verbose>=0) fprintf(stdout,
"result := no match in parameter values (column %d)\n", ri+1);
311 for(
int i=0; i<res1.
voiNr; i++)
323 fprintf(stdout,
"result := match was found\n");
324 fprintf(stdout,
"nr_of_tests := %d\n", test_nr);
328 if(parlist.
nr>0) free(parlist.
i);
double atof_dpi(char *str)
int intExpand(char *text, INT_list *list)
Header file for libtpccurveio.
int resMatchRegions(RES *res1, RES *res2)
int resMatchParameternames(RES *res1, RES *res2)
int resRead(char *filename, RES *res, int verbose)
int resMatchParameters(RES *res1, RES *res2, int test_par, double test_limit, int test_sd)
int resMatchHeader(RES *res1, RES *res2)
int resMatchParametersAbs(RES *res1, RES *res2, int test_par, double test_limit, int test_sd)
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
double parameter[MAX_RESPARAMS]