unity_fixture.c revision 310419
1//- Copyright (c) 2010 James Grenning and Contributed to Unity Project
2/* ==========================================
3    Unity Project - A Test Framework for C
4    Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
5    [Released under MIT License. Please refer to license.txt for details]
6========================================== */
7
8#include <string.h>
9#include <stdio.h>
10#include "unity_fixture.h"
11#include "unity_internals.h"
12
13UNITY_FIXTURE_T UnityFixture;
14
15//If you decide to use the function pointer approach.
16int (*outputChar)(int) = putchar;
17
18int verbose = 0;
19
20
21static void announceTestRun(unsigned int runNumber)
22{
23    UnityPrint("Unity test run ");
24    UnityPrintNumber(runNumber+1);
25    UnityPrint(" of ");
26    UnityPrintNumber(UnityFixture.RepeatCount);
27    UNITY_OUTPUT_CHAR('\n');
28}
29
30int UnityMain(int argc, const char* argv[], void (*runAllTests)(void))
31{
32    int result = UnityGetCommandLineOptions(argc, argv);
33    unsigned int r;
34    if (result != 0)
35        return result;
36
37    for (r = 0; r < UnityFixture.RepeatCount; r++)
38    {
39        UnityBegin(argv[0]);
40        announceTestRun(r);
41        runAllTests();
42        UNITY_OUTPUT_CHAR('\n');
43        UnityEnd();
44    }
45
46    return UnityFailureCount();
47}
48
49static int selected(const char * filter, const char * name)
50{
51    if (filter == 0)
52        return 1;
53    return strstr(name, filter) ? 1 : 0;
54}
55
56static int testSelected(const char* test)
57{
58    return selected(UnityFixture.NameFilter, test);
59}
60
61static int groupSelected(const char* group)
62{
63    return selected(UnityFixture.GroupFilter, group);
64}
65
66static void runTestCase(void)
67{
68
69}
70
71void UnityTestRunner(unityfunction* setup,
72        unityfunction* testBody,
73        unityfunction* teardown,
74        const char * printableName,
75        const char * group,
76        const char * name,
77        const char * file, int line)
78{
79    if (testSelected(name) && groupSelected(group))
80    {
81        Unity.CurrentTestFailed = 0;
82        Unity.TestFile = file;
83        Unity.CurrentTestName = printableName;
84        Unity.CurrentTestLineNumber = line;
85        if (!UnityFixture.Verbose)
86            UNITY_OUTPUT_CHAR('.');
87        else
88            UnityPrint(printableName);
89
90        Unity.NumberOfTests++;
91        UnityMalloc_StartTest();
92        UnityPointer_Init();
93
94        runTestCase();
95        if (TEST_PROTECT())
96        {
97            setup();
98            testBody();
99        }
100        if (TEST_PROTECT())
101        {
102            teardown();
103        }
104        if (TEST_PROTECT())
105        {
106            UnityPointer_UndoAllSets();
107            if (!Unity.CurrentTestFailed)
108                UnityMalloc_EndTest();
109        }
110        UnityConcludeFixtureTest();
111    }
112}
113
114void UnityIgnoreTest(const char * printableName)
115{
116    Unity.NumberOfTests++;
117    Unity.CurrentTestIgnored = 1;
118    if (!UnityFixture.Verbose)
119        UNITY_OUTPUT_CHAR('!');
120    else
121        UnityPrint(printableName);
122    UnityConcludeFixtureTest();
123}
124
125
126//-------------------------------------------------
127//Malloc and free stuff
128//
129#define MALLOC_DONT_FAIL -1
130static int malloc_count;
131static int malloc_fail_countdown = MALLOC_DONT_FAIL;
132
133void UnityMalloc_StartTest(void)
134{
135    malloc_count = 0;
136    malloc_fail_countdown = MALLOC_DONT_FAIL;
137}
138
139void UnityMalloc_EndTest(void)
140{
141    malloc_fail_countdown = MALLOC_DONT_FAIL;
142    if (malloc_count != 0)
143    {
144        TEST_FAIL_MESSAGE("This test leaks!");
145    }
146}
147
148void UnityMalloc_MakeMallocFailAfterCount(int countdown)
149{
150    malloc_fail_countdown = countdown;
151}
152
153#ifdef malloc
154#undef malloc
155#endif
156
157#ifdef free
158#undef free
159#endif
160
161#ifdef calloc
162#undef calloc
163#endif
164
165#ifdef realloc
166#undef realloc
167#endif
168
169#include <stdlib.h>
170#include <string.h>
171
172typedef struct GuardBytes
173{
174    size_t size;
175    char guard[sizeof(size_t)];
176} Guard;
177
178
179static const char * end = "END";
180
181void * unity_malloc(size_t size)
182{
183    char* mem;
184    Guard* guard;
185
186    if (malloc_fail_countdown != MALLOC_DONT_FAIL)
187    {
188        if (malloc_fail_countdown == 0)
189            return 0;
190        malloc_fail_countdown--;
191    }
192
193    malloc_count++;
194
195    guard = (Guard*)malloc(size + sizeof(Guard) + 4);
196    guard->size = size;
197    mem = (char*)&(guard[1]);
198    memcpy(&mem[size], end, strlen(end) + 1);
199
200    return (void*)mem;
201}
202
203static int isOverrun(void * mem)
204{
205    Guard* guard = (Guard*)mem;
206    char* memAsChar = (char*)mem;
207    guard--;
208
209    return strcmp(&memAsChar[guard->size], end) != 0;
210}
211
212static void release_memory(void * mem)
213{
214    Guard* guard = (Guard*)mem;
215    guard--;
216
217    malloc_count--;
218    free(guard);
219}
220
221void unity_free(void * mem)
222{
223    int overrun = isOverrun(mem);//strcmp(&memAsChar[guard->size], end) != 0;
224    release_memory(mem);
225    if (overrun)
226    {
227        TEST_FAIL_MESSAGE("Buffer overrun detected during free()");
228    }
229}
230
231void* unity_calloc(size_t num, size_t size)
232{
233    void* mem = unity_malloc(num * size);
234    memset(mem, 0, num*size);
235    return mem;
236}
237
238void* unity_realloc(void * oldMem, size_t size)
239{
240    Guard* guard = (Guard*)oldMem;
241//    char* memAsChar = (char*)oldMem;
242    void* newMem;
243
244    if (oldMem == 0)
245        return unity_malloc(size);
246
247    guard--;
248    if (isOverrun(oldMem))
249    {
250        release_memory(oldMem);
251        TEST_FAIL_MESSAGE("Buffer overrun detected during realloc()");
252    }
253
254    if (size == 0)
255    {
256        release_memory(oldMem);
257        return 0;
258    }
259
260    if (guard->size >= size)
261        return oldMem;
262
263    newMem = unity_malloc(size);
264    memcpy(newMem, oldMem, guard->size);
265    unity_free(oldMem);
266    return newMem;
267}
268
269
270//--------------------------------------------------------
271//Automatic pointer restoration functions
272typedef struct _PointerPair
273{
274    struct _PointerPair * next;
275    void ** pointer;
276    void * old_value;
277} PointerPair;
278
279enum {MAX_POINTERS=50};
280static PointerPair pointer_store[MAX_POINTERS];
281static int pointer_index = 0;
282
283void UnityPointer_Init(void)
284{
285    pointer_index = 0;
286}
287
288void UnityPointer_Set(void ** pointer, void * newValue)
289{
290    if (pointer_index >= MAX_POINTERS)
291        TEST_FAIL_MESSAGE("Too many pointers set");
292
293    pointer_store[pointer_index].pointer = pointer;
294    pointer_store[pointer_index].old_value = *pointer;
295    *pointer = newValue;
296    pointer_index++;
297}
298
299void UnityPointer_UndoAllSets(void)
300{
301    while (pointer_index > 0)
302    {
303        pointer_index--;
304        *(pointer_store[pointer_index].pointer) =
305        pointer_store[pointer_index].old_value;
306
307    }
308}
309
310int UnityFailureCount(void)
311{
312    return Unity.TestFailures;
313}
314
315int UnityGetCommandLineOptions(int argc, const char* argv[])
316{
317    int i;
318    UnityFixture.Verbose = 0;
319    UnityFixture.GroupFilter = 0;
320    UnityFixture.NameFilter = 0;
321    UnityFixture.RepeatCount = 1;
322
323    if (argc == 1)
324        return 0;
325
326    for (i = 1; i < argc; )
327    {
328        if (strcmp(argv[i], "-v") == 0)
329        {
330            UnityFixture.Verbose = 1;
331            i++;
332        }
333        else if (strcmp(argv[i], "-g") == 0)
334        {
335            i++;
336            if (i >= argc)
337                return 1;
338            UnityFixture.GroupFilter = argv[i];
339            i++;
340        }
341        else if (strcmp(argv[i], "-n") == 0)
342        {
343            i++;
344            if (i >= argc)
345                return 1;
346            UnityFixture.NameFilter = argv[i];
347            i++;
348        }
349        else if (strcmp(argv[i], "-r") == 0)
350        {
351            UnityFixture.RepeatCount = 2;
352            i++;
353            if (i < argc)
354            {
355                if (*(argv[i]) >= '0' && *(argv[i]) <= '9')
356                {
357                    UnityFixture.RepeatCount = atoi(argv[i]);
358                    i++;
359                }
360            }
361        } else {
362            // ignore unknown parameter
363            i++;
364        }
365    }
366    return 0;
367}
368
369void UnityConcludeFixtureTest(void)
370{
371    if (Unity.CurrentTestIgnored)
372    {
373        if (UnityFixture.Verbose)
374        {
375            UNITY_OUTPUT_CHAR('\n');
376        }
377        Unity.TestIgnores++;
378    }
379    else if (!Unity.CurrentTestFailed)
380    {
381        if (UnityFixture.Verbose)
382        {
383            UnityPrint(" PASS");
384            UNITY_OUTPUT_CHAR('\n');
385        }
386    }
387    else if (Unity.CurrentTestFailed)
388    {
389        Unity.TestFailures++;
390    }
391
392    Unity.CurrentTestFailed = 0;
393    Unity.CurrentTestIgnored = 0;
394}
395