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 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 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 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 58 static int testSelected(const char* test) 59 { 60 return selected(UnityFixture.NameFilter, test); 61 } 62 63 static int groupSelected(const char* group) 64 { 65 return selected(UnityFixture.GroupFilter, group); 66 } 67 68 static void runTestCase(void) 69 { 70 71 } 72 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 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 135 void UnityMalloc_StartTest(void) 136 { 137 malloc_count = 0; 138 malloc_fail_countdown = MALLOC_DONT_FAIL; 139 } 140 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 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 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 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 214 static void release_memory(void * mem) 215 { 216 Guard* guard = (Guard*)mem; 217 guard--; 218 219 malloc_count--; 220 free(guard); 221 } 222 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 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 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 285 void UnityPointer_Init(void) 286 { 287 pointer_index = 0; 288 } 289 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 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 312 int UnityFailureCount(void) 313 { 314 return Unity.TestFailures; 315 } 316 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 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