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