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