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