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