1284990Scy//- Copyright (c) 2010 James Grenning and Contributed to Unity Project 2284990Scy/* ========================================== 3284990Scy Unity Project - A Test Framework for C 4284990Scy Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams 5284990Scy [Released under MIT License. Please refer to license.txt for details] 6284990Scy========================================== */ 7284990Scy 8284990Scy#include <string.h> 9284990Scy#include <stdio.h> 10284990Scy#include "unity_fixture.h" 11284990Scy#include "unity_internals.h" 12284990Scy 13284990ScyUNITY_FIXTURE_T UnityFixture; 14284990Scy 15284990Scy//If you decide to use the function pointer approach. 16284990Scyint (*outputChar)(int) = putchar; 17284990Scy 18284990Scyint verbose = 0; 19284990Scy 20284990Scy 21284990Scystatic void announceTestRun(unsigned int runNumber) 22284990Scy{ 23284990Scy UnityPrint("Unity test run "); 24284990Scy UnityPrintNumber(runNumber+1); 25284990Scy UnityPrint(" of "); 26284990Scy UnityPrintNumber(UnityFixture.RepeatCount); 27284990Scy UNITY_OUTPUT_CHAR('\n'); 28284990Scy} 29284990Scy 30284990Scyint UnityMain(int argc, const char* argv[], void (*runAllTests)(void)) 31284990Scy{ 32284990Scy int result = UnityGetCommandLineOptions(argc, argv); 33284990Scy unsigned int r; 34284990Scy if (result != 0) 35284990Scy return result; 36284990Scy 37284990Scy for (r = 0; r < UnityFixture.RepeatCount; r++) 38284990Scy { 39284990Scy UnityBegin(argv[0]); 40284990Scy announceTestRun(r); 41284990Scy runAllTests(); 42284990Scy UNITY_OUTPUT_CHAR('\n'); 43284990Scy UnityEnd(); 44284990Scy } 45284990Scy 46284990Scy return UnityFailureCount(); 47284990Scy} 48284990Scy 49284990Scystatic int selected(const char * filter, const char * name) 50284990Scy{ 51284990Scy if (filter == 0) 52284990Scy return 1; 53284990Scy return strstr(name, filter) ? 1 : 0; 54284990Scy} 55284990Scy 56284990Scystatic int testSelected(const char* test) 57284990Scy{ 58284990Scy return selected(UnityFixture.NameFilter, test); 59284990Scy} 60284990Scy 61284990Scystatic int groupSelected(const char* group) 62284990Scy{ 63284990Scy return selected(UnityFixture.GroupFilter, group); 64284990Scy} 65284990Scy 66284990Scystatic void runTestCase(void) 67284990Scy{ 68284990Scy 69284990Scy} 70284990Scy 71284990Scyvoid UnityTestRunner(unityfunction* setup, 72284990Scy unityfunction* testBody, 73284990Scy unityfunction* teardown, 74284990Scy const char * printableName, 75284990Scy const char * group, 76284990Scy const char * name, 77284990Scy const char * file, int line) 78284990Scy{ 79284990Scy if (testSelected(name) && groupSelected(group)) 80284990Scy { 81284990Scy Unity.CurrentTestFailed = 0; 82284990Scy Unity.TestFile = file; 83284990Scy Unity.CurrentTestName = printableName; 84284990Scy Unity.CurrentTestLineNumber = line; 85284990Scy if (!UnityFixture.Verbose) 86284990Scy UNITY_OUTPUT_CHAR('.'); 87284990Scy else 88284990Scy UnityPrint(printableName); 89284990Scy 90284990Scy Unity.NumberOfTests++; 91284990Scy UnityMalloc_StartTest(); 92284990Scy UnityPointer_Init(); 93284990Scy 94284990Scy runTestCase(); 95284990Scy if (TEST_PROTECT()) 96284990Scy { 97284990Scy setup(); 98284990Scy testBody(); 99284990Scy } 100284990Scy if (TEST_PROTECT()) 101284990Scy { 102284990Scy teardown(); 103284990Scy } 104284990Scy if (TEST_PROTECT()) 105284990Scy { 106284990Scy UnityPointer_UndoAllSets(); 107284990Scy if (!Unity.CurrentTestFailed) 108284990Scy UnityMalloc_EndTest(); 109284990Scy } 110284990Scy UnityConcludeFixtureTest(); 111284990Scy } 112284990Scy} 113284990Scy 114284990Scyvoid UnityIgnoreTest(const char * printableName) 115284990Scy{ 116284990Scy Unity.NumberOfTests++; 117284990Scy Unity.CurrentTestIgnored = 1; 118284990Scy if (!UnityFixture.Verbose) 119284990Scy UNITY_OUTPUT_CHAR('!'); 120284990Scy else 121284990Scy UnityPrint(printableName); 122284990Scy UnityConcludeFixtureTest(); 123284990Scy} 124284990Scy 125284990Scy 126284990Scy//------------------------------------------------- 127284990Scy//Malloc and free stuff 128284990Scy// 129284990Scy#define MALLOC_DONT_FAIL -1 130284990Scystatic int malloc_count; 131284990Scystatic int malloc_fail_countdown = MALLOC_DONT_FAIL; 132284990Scy 133284990Scyvoid UnityMalloc_StartTest(void) 134284990Scy{ 135284990Scy malloc_count = 0; 136284990Scy malloc_fail_countdown = MALLOC_DONT_FAIL; 137284990Scy} 138284990Scy 139284990Scyvoid UnityMalloc_EndTest(void) 140284990Scy{ 141284990Scy malloc_fail_countdown = MALLOC_DONT_FAIL; 142284990Scy if (malloc_count != 0) 143284990Scy { 144284990Scy TEST_FAIL_MESSAGE("This test leaks!"); 145284990Scy } 146284990Scy} 147284990Scy 148284990Scyvoid UnityMalloc_MakeMallocFailAfterCount(int countdown) 149284990Scy{ 150284990Scy malloc_fail_countdown = countdown; 151284990Scy} 152284990Scy 153284990Scy#ifdef malloc 154284990Scy#undef malloc 155284990Scy#endif 156284990Scy 157284990Scy#ifdef free 158284990Scy#undef free 159284990Scy#endif 160284990Scy 161284990Scy#ifdef calloc 162284990Scy#undef calloc 163284990Scy#endif 164284990Scy 165284990Scy#ifdef realloc 166284990Scy#undef realloc 167284990Scy#endif 168284990Scy 169284990Scy#include <stdlib.h> 170284990Scy#include <string.h> 171284990Scy 172284990Scytypedef struct GuardBytes 173284990Scy{ 174284990Scy size_t size; 175284990Scy char guard[sizeof(size_t)]; 176284990Scy} Guard; 177284990Scy 178284990Scy 179284990Scystatic const char * end = "END"; 180284990Scy 181284990Scyvoid * unity_malloc(size_t size) 182284990Scy{ 183284990Scy char* mem; 184284990Scy Guard* guard; 185284990Scy 186284990Scy if (malloc_fail_countdown != MALLOC_DONT_FAIL) 187284990Scy { 188284990Scy if (malloc_fail_countdown == 0) 189284990Scy return 0; 190284990Scy malloc_fail_countdown--; 191284990Scy } 192284990Scy 193284990Scy malloc_count++; 194284990Scy 195284990Scy guard = (Guard*)malloc(size + sizeof(Guard) + 4); 196284990Scy guard->size = size; 197284990Scy mem = (char*)&(guard[1]); 198284990Scy memcpy(&mem[size], end, strlen(end) + 1); 199284990Scy 200284990Scy return (void*)mem; 201284990Scy} 202284990Scy 203284990Scystatic int isOverrun(void * mem) 204284990Scy{ 205284990Scy Guard* guard = (Guard*)mem; 206284990Scy char* memAsChar = (char*)mem; 207284990Scy guard--; 208284990Scy 209284990Scy return strcmp(&memAsChar[guard->size], end) != 0; 210284990Scy} 211284990Scy 212284990Scystatic void release_memory(void * mem) 213284990Scy{ 214284990Scy Guard* guard = (Guard*)mem; 215284990Scy guard--; 216284990Scy 217284990Scy malloc_count--; 218284990Scy free(guard); 219284990Scy} 220284990Scy 221284990Scyvoid unity_free(void * mem) 222284990Scy{ 223284990Scy int overrun = isOverrun(mem);//strcmp(&memAsChar[guard->size], end) != 0; 224284990Scy release_memory(mem); 225284990Scy if (overrun) 226284990Scy { 227284990Scy TEST_FAIL_MESSAGE("Buffer overrun detected during free()"); 228284990Scy } 229284990Scy} 230284990Scy 231284990Scyvoid* unity_calloc(size_t num, size_t size) 232284990Scy{ 233284990Scy void* mem = unity_malloc(num * size); 234284990Scy memset(mem, 0, num*size); 235284990Scy return mem; 236284990Scy} 237284990Scy 238284990Scyvoid* unity_realloc(void * oldMem, size_t size) 239284990Scy{ 240284990Scy Guard* guard = (Guard*)oldMem; 241284990Scy// char* memAsChar = (char*)oldMem; 242284990Scy void* newMem; 243284990Scy 244284990Scy if (oldMem == 0) 245284990Scy return unity_malloc(size); 246284990Scy 247284990Scy guard--; 248284990Scy if (isOverrun(oldMem)) 249284990Scy { 250284990Scy release_memory(oldMem); 251284990Scy TEST_FAIL_MESSAGE("Buffer overrun detected during realloc()"); 252284990Scy } 253284990Scy 254284990Scy if (size == 0) 255284990Scy { 256284990Scy release_memory(oldMem); 257284990Scy return 0; 258284990Scy } 259284990Scy 260284990Scy if (guard->size >= size) 261284990Scy return oldMem; 262284990Scy 263284990Scy newMem = unity_malloc(size); 264284990Scy memcpy(newMem, oldMem, guard->size); 265284990Scy unity_free(oldMem); 266284990Scy return newMem; 267284990Scy} 268284990Scy 269284990Scy 270284990Scy//-------------------------------------------------------- 271284990Scy//Automatic pointer restoration functions 272284990Scytypedef struct _PointerPair 273284990Scy{ 274284990Scy struct _PointerPair * next; 275284990Scy void ** pointer; 276284990Scy void * old_value; 277284990Scy} PointerPair; 278284990Scy 279284990Scyenum {MAX_POINTERS=50}; 280284990Scystatic PointerPair pointer_store[MAX_POINTERS]; 281284990Scystatic int pointer_index = 0; 282284990Scy 283284990Scyvoid UnityPointer_Init(void) 284284990Scy{ 285284990Scy pointer_index = 0; 286284990Scy} 287284990Scy 288284990Scyvoid UnityPointer_Set(void ** pointer, void * newValue) 289284990Scy{ 290284990Scy if (pointer_index >= MAX_POINTERS) 291284990Scy TEST_FAIL_MESSAGE("Too many pointers set"); 292284990Scy 293284990Scy pointer_store[pointer_index].pointer = pointer; 294284990Scy pointer_store[pointer_index].old_value = *pointer; 295284990Scy *pointer = newValue; 296284990Scy pointer_index++; 297284990Scy} 298284990Scy 299284990Scyvoid UnityPointer_UndoAllSets(void) 300284990Scy{ 301284990Scy while (pointer_index > 0) 302284990Scy { 303284990Scy pointer_index--; 304284990Scy *(pointer_store[pointer_index].pointer) = 305284990Scy pointer_store[pointer_index].old_value; 306284990Scy 307284990Scy } 308284990Scy} 309284990Scy 310284990Scyint UnityFailureCount(void) 311284990Scy{ 312284990Scy return Unity.TestFailures; 313284990Scy} 314284990Scy 315284990Scyint UnityGetCommandLineOptions(int argc, const char* argv[]) 316284990Scy{ 317284990Scy int i; 318284990Scy UnityFixture.Verbose = 0; 319284990Scy UnityFixture.GroupFilter = 0; 320284990Scy UnityFixture.NameFilter = 0; 321284990Scy UnityFixture.RepeatCount = 1; 322284990Scy 323284990Scy if (argc == 1) 324284990Scy return 0; 325284990Scy 326284990Scy for (i = 1; i < argc; ) 327284990Scy { 328284990Scy if (strcmp(argv[i], "-v") == 0) 329284990Scy { 330284990Scy UnityFixture.Verbose = 1; 331284990Scy i++; 332284990Scy } 333284990Scy else if (strcmp(argv[i], "-g") == 0) 334284990Scy { 335284990Scy i++; 336284990Scy if (i >= argc) 337284990Scy return 1; 338284990Scy UnityFixture.GroupFilter = argv[i]; 339284990Scy i++; 340284990Scy } 341284990Scy else if (strcmp(argv[i], "-n") == 0) 342284990Scy { 343284990Scy i++; 344284990Scy if (i >= argc) 345284990Scy return 1; 346284990Scy UnityFixture.NameFilter = argv[i]; 347284990Scy i++; 348284990Scy } 349284990Scy else if (strcmp(argv[i], "-r") == 0) 350284990Scy { 351284990Scy UnityFixture.RepeatCount = 2; 352284990Scy i++; 353284990Scy if (i < argc) 354284990Scy { 355284990Scy if (*(argv[i]) >= '0' && *(argv[i]) <= '9') 356284990Scy { 357284990Scy UnityFixture.RepeatCount = atoi(argv[i]); 358284990Scy i++; 359284990Scy } 360284990Scy } 361284990Scy } else { 362284990Scy // ignore unknown parameter 363284990Scy i++; 364284990Scy } 365284990Scy } 366284990Scy return 0; 367284990Scy} 368284990Scy 369284990Scyvoid UnityConcludeFixtureTest(void) 370284990Scy{ 371284990Scy if (Unity.CurrentTestIgnored) 372284990Scy { 373284990Scy if (UnityFixture.Verbose) 374284990Scy { 375284990Scy UNITY_OUTPUT_CHAR('\n'); 376284990Scy } 377284990Scy Unity.TestIgnores++; 378284990Scy } 379284990Scy else if (!Unity.CurrentTestFailed) 380284990Scy { 381284990Scy if (UnityFixture.Verbose) 382284990Scy { 383284990Scy UnityPrint(" PASS"); 384284990Scy UNITY_OUTPUT_CHAR('\n'); 385284990Scy } 386284990Scy } 387284990Scy else if (Unity.CurrentTestFailed) 388284990Scy { 389284990Scy Unity.TestFailures++; 390284990Scy } 391284990Scy 392284990Scy Unity.CurrentTestFailed = 0; 393284990Scy Unity.CurrentTestIgnored = 0; 394284990Scy} 395