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