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