Change logging a bit in ZOOM's Z39.50 layer
[yaz-moved-to-github.git] / src / test.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5
6 /** \file test.c
7     \brief Unit Test for YAZ
8 */
9
10 #if HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14 #include <stdio.h>
15 #include <string.h>
16 #include <stdlib.h>
17 #if HAVE_UNISTSD_H
18 #include <unistd.h>
19 #endif
20
21 #include <yaz/test.h>
22 #include <yaz/log.h>
23
24 static FILE *test_fout = 0; /* can't use '= stdout' on some systems */
25 static int test_total = 0;
26 static int test_failed = 0;
27 static int test_todo = 0;
28 static int test_verbose = 1;
29 static const char *test_prog = 0;
30 static int log_tests = 0;
31 static int test_stop = 0;
32
33 static FILE *get_file(void)
34 {
35     if (test_fout)
36         return test_fout;
37     return stdout;
38 }
39
40 static const char *progname(const char *argv0)
41 {
42     const char *cp = strrchr(argv0, '/');
43     if (cp)
44         return cp+1;
45     cp = strrchr(argv0, '\\');
46     if (cp)
47         return cp+1;
48     return argv0;
49 }
50
51 void yaz_check_init1(int *argc_p, char ***argv_p)
52 {
53     int i = 0;
54     int argc = *argc_p;
55     char **argv = *argv_p;
56
57     test_prog = progname(argv[0]);
58
59     for (i = 1; i<argc; i++)
60     {
61         if (strlen(argv[i]) >= 7 && !memcmp(argv[i], "--test-", 7))
62         {
63             const char *suf = argv[i]+7;
64             if (i < argc-1 && !strcmp(suf, "file"))
65             {
66                 i++;
67                 if (test_fout)
68                     fclose(test_fout);
69                 test_fout = fopen(argv[i], "w");
70                 continue;
71             }
72             else if (i < argc-1 && !strcmp(suf, "verbose"))
73             {
74                 i++;
75                 test_verbose = atoi(argv[i]);
76                 continue;
77             }
78             else if (i < argc && !strcmp(suf, "stop"))
79             {
80                 test_stop = 1;
81                 continue;
82             }
83             else if (!strcmp(suf, "help"))
84             {
85                 fprintf(stderr,
86                         "--test-help           help\n"
87                         "--test-file fname     output to fname\n"
88                         "--test-stop           stop at first failing test\n"
89                         "--test-verbose level  verbose level\n"
90                         "       0=Quiet. Only exit code tells what's wrong\n"
91                         "       1=Report+Summary only if tests fail.\n"
92                         "       2=Report failures. Print summary always\n"
93                         "       3=Report + summary always\n"
94                         "       4=Report + summary + extra prints from tests\n"
95                     );
96                 exit(0);
97             }
98             else
99             {
100                 fprintf(stderr, "Unrecognized option for YAZ test: %s\n",
101                         argv[i]);
102                 fprintf(stderr, "Use --test-help for more info\n");
103                 exit(1);
104             }
105
106         }
107         break;
108     }
109     /* remove --test- options from argc, argv so that they disappear */
110     (*argv_p)[i-1] = **argv_p;  /* program name */
111     --i;
112     *argc_p -= i;
113     *argv_p += i;
114 }
115
116 /** \brief  Initialize the log system */
117 void yaz_check_init_log(const char *argv0)
118 {
119     char logfilename[2048];
120     log_tests = 1;
121     sprintf(logfilename,"%s.log", progname(argv0) );
122     yaz_log_init_file(logfilename);
123     yaz_log_trunc();
124
125 }
126
127 void  yaz_check_inc_todo(void)
128 {
129     test_todo++;
130 }
131
132 void yaz_check_term1(void)
133 {
134     /* summary */
135     if (test_failed)
136     {
137         if (test_verbose >= 1) {
138             if (test_todo)
139                 fprintf(get_file(), "%d out of %d tests failed for program %s"
140                         " (%d TODO's remaining)\n",
141                     test_failed, test_total, test_prog,test_todo);
142             else
143                 fprintf(get_file(), "%d out of %d tests failed for program %s\n",
144                     test_failed, test_total, test_prog);
145         }
146     }
147     else
148     {
149         if (test_verbose >= 2) {
150             if (test_todo)
151                 fprintf(get_file(), "%d tests passed for program %s"
152                         " (%d TODO's remaining)\n",
153                     test_total, test_prog,test_todo);
154             else
155                 fprintf(get_file(), "%d tests passed for program %s\n",
156                     test_total, test_prog);
157         }
158     }
159     if (test_fout)
160         fclose(test_fout);
161     if (test_failed)
162         exit(1);
163     exit(0);
164 }
165
166 void yaz_check_eq1(int type, const char *file, int line,
167                    const char *left, const char *right, int lval, int rval)
168 {
169     char formstr[2048];
170
171     if (type == YAZ_TEST_TYPE_OK)
172         sprintf(formstr, "%.500s == %.500s ", left, right);
173     else
174         sprintf(formstr, "%.500s != %.500s\n %d != %d", left, right, lval,rval);
175     yaz_check_print1(type, file, line, formstr);
176 }
177
178 void yaz_check_print1(int type, const char *file, int line,
179                       const char *expr)
180 {
181     const char *msg = "unknown";
182     int printit = 1;
183
184     test_total++;
185     switch(type)
186     {
187     case YAZ_TEST_TYPE_FAIL:
188         test_failed++;
189         msg = "FAILED";
190         if (test_verbose < 1)
191             printit = 0;
192         break;
193     case YAZ_TEST_TYPE_OK:
194         msg = "ok";
195         if (test_verbose < 3)
196             printit = 0;
197         break;
198     }
199     if (printit)
200     {
201         fprintf(get_file(), "%s:%d: %s: ", file, line, msg);
202         fprintf(get_file(), "%s\n", expr);
203     }
204     if (log_tests)
205     {
206         yaz_log(YLOG_LOG, "%s:%d %s: ", file, line, msg);
207         yaz_log(YLOG_LOG, "%s", expr);
208     }
209     if ( type == YAZ_TEST_TYPE_FAIL && test_stop )
210     {
211         exit(1);
212     }
213 }
214
215
216 int yaz_test_get_verbosity()
217 {
218     return test_verbose;
219 }
220
221 /*
222  * Local variables:
223  * c-basic-offset: 4
224  * c-file-style: "Stroustrup"
225  * indent-tabs-mode: nil
226  * End:
227  * vim: shiftwidth=4 tabstop=8 expandtab
228  */
229