unity_fixture.c 10.2 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
#include "unity_fixture.h"
#include "unity_internals.h"

12
struct _UnityFixture UnityFixture;
13 14

//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
{
    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;
}

152 153
// These definitions are always included from unity_fixture_malloc_overrides.h
// We undef to use them or avoid conflict with <stdlib.h> per the C standard
154 155
#undef malloc
#undef free
@
@gageas 已提交
156 157 158
#undef calloc
#undef realloc

159 160 161 162
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
static unsigned char unity_heap[UNITY_INTERNAL_HEAP_SIZE_BYTES];
static unsigned int  heap_index;
#else
163
#include <stdlib.h>
164
#endif
165 166 167

typedef struct GuardBytes
{
168
    size_t size;
169
    size_t guard_space;
170 171 172
} Guard;


173
static const char end[] = "END";
174

175
void* unity_malloc(size_t size)
176 177 178
{
    char* mem;
    Guard* guard;
179
    size_t total_size = size + sizeof(Guard) + sizeof(end);
180 181 182 183

    if (malloc_fail_countdown != MALLOC_DONT_FAIL)
    {
        if (malloc_fail_countdown == 0)
184
            return NULL;
185 186 187
        malloc_fail_countdown--;
    }

188
    if (size == 0) return NULL;
189 190 191 192 193 194 195 196 197 198 199 200 201
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
    if (heap_index + total_size > UNITY_INTERNAL_HEAP_SIZE_BYTES)
    {
        guard = NULL;
    }
    else
    {
        guard = (Guard*) &unity_heap[heap_index];
        heap_index += total_size;
    }
#else
    guard = (Guard*)UNITY_FIXTURE_MALLOC(total_size);
#endif
202
    if (guard == NULL) return NULL;
203
    malloc_count++;
204
    guard->size = size;
205
    guard->guard_space = 0;
206
    mem = (char*)&(guard[1]);
207
    memcpy(&mem[size], end, sizeof(end));
208 209 210 211

    return (void*)mem;
}

212
static int isOverrun(void* mem)
213 214 215 216
{
    Guard* guard = (Guard*)mem;
    char* memAsChar = (char*)mem;
    guard--;
217

218
    return guard->guard_space != 0 || strcmp(&memAsChar[guard->size], end) != 0;
219 220
}

221
static void release_memory(void* mem)
222 223 224 225 226
{
    Guard* guard = (Guard*)mem;
    guard--;

    malloc_count--;
227 228 229 230 231 232
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
    if (mem == unity_heap + heap_index - guard->size - sizeof(end))
    {
        heap_index -= (guard->size + sizeof(Guard) + sizeof(end));
    }
#else
233
    UNITY_FIXTURE_FREE(guard);
234
#endif
235 236
}

237
void unity_free(void* mem)
238
{
239 240 241 242 243 244 245
    int overrun;

    if (mem == NULL)
    {
        return;
    }

246
    overrun = isOverrun(mem);
247 248
    release_memory(mem);
    if (overrun)
249 250 251 252 253 254 255 256
    {
        TEST_FAIL_MESSAGE("Buffer overrun detected during free()");
    }
}

void* unity_calloc(size_t num, size_t size)
{
    void* mem = unity_malloc(num * size);
257
    if (mem == NULL) return NULL;
258
    memset(mem, 0, num * size);
259 260 261
    return mem;
}

262
void* unity_realloc(void* oldMem, size_t size)
263 264 265 266
{
    Guard* guard = (Guard*)oldMem;
    void* newMem;

267
    if (oldMem == NULL) return unity_malloc(size);
268 269

    guard--;
270
    if (isOverrun(oldMem))
271
    {
272
        release_memory(oldMem);
273 274 275 276 277
        TEST_FAIL_MESSAGE("Buffer overrun detected during realloc()");
    }

    if (size == 0)
    {
278
        release_memory(oldMem);
279
        return NULL;
280 281
    }

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

284 285 286 287 288 289 290 291
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC // Optimization if memory is expandable
    if (oldMem == unity_heap + heap_index - guard->size - sizeof(end) &&
        heap_index + size - guard->size <= UNITY_INTERNAL_HEAP_SIZE_BYTES)
    {
        release_memory(oldMem); // Not thread-safe, like unity_heap generally
        return unity_malloc(size); // No memcpy since data is in place
    }
#endif
292
    newMem = unity_malloc(size);
293
    if (newMem == NULL) return NULL; // Do not release old memory
294
    memcpy(newMem, oldMem, guard->size);
295
    release_memory(oldMem);
296 297 298 299 300 301
    return newMem;
}


//--------------------------------------------------------
//Automatic pointer restoration functions
302
struct PointerPair
303
{
304 305
    void** pointer;
    void* old_value;
306
};
307

308 309
enum { MAX_POINTERS = 50 };
static struct PointerPair pointer_store[MAX_POINTERS];
310 311
static int pointer_index = 0;

312
void UnityPointer_Init(void)
313 314 315 316
{
    pointer_index = 0;
}

317
void UnityPointer_Set(void** pointer, void* newValue, UNITY_LINE_TYPE line)
318 319
{
    if (pointer_index >= MAX_POINTERS)
320
    {
321
        UNITY_TEST_FAIL(line, "Too many pointers set");
322 323 324 325 326 327 328 329
    }
    else
    {
        pointer_store[pointer_index].pointer = pointer;
        pointer_store[pointer_index].old_value = *pointer;
        *pointer = newValue;
        pointer_index++;
    }
330 331
}

332
void UnityPointer_UndoAllSets(void)
333 334 335 336 337
{
    while (pointer_index > 0)
    {
        pointer_index--;
        *(pointer_store[pointer_index].pointer) =
338
            pointer_store[pointer_index].old_value;
339 340 341
    }
}

342
UNITY_COUNTER_TYPE UnityFailureCount(void)
343 344 345 346
{
    return Unity.TestFailures;
}

347 348 349 350 351 352 353 354 355 356
UNITY_COUNTER_TYPE UnityIgnoreCount(void)
{
    return Unity.TestIgnores;
}

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

357
int UnityGetCommandLineOptions(int argc, const char* argv[])
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
{
    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')
                {
399 400 401 402 403 404 405
                    unsigned int digit = 0;
                    UnityFixture.RepeatCount = 0;
                    while (argv[i][digit] >= '0' && argv[i][digit] <= '9')
                    {
                        UnityFixture.RepeatCount *= 10;
                        UnityFixture.RepeatCount += (unsigned int)argv[i][digit++] - '0';
                    }
406 407 408
                    i++;
                }
            }
409 410 411
        } else {
            // ignore unknown parameter
            i++;
412 413 414 415 416
        }
    }
    return 0;
}

417
void UnityConcludeFixtureTest(void)
418 419 420
{
    if (Unity.CurrentTestIgnored)
    {
421 422
        if (UnityFixture.Verbose)
        {
423
            UNITY_PRINT_EOL();
424
        }
425 426 427 428 429 430 431
        Unity.TestIgnores++;
    }
    else if (!Unity.CurrentTestFailed)
    {
        if (UnityFixture.Verbose)
        {
            UnityPrint(" PASS");
432
            UNITY_PRINT_EOL();
433 434 435 436 437
        }
    }
    else if (Unity.CurrentTestFailed)
    {
        Unity.TestFailures++;
438
        UNITY_PRINT_EOL();
439 440 441 442 443
    }

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