unity_fixture.c 8.7 KB
Newer Older
1 2 3 4 5 6 7
//- Copyright (c) 2010 James Grenning and Contributed to Unity Project
/* ==========================================
    Unity Project - A Test Framework for C
    Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
    [Released under MIT License. Please refer to license.txt for details]
========================================== */

8
#include <string.h>
9 10 11 12 13 14
#include "unity_fixture.h"
#include "unity_internals.h"

UNITY_FIXTURE_T UnityFixture;

//If you decide to use the function pointer approach.
15 16
//Build with -D UNITY_OUTPUT_CHAR=outputChar and include <stdio.h>
//int (*outputChar)(int) = putchar;
17

18
#if !defined(UNITY_WEAK_ATTRIBUTE) && !defined(UNITY_WEAK_PRAGMA)
19 20
void setUp(void)    { /*does nothing*/ }
void tearDown(void) { /*does nothing*/ }
21
#endif
22

23
static void announceTestRun(unsigned int runNumber)
24 25 26 27 28
{
    UnityPrint("Unity test run ");
    UnityPrintNumber(runNumber+1);
    UnityPrint(" of ");
    UnityPrintNumber(UnityFixture.RepeatCount);
29
    UNITY_PRINT_EOL();
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 37 38 39 40
    if (result != 0)
        return result;

    for (r = 0; r < UnityFixture.RepeatCount; r++)
    {
41
        UnityBegin(argv[0]);
42
        announceTestRun(r);
43
        runAllTests();
44
        UNITY_PRINT_EOL();
45 46 47 48 49 50
        UnityEnd();
    }

    return UnityFailureCount();
}

51
static int selected(const char* filter, const char* name)
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
{
    if (filter == 0)
        return 1;
    return strstr(name, filter) ? 1 : 0;
}

static int testSelected(const char* test)
{
    return selected(UnityFixture.NameFilter, test);
}

static int groupSelected(const char* group)
{
    return selected(UnityFixture.GroupFilter, group);
}

void UnityTestRunner(unityfunction* setup,
69 70 71 72 73 74
                     unityfunction* testBody,
                     unityfunction* teardown,
                     const char* printableName,
                     const char* group,
                     const char* name,
                     const char* file, int line)
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
{
    if (testSelected(name) && groupSelected(group))
    {
        Unity.CurrentTestFailed = 0;
        Unity.TestFile = file;
        Unity.CurrentTestName = printableName;
        Unity.CurrentTestLineNumber = line;
        if (!UnityFixture.Verbose)
            UNITY_OUTPUT_CHAR('.');
        else
            UnityPrint(printableName);

        Unity.NumberOfTests++;
        UnityMalloc_StartTest();
        UnityPointer_Init();

        if (TEST_PROTECT())
        {
            setup();
            testBody();
        }
        if (TEST_PROTECT())
        {
            teardown();
        }
        if (TEST_PROTECT())
        {
            UnityPointer_UndoAllSets();
            if (!Unity.CurrentTestFailed)
                UnityMalloc_EndTest();
        }
106
        UnityConcludeFixtureTest();
107 108 109
    }
}

110
void UnityIgnoreTest(const char* printableName, const char* group, const char* name)
111
{
112
    if (testSelected(name) && groupSelected(group))
113 114 115 116 117 118 119 120 121
    {
        Unity.NumberOfTests++;
        Unity.CurrentTestIgnored = 1;
        if (!UnityFixture.Verbose)
            UNITY_OUTPUT_CHAR('!');
        else
            UnityPrint(printableName);
        UnityConcludeFixtureTest();
    }
122 123
}

124 125 126 127 128 129 130 131

//-------------------------------------------------
//Malloc and free stuff
//
#define MALLOC_DONT_FAIL -1
static int malloc_count;
static int malloc_fail_countdown = MALLOC_DONT_FAIL;

132
void UnityMalloc_StartTest(void)
133 134 135 136 137
{
    malloc_count = 0;
    malloc_fail_countdown = MALLOC_DONT_FAIL;
}

138
void UnityMalloc_EndTest(void)
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
{
    malloc_fail_countdown = MALLOC_DONT_FAIL;
    if (malloc_count != 0)
    {
        TEST_FAIL_MESSAGE("This test leaks!");
    }
}

void UnityMalloc_MakeMallocFailAfterCount(int countdown)
{
    malloc_fail_countdown = countdown;
}

#ifdef malloc
#undef malloc
#endif

#ifdef free
#undef free
#endif

@
@gageas 已提交
160 161 162 163 164 165 166 167
#ifdef calloc
#undef calloc
#endif

#ifdef realloc
#undef realloc
#endif

168 169 170 171
#include <stdlib.h>

typedef struct GuardBytes
{
172
    size_t size;
173
    char guard_space[4];
174 175 176
} Guard;


177
static const char end[] = "END";
178

179
void* unity_malloc(size_t size)
180 181 182 183 184 185 186 187 188 189 190 191 192
{
    char* mem;
    Guard* guard;

    if (malloc_fail_countdown != MALLOC_DONT_FAIL)
    {
        if (malloc_fail_countdown == 0)
            return 0;
        malloc_fail_countdown--;
    }

    malloc_count++;

193
    guard = (Guard*)UNITY_FIXTURE_MALLOC(size + sizeof(Guard) + sizeof(end));
194 195
    guard->size = size;
    mem = (char*)&(guard[1]);
196
    memcpy(&mem[size], end, sizeof(end));
197 198 199 200

    return (void*)mem;
}

201
static int isOverrun(void* mem)
202 203 204 205
{
    Guard* guard = (Guard*)mem;
    char* memAsChar = (char*)mem;
    guard--;
206 207 208 209

    return strcmp(&memAsChar[guard->size], end) != 0;
}

