upload http
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr / test / CuTest.c
1 /*
2  * Copyright (c) 2002-2006 Asim Jalis
3  * 
4  * This library is released under the zlib/libpng license as described at
5  * 
6  * http://www.opensource.org/licenses/zlib-license.html
7  * 
8  * Here is the statement of the license:
9  * 
10  * This software is provided 'as-is', without any express or implied warranty. 
11  * In no event will the authors be held liable for any damages arising from 
12  * the use of this software.
13  * 
14  * Permission is granted to anyone to use this software for any purpose, 
15  * including commercial applications, and to alter it and redistribute it 
16  * freely, subject to the following restrictions:
17  * 
18  * 1. The origin of this software must not be misrepresented; you must not 
19  * claim that you wrote the original software. If you use this software in a 
20  * product, an acknowledgment in the product documentation would be 
21  * appreciated but is not required.
22  * 
23  * 2. Altered source versions must be plainly marked as such, and must not be
24  * misrepresented as being the original software.
25  * 
26  * 3. This notice may not be removed or altered from any source distribution.
27  */
28 /*
29  * This file has been modified from the original distribution.
30  */
31
32 #include <assert.h>
33 #include <setjmp.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37
38 #include "CuTest.h"
39
40 static int verbose = 0;
41
42 void CuInit(int argc, char *argv[])
43 {
44         int i;
45         
46         /* Windows doesn't have getopt, so we have to fake it.  We can't use
47          * apr_getopt, because CuTest is meant to be a stand-alone test suite
48          */
49         for (i = 0; i < argc; i++) {
50                 if (!strcmp(argv[i], "-v")) {
51                         verbose = 1;
52                 }
53         }
54 }
55
56 /*-------------------------------------------------------------------------*
57  * CuStr
58  *-------------------------------------------------------------------------*/
59
60 char* CuStrAlloc(int size)
61 {
62         char* new = (char*) malloc( sizeof(char) * (size) );
63         return new;
64 }
65
66 char* CuStrCopy(const char* old)
67 {
68         int len = strlen(old);
69         char* new = CuStrAlloc(len + 1);
70         strcpy(new, old);
71         return new;
72 }
73
74 /*-------------------------------------------------------------------------*
75  * CuString
76  *-------------------------------------------------------------------------*/
77
78 void CuStringInit(CuString* str)
79 {
80         str->length = 0;
81         str->size = STRING_MAX;
82         str->buffer = (char*) malloc(sizeof(char) * str->size);
83         str->buffer[0] = '\0';
84 }
85
86 CuString* CuStringNew(void)
87 {
88         CuString* str = (CuString*) malloc(sizeof(CuString));
89         str->length = 0;
90         str->size = STRING_MAX;
91         str->buffer = (char*) malloc(sizeof(char) * str->size);
92         str->buffer[0] = '\0';
93         return str;
94 }
95
96 void CuStringResize(CuString* str, int newSize)
97 {
98         str->buffer = (char*) realloc(str->buffer, sizeof(char) * newSize);
99         str->size = newSize;
100 }
101
102 void CuStringAppend(CuString* str, const char* text)
103 {
104         int length = strlen(text);
105         if (str->length + length + 1 >= str->size)
106                 CuStringResize(str, str->length + length + 1 + STRING_INC);
107         str->length += length;
108         strcat(str->buffer, text);
109 }
110
111 void CuStringAppendChar(CuString* str, char ch)
112 {
113         char text[2];
114         text[0] = ch;
115         text[1] = '\0';
116         CuStringAppend(str, text);
117 }
118
119 void CuStringAppendFormat(CuString* str, const char* format, ...)
120 {
121         va_list argp;
122         char buf[HUGE_STRING_LEN];
123         va_start(argp, format);
124         vsprintf(buf, format, argp);
125         va_end(argp);
126         CuStringAppend(str, buf);
127 }
128
129 void CuStringRead(CuString *str, char *path)
130 {
131         path = strdup(str->buffer);
132 }
133
134 /*-------------------------------------------------------------------------*
135  * CuTest
136  *-------------------------------------------------------------------------*/
137
138 void CuTestInit(CuTest* t, char* name, TestFunction function)
139 {
140         t->name = CuStrCopy(name);
141         t->notimpl = 0;
142         t->failed = 0;
143         t->ran = 0;
144         t->message = NULL;
145         t->function = function;
146         t->jumpBuf = NULL;
147 }
148
149 CuTest* CuTestNew(char* name, TestFunction function)
150 {
151         CuTest* tc = CU_ALLOC(CuTest);
152         CuTestInit(tc, name, function);
153         return tc;
154 }
155
156 void CuNotImpl(CuTest* tc, const char* message)
157 {
158         CuString* newstr = CuStringNew();
159         CuStringAppend(newstr, message);
160         CuStringAppend(newstr, " not implemented on this platform");
161         tc->notimpl = 1;
162         tc->message = CuStrCopy(newstr->buffer);
163         if (tc->jumpBuf != 0) longjmp(*(tc->jumpBuf), 0);
164 }
165
166 void CuFail(CuTest* tc, const char* message)
167 {
168         tc->failed = 1;
169         tc->message = CuStrCopy(message);
170         if (tc->jumpBuf != 0) longjmp(*(tc->jumpBuf), 0);
171 }
172
173 void CuAssert(CuTest* tc, const char* message, int condition)
174 {
175         if (condition) return;
176         CuFail(tc, message);
177 }
178
179 void CuAssertTrue(CuTest* tc, int condition)
180 {
181         if (condition) return;
182         CuFail(tc, "assert failed");
183 }
184
185 void CuAssertStrNEquals(CuTest* tc, const char* expected, const char* actual,
186                         int n)
187 {
188         CuString* message;
189         if (strncmp(expected, actual, n) == 0) return;
190         message = CuStringNew();
191         CuStringAppend(message, "expected\n---->\n");
192         CuStringAppend(message, expected);
193         CuStringAppend(message, "\n<----\nbut saw\n---->\n");
194         CuStringAppend(message, actual);
195         CuStringAppend(message, "\n<----");
196         CuFail(tc, message->buffer);
197 }
198
199 void CuAssertStrEquals(CuTest* tc, const char* expected, const char* actual)
200 {
201         CuString* message;
202         if (strcmp(expected, actual) == 0) return;
203         message = CuStringNew();
204         CuStringAppend(message, "expected\n---->\n");
205         CuStringAppend(message, expected);
206         CuStringAppend(message, "\n<----\nbut saw\n---->\n");
207         CuStringAppend(message, actual);
208         CuStringAppend(message, "\n<----");
209         CuFail(tc, message->buffer);
210 }
211
212 void CuAssertIntEquals(CuTest* tc, int expected, int actual)
213 {
214         char buf[STRING_MAX];
215         if (expected == actual) return;
216         sprintf(buf, "expected <%d> but was <%d>", expected, actual);
217         CuFail(tc, buf);
218 }
219
220 void CuAssertPtrEquals(CuTest* tc, const void* expected, const void* actual)
221 {
222         char buf[STRING_MAX];
223         if (expected == actual) return;
224         sprintf(buf, "expected pointer <%p> but was <%p>", expected, actual);
225         CuFail(tc, buf);
226 }
227
228 void CuAssertPtrNotNull(CuTest* tc, const void* pointer)
229 {
230         char buf[STRING_MAX];
231         if (pointer != NULL ) return;
232         sprintf(buf, "null pointer unexpected, but was <%p>", pointer);
233         CuFail(tc, buf);
234 }
235
236 void CuTestRun(CuTest* tc)
237 {
238         jmp_buf buf;
239         tc->jumpBuf = &buf;
240         if (setjmp(buf) == 0)
241         {
242                 tc->ran = 1;
243                 (tc->function)(tc);
244         }
245         tc->jumpBuf = 0;
246 }
247
248 /*-------------------------------------------------------------------------*
249  * CuSuite
250  *-------------------------------------------------------------------------*/
251
252 void CuSuiteInit(CuSuite* testSuite, char *name)
253 {
254         testSuite->name = strdup(name);
255         testSuite->count = 0;
256         testSuite->failCount = 0;
257         testSuite->notimplCount = 0;
258 }
259
260 CuSuite* CuSuiteNew(char *name)
261 {
262         CuSuite* testSuite = CU_ALLOC(CuSuite);
263         CuSuiteInit(testSuite, name);
264         return testSuite;
265 }
266
267 void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase)
268 {
269         assert(testSuite->count < MAX_TEST_CASES);
270         testSuite->list[testSuite->count] = testCase;
271         testSuite->count++;
272 }
273
274 void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2)
275 {
276         int i;
277         for (i = 0 ; i < testSuite2->count ; ++i)
278         {
279                 CuTest* testCase = testSuite2->list[i];
280                 CuSuiteAdd(testSuite, testCase);
281         }
282 }
283
284 void CuSuiteRun(CuSuite* testSuite)
285 {
286         int i;
287         for (i = 0 ; i < testSuite->count ; ++i)
288         {
289                 CuTest* testCase = testSuite->list[i];
290                 CuTestRun(testCase);
291                 if (testCase->failed) { testSuite->failCount += 1; }
292                 if (testCase->notimpl) { testSuite->notimplCount += 1; }
293         }
294 }
295
296 void CuSuiteSummary(CuSuite* testSuite, CuString* summary)
297 {
298         int i;
299         for (i = 0 ; i < testSuite->count ; ++i)
300         {
301                 CuTest* testCase = testSuite->list[i];
302                 CuStringAppend(summary, testCase->failed ? "F" : 
303                                testCase->notimpl ? "N": ".");
304         }
305         CuStringAppend(summary, "\n");
306 }
307
308 void CuSuiteOverView(CuSuite* testSuite, CuString* details)
309 {
310         CuStringAppendFormat(details, "%d %s run:  %d passed, %d failed, "
311                              "%d not implemented.\n",
312                              testSuite->count, 
313                              testSuite->count == 1 ? "test" : "tests",
314                              testSuite->count - testSuite->failCount - 
315                                 testSuite->notimplCount,
316                              testSuite->failCount, testSuite->notimplCount);
317 }
318
319 void CuSuiteDetails(CuSuite* testSuite, CuString* details)
320 {
321         int i;
322         int failCount = 0;
323
324         if (testSuite->failCount != 0 && verbose)
325         {
326                 CuStringAppendFormat(details, "\nFailed tests in %s:\n", testSuite->name);
327                 for (i = 0 ; i < testSuite->count ; ++i)
328                 {
329                         CuTest* testCase = testSuite->list[i];
330                         if (testCase->failed)
331                         {
332                                 failCount++;
333                                 CuStringAppendFormat(details, "%d) %s: %s\n", 
334                                         failCount, testCase->name, testCase->message);
335                         }
336                 }
337         }
338         if (testSuite->notimplCount != 0 && verbose)
339         {
340                 CuStringAppendFormat(details, "\nNot Implemented tests in %s:\n", testSuite->name);
341                 for (i = 0 ; i < testSuite->count ; ++i)
342                 {
343                         CuTest* testCase = testSuite->list[i];
344                         if (testCase->notimpl)
345                         {
346                                 failCount++;
347                                 CuStringAppendFormat(details, "%d) %s: %s\n",
348                                         failCount, testCase->name, testCase->message);
349                         }
350                 }
351         }
352 }
353
354 /*-------------------------------------------------------------------------*
355  * CuSuiteList
356  *-------------------------------------------------------------------------*/
357
358 CuSuiteList* CuSuiteListNew(char *name)
359 {
360         CuSuiteList* testSuite = CU_ALLOC(CuSuiteList);
361         testSuite->name = strdup(name);
362         testSuite->count = 0;
363         return testSuite;
364 }
365
366 void CuSuiteListAdd(CuSuiteList *suites, CuSuite *origsuite)
367 {
368         assert(suites->count < MAX_TEST_CASES);
369         suites->list[suites->count] = origsuite;
370         suites->count++;
371 }
372
373 void CuSuiteListRun(CuSuiteList* testSuite)
374 {
375         int i;
376         for (i = 0 ; i < testSuite->count ; ++i)
377         {
378                 CuSuite* testCase = testSuite->list[i];
379                 CuSuiteRun(testCase);
380         }
381 }
382
383 static const char *genspaces(int i)
384 {
385     char *str = malloc((i + 1) * sizeof(char));
386     memset(str, ' ', i);
387     str[i] = '\0';
388     return str;
389 }
390
391 void CuSuiteListRunWithSummary(CuSuiteList* testSuite)
392 {
393         int i;
394
395         printf("%s:\n", testSuite->name);
396         for (i = 0 ; i < testSuite->count ; ++i)
397         {
398                 CuSuite* testCase = testSuite->list[i];
399                 CuString *str = CuStringNew();
400
401                 printf("    %s:%s", testCase->name, 
402                                   genspaces(21 - strlen(testCase->name)));
403                 fflush(stdout);
404                 CuSuiteRun(testCase);
405                 CuSuiteSummary(testCase, str);
406                 printf("    %s", str->buffer);
407
408         }
409         printf("\n");
410 }
411
412 void CuSuiteListSummary(CuSuiteList* testSuite, CuString* summary)
413 {
414         int i;
415         CuStringAppendFormat(summary, "%s:\n", testSuite->name);
416         for (i = 0 ; i < testSuite->count ; ++i)
417         {
418                 CuSuite* testCase = testSuite->list[i];
419                 CuString *str = CuStringNew();
420                 CuSuiteSummary(testCase, str);
421                 CuStringAppend(summary, "    ");
422                 CuStringAppend(summary, str->buffer);
423         }
424         CuStringAppend(summary, "\n");
425 }
426
427 int CuSuiteListDetails(CuSuiteList* testSuite, CuString* details)
428 {
429         int i;
430         int failCount = 0;
431         int notImplCount = 0;
432         int count = 0;
433
434         for (i = 0 ; i < testSuite->count ; ++i)
435         {
436                 failCount += testSuite->list[i]->failCount;
437                 notImplCount += testSuite->list[i]->notimplCount;
438                 count += testSuite->list[i]->count;
439         }
440         CuStringAppendFormat(details, "%d %s run:  %d passed, %d failed, "
441                              "%d not implemented.\n",
442                              count, 
443                              count == 1 ? "test" : "tests",
444                              count - failCount - notImplCount,
445                              failCount, notImplCount);
446
447         if (failCount != 0 && verbose)
448         {
449                 for (i = 0 ; i < testSuite->count ; ++i)
450                 {
451                         CuString *str = CuStringNew();
452                         CuSuite* testCase = testSuite->list[i];
453                         if (testCase->failCount)
454                         {
455                                 CuSuiteDetails(testCase, str);
456                                 CuStringAppend(details, str->buffer);
457                         }
458                 }
459         }
460         if (notImplCount != 0 && verbose)
461         {
462                 for (i = 0 ; i < testSuite->count ; ++i)
463                 {
464                         CuString *str = CuStringNew();
465                         CuSuite* testCase = testSuite->list[i];
466                         if (testCase->notimplCount)
467                         {
468                                 CuSuiteDetails(testCase, str);
469                                 CuStringAppend(details, str->buffer);
470                         }
471                 }
472         } 
473         return failCount;
474 }
475