]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/apr-util/test/abts.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / apr-util / test / abts.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "abts.h"
18 #include "abts_tests.h"
19 #include "testutil.h"
20
21 #define ABTS_STAT_SIZE 6
22 static char status[ABTS_STAT_SIZE] = {'|', '/', '-', '|', '\\', '-'};
23 static int curr_char;
24 static int verbose = 0;
25 static int exclude = 0;
26 static int quiet = 0;
27 static int list_tests = 0;
28
29 const char **testlist = NULL;
30
31 static int find_test_name(const char *testname) {
32     int i;
33     for (i = 0; testlist[i] != NULL; i++) {
34         if (!strcmp(testlist[i], testname)) {
35             return 1;
36         }
37     }
38     return 0;
39 }
40
41 /* Determine if the test should be run at all */
42 static int should_test_run(const char *testname) {
43     int found = 0;
44     if (list_tests == 1) {
45         return 0;
46     }
47     if (testlist == NULL) {
48         return 1;
49     }
50     found = find_test_name(testname);
51     if ((found && !exclude) || (!found && exclude)) {
52         return 1;
53     }
54     return 0;
55 }
56
57 static void reset_status(void)
58 {
59     curr_char = 0;
60 }
61
62 static void update_status(void)
63 {
64     if (!quiet) {
65         curr_char = (curr_char + 1) % ABTS_STAT_SIZE;
66         fprintf(stdout, "\b%c", status[curr_char]);
67         fflush(stdout);
68     }
69 }
70
71 static void end_suite(abts_suite *suite)
72 {
73     if (suite != NULL) {
74         sub_suite *last = suite->tail;
75         if (!quiet) {
76             fprintf(stdout, "\b");
77             fflush(stdout);
78         }
79         if (last->failed == 0) {
80             fprintf(stdout, "SUCCESS\n");
81             fflush(stdout);
82         }
83         else {
84             fprintf(stdout, "FAILED %d of %d\n", last->failed, last->num_test);
85             fflush(stdout);
86         }
87     }
88 }
89
90 abts_suite *abts_add_suite(abts_suite *suite, const char *suite_name_full)
91 {
92     sub_suite *subsuite;
93     char *p;
94     const char *suite_name;
95     curr_char = 0;
96     
97     /* Only end the suite if we actually ran it */
98     if (suite && suite->tail &&!suite->tail->not_run) {
99         end_suite(suite);
100     }
101
102     subsuite = malloc(sizeof(*subsuite));
103     subsuite->num_test = 0;
104     subsuite->failed = 0;
105     subsuite->next = NULL;
106     /* suite_name_full may be an absolute path depending on __FILE__ 
107      * expansion */
108     suite_name = strrchr(suite_name_full, '/');
109     if (!suite_name) {
110         suite_name = strrchr(suite_name_full, '\\');
111     }
112     if (suite_name) {
113         suite_name++;
114     } else {
115         suite_name = suite_name_full;
116     }
117     p = strrchr(suite_name, '.');
118     if (p) {
119         subsuite->name = memcpy(calloc(p - suite_name + 1, 1),
120                                 suite_name, p - suite_name);
121     }
122     else {
123         subsuite->name = suite_name;
124     }
125
126     if (list_tests) {
127         fprintf(stdout, "%s\n", subsuite->name);
128     }
129     
130     subsuite->not_run = 0;
131
132     if (suite == NULL) {
133         suite = malloc(sizeof(*suite));
134         suite->head = subsuite;
135         suite->tail = subsuite;
136     }
137     else {
138         suite->tail->next = subsuite;
139         suite->tail = subsuite;
140     }
141
142     if (!should_test_run(subsuite->name)) {
143         subsuite->not_run = 1;
144         return suite;
145     }
146
147     reset_status();
148     fprintf(stdout, "%-20s:  ", subsuite->name);
149     update_status();
150     fflush(stdout);
151
152     return suite;
153 }
154
155 void abts_run_test(abts_suite *ts, test_func f, void *value)
156 {
157     abts_case *tc;
158     sub_suite *ss;
159
160     if (!should_test_run(ts->tail->name)) {
161         return;
162     }
163     ss = ts->tail;
164
165     tc = malloc(sizeof(*tc));
166     tc->failed = 0;
167     tc->suite = ss;
168     
169     ss->num_test++;
170     update_status();
171
172     f(tc, value);
173     
174     if (tc->failed) {
175         ss->failed++;
176     }
177     free(tc);
178 }
179
180 static int report(abts_suite *suite)
181 {
182     int count = 0;
183     sub_suite *dptr;
184
185     if (suite && suite->tail &&!suite->tail->not_run) {
186         end_suite(suite);
187     }
188
189     for (dptr = suite->head; dptr; dptr = dptr->next) {
190         count += dptr->failed;
191     }
192
193     if (list_tests) {
194         return 0;
195     }
196
197     if (count == 0) {
198         printf("All tests passed.\n");
199         return 0;
200     }
201
202     dptr = suite->head;
203     fprintf(stdout, "%-15s\t\tTotal\tFail\tFailed %%\n", "Failed Tests");
204     fprintf(stdout, "===================================================\n");
205     while (dptr != NULL) {
206         if (dptr->failed != 0) {
207             float percent = ((float)dptr->failed / (float)dptr->num_test);
208             fprintf(stdout, "%-15s\t\t%5d\t%4d\t%6.2f%%\n", dptr->name, 
209                     dptr->num_test, dptr->failed, percent * 100);
210         }
211         dptr = dptr->next;
212     }
213     return 1;
214 }
215
216 void abts_log_message(const char *fmt, ...)
217 {
218     va_list args;
219     update_status();
220
221     if (verbose) {
222         va_start(args, fmt);
223         vfprintf(stderr, fmt, args);
224         va_end(args);
225         fprintf(stderr, "\n");
226         fflush(stderr);
227     }
228 }
229
230 void abts_int_equal(abts_case *tc, const int expected, const int actual, int lineno)
231 {
232     update_status();
233     if (tc->failed) return;
234
235     if (expected == actual) return;
236
237     tc->failed = TRUE;
238     if (verbose) {
239         fprintf(stderr, "Line %d: expected <%d>, but saw <%d>\n", lineno, expected, actual);
240         fflush(stderr);
241     }
242 }
243
244 void abts_int_nequal(abts_case *tc, const int expected, const int actual, int lineno)
245 {
246     update_status();
247     if (tc->failed) return;
248
249     if (expected != actual) return;
250
251     tc->failed = TRUE;
252     if (verbose) {
253         fprintf(stderr, "Line %d: expected something other than <%d>, but saw <%d>\n",
254                 lineno, expected, actual);
255         fflush(stderr);
256     }
257 }
258
259 void abts_str_equal(abts_case *tc, const char *expected, const char *actual, int lineno)
260 {
261     update_status();
262     if (tc->failed) return;
263
264     /* If both are NULL, match is good */
265     if (!expected && !actual) return;
266     if (expected && actual)
267         if (!strcmp(expected, actual)) return;
268
269     tc->failed = TRUE;
270     if (verbose) {
271         fprintf(stderr, "Line %d: expected <%s>, but saw <%s>\n", lineno, expected, actual);
272         fflush(stderr);
273     }
274 }
275
276 void abts_str_nequal(abts_case *tc, const char *expected, const char *actual,
277                        size_t n, int lineno)
278 {
279     update_status();
280     if (tc->failed) return;
281
282     if (!strncmp(expected, actual, n)) return;
283
284     tc->failed = TRUE;
285     if (verbose) {
286         fprintf(stderr, "Line %d: expected something other than <%s>, but saw <%s>\n",
287                 lineno, expected, actual);
288         fflush(stderr);
289     }
290 }
291
292 void abts_ptr_notnull(abts_case *tc, const void *ptr, int lineno)
293 {
294     update_status();
295     if (tc->failed) return;
296
297     if (ptr != NULL) return;
298
299     tc->failed = TRUE;
300     if (verbose) {
301         fprintf(stderr, "Line %d: expected non-NULL, but saw NULL\n", lineno);
302         fflush(stderr);
303     }
304 }
305  
306 void abts_ptr_equal(abts_case *tc, const void *expected, const void *actual, int lineno)
307 {
308     update_status();
309     if (tc->failed) return;
310
311     if (expected == actual) return;
312
313     tc->failed = TRUE;
314     if (verbose) {
315         fprintf(stderr, "Line %d: expected <%p>, but saw <%p>\n", lineno, expected, actual);
316         fflush(stderr);
317     }
318 }
319
320 void abts_fail(abts_case *tc, const char *message, int lineno)
321 {
322     update_status();
323     if (tc->failed) return;
324
325     tc->failed = TRUE;
326     if (verbose) {
327         fprintf(stderr, "Line %d: %s\n", lineno, message);
328         fflush(stderr);
329     }
330 }
331  
332 void abts_assert(abts_case *tc, const char *message, int condition, int lineno)
333 {
334     update_status();
335     if (tc->failed) return;
336
337     if (condition) return;
338
339     tc->failed = TRUE;
340     if (verbose) {
341         fprintf(stderr, "Line %d: %s\n", lineno, message);
342         fflush(stderr);
343     }
344 }
345
346 void abts_true(abts_case *tc, int condition, int lineno)
347 {
348     update_status();
349     if (tc->failed) return;
350
351     if (condition) return;
352
353     tc->failed = TRUE;
354     if (verbose) {
355         fprintf(stderr, "Line %d: Condition is false, but expected true\n", lineno);
356         fflush(stderr);
357     }
358 }
359
360 void abts_not_impl(abts_case *tc, const char *message, int lineno)
361 {
362     update_status();
363
364     tc->suite->not_impl++;
365     if (verbose) {
366         fprintf(stderr, "Line %d: %s\n", lineno, message);
367         fflush(stderr);
368     }
369 }
370
371 int main(int argc, const char *const argv[]) {
372     int i;
373     int rv;
374     int list_provided = 0;
375     abts_suite *suite = NULL;
376    
377     initialize();
378
379     quiet = !isatty(STDOUT_FILENO);
380
381     for (i = 1; i < argc; i++) {
382         if (!strcmp(argv[i], "-v")) {
383             verbose = 1;
384             continue;
385         }
386         if (!strcmp(argv[i], "-x")) {
387             exclude = 1;
388             continue;
389         }
390         if (!strcmp(argv[i], "-l")) {
391             list_tests = 1;
392             continue;
393         }
394         if (!strcmp(argv[i], "-q")) {
395             quiet = 1;
396             continue;
397         }
398         if (argv[i][0] == '-') {
399             fprintf(stderr, "Invalid option: `%s'\n", argv[i]);
400             exit(1);
401         }
402         list_provided = 1;
403     }
404
405     if (list_provided) {
406         /* Waste a little space here, because it is easier than counting the
407          * number of tests listed.  Besides it is at most three char *.
408          */
409         testlist = calloc(argc + 1, sizeof(char *));
410         for (i = 1; i < argc; i++) {
411             testlist[i - 1] = argv[i];
412         }
413     }
414
415     for (i = 0; i < (sizeof(alltests) / sizeof(struct testlist *)); i++) {
416         suite = alltests[i].func(suite);
417         apr_pool_clear(p);
418     }
419
420     rv = report(suite);
421     return rv;
422 }
423