210
static void release_memory(void* mem)
211 212 213 214 215
{
    Guard* guard = (Guard*)mem;
    guard--;

    malloc_count--;
216
    UNITY_FIXTURE_FREE(guard);
217 218
}

219
void unity_free(void* mem)
220
{
221 222 223 224 225 226 227 228
    int overrun;

    if (mem == NULL)
    {
        return;
    }

    overrun = isOverrun(mem);//strcmp(&memAsChar[guard->size], end) != 0;
229 230
    release_memory(mem);
    if (overrun)
231 232 233 234 235 236 237 238 239 240 241 242
    {
        TEST_FAIL_MESSAGE("Buffer overrun detected during free()");
    }
}

void* unity_calloc(size_t num, size_t size)
{
    void* mem = unity_malloc(num * size);
    memset(mem, 0, num*size);
    return mem;
}

243
void* unity_realloc(void* oldMem, size_t size)
244 245
{
    Guard* guard = (Guard*)oldMem;
246
//    char* memAsChar = (char*)oldMem;
247 248 249 250 251 252
    void* newMem;

    if (oldMem == 0)
        return unity_malloc(size);

    guard--;
253
    if (isOverrun(oldMem))
254
    {
255
        release_memory(oldMem);
256 257 258 259 260
        TEST_FAIL_MESSAGE("Buffer overrun detected during realloc()");
    }

    if (size == 0)
    {
261
        release_memory(oldMem);
262 263 264 265 266 267 268
        return 0;
    }

    if (guard->size >= size)
        return oldMem;

    newMem = unity_malloc(size);
269
    memcpy(newMem, oldMem, guard->size);
270 271 272 273 274 275 276 277 278
    unity_free(oldMem);
    return newMem;
}


//--------------------------------------------------------
//Automatic pointer restoration functions
typedef struct _PointerPair
{
279 280 281
    struct _PointerPair* next;
    void** pointer;
    void* old_value;
282 283 284
} PointerPair;

enum {MAX_POINTERS=50};
285
static PointerPair pointer_store[MAX_POINTERS+1];
286 287
static int pointer_index = 0;

288
void UnityPointer_Init(void)
289 290 291 292 293 294 295
{
    pointer_index = 0;
}

void UnityPointer_Set(void ** pointer, void * newValue)
{
    if (pointer_index >= MAX_POINTERS)
296
    {
297
        TEST_FAIL_MESSAGE("Too many pointers set");
298 299 300 301 302 303 304 305
    }
    else
    {
        pointer_store[pointer_index].pointer = pointer;
        pointer_store[pointer_index].old_value = *pointer;
        *pointer = newValue;
        pointer_index++;
    }
306 307
}

308
void UnityPointer_UndoAllSets(void)
309 310 311 312 313 314 315 316 317 318
{
    while (pointer_index > 0)
    {
        pointer_index--;
        *(pointer_store[pointer_index].pointer) =
        pointer_store[pointer_index].old_value;

    }
}

319
UNITY_COUNTER_TYPE UnityFailureCount(void)
320 321 322 323
{
    return Unity.TestFailures;
}

324 325 326 327 328 329 330 331 332 333
UNITY_COUNTER_TYPE UnityIgnoreCount(void)
{
    return Unity.TestIgnores;
}

UNITY_COUNTER_TYPE UnityTestsCount(void)
{
    return Unity.NumberOfTests;
}

334
int UnityGetCommandLineOptions(int argc, const char* argv[])
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
{
    int i;
    UnityFixture.Verbose = 0;
    UnityFixture.GroupFilter = 0;
    UnityFixture.NameFilter = 0;
    UnityFixture.RepeatCount = 1;

    if (argc == 1)
        return 0;

    for (i = 1; i < argc; )
    {
        if (strcmp(argv[i], "-v") == 0)
        {
            UnityFixture.Verbose = 1;
            i++;
        }
        else if (strcmp(argv[i], "-g") == 0)
        {
            i++;
            if (i >= argc)
                return 1;
            UnityFixture.GroupFilter = argv[i];
            i++;
        }
        else if (strcmp(argv[i], "-n") == 0)
        {
            i++;
            if (i >= argc)
                return 1;
            UnityFixture.NameFilter = argv[i];
            i++;
        }
        else if (strcmp(argv[i], "-r") == 0)
        {
            UnityFixture.RepeatCount = 2;
            i++;
            if (i < argc)
            {
                if (*(argv[i]) >= '0' && *(argv[i]) <= '9')
                {
                    UnityFixture.RepeatCount = atoi(argv[i]);
                    i++;
                }
            }
380 381 382
        } else {
            // ignore unknown parameter
            i++;
383 384 385 386 387
        }
    }
    return 0;
}

388
void UnityConcludeFixtureTest(void)
389 390 391
{
    if (Unity.CurrentTestIgnored)
    {
392 393
        if (UnityFixture.Verbose)
        {
394
            UNITY_PRINT_EOL();
395
        }
396 397 398 399 400 401 402
        Unity.TestIgnores++;
    }
    else if (!Unity.CurrentTestFailed)
    {
        if (UnityFixture.Verbose)
        {
            UnityPrint(" PASS");
403
            UNITY_PRINT_EOL();
404 405 406 407 408
        }
    }
    else if (Unity.CurrentTestFailed)
    {
        Unity.TestFailures++;
409
        UNITY_PRINT_EOL();
410 411 412 413 414
    }

    Unity.CurrentTestFailed = 0;
    Unity.CurrentTestIgnored = 0;
}