unity_fixture.c 10.9 KB
Newer Older
J
jsalling 已提交
1 2 3 4 5 6
/* 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]
 * ========================================== */
7 8 9

#include "unity_fixture.h"
#include "unity_internals.h"
10
#include <string.h>
11

12
struct UNITY_FIXTURE_T UnityFixture;
13

J
jsalling 已提交
14 15 16
/* If you decide to use the function pointer approach.
 * Build with -D UNITY_OUTPUT_CHAR=outputChar and include <stdio.h>
 * int (*outputChar)(int) = putchar; */
17 18 19 20

void setUp(void)    { /*does nothing*/ }
void tearDown(void) { /*does nothing*/ }

21
static void announceTestRun(unsigned int runNumber)
22 23
{
    UnityPrint("Unity test run ");
24
    UnityPrintNumberUnsigned(runNumber+1);
25
    UnityPrint(" of ");
26
    UnityPrintNumberUnsigned(UnityFixture.RepeatCount);
27
    UNITY_PRINT_EOL();
28 29
}

30
int UnityMain(int argc, const char* argv[], void (*runAllTests)(void))
31 32
{
    int result = UnityGetCommandLineOptions(argc, argv);
33
    unsigned int r;
34 35 36 37 38
    if (result != 0)
        return result;

    for (r = 0; r < UnityFixture.RepeatCount; r++)
    {
39
        UnityBegin(argv[0]);
40
        announceTestRun(r);
41
        runAllTests();
42
        if (!UnityFixture.Verbose) UNITY_PRINT_EOL();
43 44 45
        UnityEnd();
    }

46
    return (int)Unity.TestFailures;
47 48
}

49
static int selected(const char* filter, const char* name)
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
{
    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,
67 68 69 70 71
                     unityfunction* testBody,
                     unityfunction* teardown,
                     const char* printableName,
                     const char* group,
                     const char* name,
72 73
                     const char* file,
                     unsigned int line)
74 75 76 77 78 79
{
    if (testSelected(name) && groupSelected(group))
    {
        Unity.TestFile = file;
        Unity.CurrentTestName = printableName;
        Unity.CurrentTestLineNumber = line;
D
Dom Postorivo 已提交
80
        if (UnityFixture.Verbose)
81
        {
82
            UnityPrint(printableName);
83 84 85 86
        #ifndef UNITY_REPEAT_TEST_NAME
            Unity.CurrentTestName = NULL;
        #endif
        }
D
Dom Postorivo 已提交
87 88 89 90 91 92 93 94
        else if (UnityFixture.Silent)
        {
            /* Do Nothing */
        }
        else
        {
            UNITY_OUTPUT_CHAR('.');
        }
95 96 97 98 99

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

100 101
        UNITY_EXEC_TIME_START();

102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
        if (TEST_PROTECT())
        {
            setup();
            testBody();
        }
        if (TEST_PROTECT())
        {
            teardown();
        }
        if (TEST_PROTECT())
        {
            UnityPointer_UndoAllSets();
            if (!Unity.CurrentTestFailed)
                UnityMalloc_EndTest();
        }
117
        UnityConcludeFixtureTest();
118 119 120
    }
}

121
void UnityIgnoreTest(const char* printableName, const char* group, const char* name)
122
{
123
    if (testSelected(name) && groupSelected(group))
124 125
    {
        Unity.NumberOfTests++;
126
        Unity.TestIgnores++;
D
Dom Postorivo 已提交
127
        if (UnityFixture.Verbose)
128
        {
129
            UnityPrint(printableName);
130 131
            UNITY_PRINT_EOL();
        }
D
Dom Postorivo 已提交
132 133 134 135 136 137 138 139
        else if (UnityFixture.Silent)
        {
            /* Do Nothing */
        }
        else
        {
            UNITY_OUTPUT_CHAR('!');
        }
140
    }
141 142
}

143

J
jsalling 已提交
144 145
/*------------------------------------------------- */
/* Malloc and free stuff */
146 147 148 149
#define MALLOC_DONT_FAIL -1
static int malloc_count;
static int malloc_fail_countdown = MALLOC_DONT_FAIL;

150
void UnityMalloc_StartTest(void)
151 152 153 154 155
{
    malloc_count = 0;
    malloc_fail_countdown = MALLOC_DONT_FAIL;
}

156
void UnityMalloc_EndTest(void)
157 158 159 160
{
    malloc_fail_countdown = MALLOC_DONT_FAIL;
    if (malloc_count != 0)
    {
161
        UNITY_TEST_FAIL(Unity.CurrentTestLineNumber, "This test leaks!");
162 163 164 165 166 167 168 169
    }
}

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

J
jsalling 已提交
170 171
/* 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 */
172 173
#undef malloc
#undef free
@
@gageas 已提交
174 175 176
#undef calloc
#undef realloc

177 178
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
static unsigned char unity_heap[UNITY_INTERNAL_HEAP_SIZE_BYTES];
179
static size_t heap_index;
180
#else
181
#include <stdlib.h>
182
#endif
183 184 185

typedef struct GuardBytes
{
186
    size_t size;
187
    size_t guard_space;
188 189 190
} Guard;


A
Alessio Centazzo 已提交
191
#define UNITY_MALLOC_ALIGNMENT (UNITY_POINTER_WIDTH / 8)
192
static const char end[] = "END";
193

A
Alessio Centazzo 已提交
194 195 196 197 198 199 200 201 202 203

static size_t unity_size_round_up(size_t size)
{
    size_t rounded_size;

    rounded_size = ((size + UNITY_MALLOC_ALIGNMENT - 1) / UNITY_MALLOC_ALIGNMENT) * UNITY_MALLOC_ALIGNMENT;

    return rounded_size;
}

204
void* unity_malloc(size_t size)
205 206 207
{
    char* mem;
    Guard* guard;
A
Alessio Centazzo 已提交
208 209 210
    size_t total_size;

    total_size = sizeof(Guard) + unity_size_round_up(size + sizeof(end));
211 212 213 214

    if (malloc_fail_countdown != MALLOC_DONT_FAIL)
    {
        if (malloc_fail_countdown == 0)
215
            return NULL;
216 217 218
        malloc_fail_countdown--;
    }

219
    if (size == 0) return NULL;
220 221 222 223 224 225 226
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
    if (heap_index + total_size > UNITY_INTERNAL_HEAP_SIZE_BYTES)
    {
        guard = NULL;
    }
    else
    {
227
        guard = (Guard*)&unity_heap[heap_index];
228 229 230 231 232
        heap_index += total_size;
    }
#else
    guard = (Guard*)UNITY_FIXTURE_MALLOC(total_size);
#endif
233
    if (guard == NULL) return NULL;
234
    malloc_count++;
235
    guard->size = size;
236
    guard->guard_space = 0;
237
    mem = (char*)&(guard[1]);
238
    memcpy(&mem[size], end, sizeof(end));
239 240 241 242

    return (void*)mem;
}

243
static int isOverrun(void* mem)
244 245 246 247
{
    Guard* guard = (Guard*)mem;
    char* memAsChar = (char*)mem;
    guard--;
248

249
    return guard->guard_space != 0 || strcmp(&memAsChar[guard->size], end) != 0;
250 251
}

252
static void release_memory(void* mem)
253 254 255 256 257
{
    Guard* guard = (Guard*)mem;
    guard--;

    malloc_count--;
258
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
A
Alessio Centazzo 已提交
259 260 261 262 263
    size_t block_size;

    block_size = unity_size_round_up(guard->size + sizeof(end));

    if (mem == unity_heap + heap_index - block_size)
264
    {
A
Alessio Centazzo 已提交
265
        heap_index -= (sizeof(Guard) + block_size);
266 267
    }
#else
268
    UNITY_FIXTURE_FREE(guard);
269
#endif
270 271
}

272
void unity_free(void* mem)
273
{
274 275 276 277 278 279 280
    int overrun;

    if (mem == NULL)
    {
        return;
    }

281
    overrun = isOverrun(mem);
282 283
    release_memory(mem);
    if (overrun)
284
    {
285
        UNITY_TEST_FAIL(Unity.CurrentTestLineNumber, "Buffer overrun detected during free()");
286 287 288 289 290 291
    }
}

void* unity_calloc(size_t num, size_t size)
{
    void* mem = unity_malloc(num * size);
292
    if (mem == NULL) return NULL;
293
    memset(mem, 0, num * size);
294 295 296
    return mem;
}

297
void* unity_realloc(void* oldMem, size_t size)
298 299 300 301
{
    Guard* guard = (Guard*)oldMem;
    void* newMem;

302
    if (oldMem == NULL) return unity_malloc(size);
303 304

    guard--;
305
    if (isOverrun(oldMem))
306
    {
307
        release_memory(oldMem);
308
        UNITY_TEST_FAIL(Unity.CurrentTestLineNumber, "Buffer overrun detected during realloc()");
309 310 311 312
    }

    if (size == 0)
    {
313
        release_memory(oldMem);
314
        return NULL;
315 316
    }

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

J
jsalling 已提交
319
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC /* Optimization if memory is expandable */
320 321 322
    if (oldMem == unity_heap + heap_index - guard->size - sizeof(end) &&
        heap_index + size - guard->size <= UNITY_INTERNAL_HEAP_SIZE_BYTES)
    {
323
        release_memory(oldMem);    /* Not thread-safe, like unity_heap generally */
J
jsalling 已提交
324
        return unity_malloc(size); /* No memcpy since data is in place */
325 326
    }
#endif
327
    newMem = unity_malloc(size);
J
jsalling 已提交
328
    if (newMem == NULL) return NULL; /* Do not release old memory */
329
    memcpy(newMem, oldMem, guard->size);
330
    release_memory(oldMem);
331 332 333 334
    return newMem;
}


J
jsalling 已提交
335 336
/*-------------------------------------------------------- */
/*Automatic pointer restoration functions */
337
struct PointerPair
338
{
339 340
    void** pointer;
    void* old_value;
341
};
342

343
static struct PointerPair pointer_store[UNITY_MAX_POINTERS];
344 345
static int pointer_index = 0;

346
void UnityPointer_Init(void)
347 348 349 350
{
    pointer_index = 0;
}

351
void UnityPointer_Set(void** pointer, void* newValue, UNITY_LINE_TYPE line)
352
{
353
    if (pointer_index >= UNITY_MAX_POINTERS)
354
    {
355
        UNITY_TEST_FAIL(line, "Too many pointers set");
356 357 358 359 360 361 362 363
    }
    else
    {
        pointer_store[pointer_index].pointer = pointer;
        pointer_store[pointer_index].old_value = *pointer;
        *pointer = newValue;
        pointer_index++;
    }
364 365
}

366
void UnityPointer_UndoAllSets(void)
367 368 369 370 371
{
    while (pointer_index > 0)
    {
        pointer_index--;
        *(pointer_store[pointer_index].pointer) =
372
            pointer_store[pointer_index].old_value;
373 374 375
    }
}

376
int UnityGetCommandLineOptions(int argc, const char* argv[])
377 378 379
{
    int i;
    UnityFixture.Verbose = 0;
D
Dom Postorivo 已提交
380
    UnityFixture.Silent = 0;
381 382 383 384 385 386 387 388 389 390 391 392 393 394
    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++;
        }
D
Dom Postorivo 已提交
395 396 397 398 399
        else if (strcmp(argv[i], "-s") == 0)
        {
            UnityFixture.Silent = 1;
            i++;
        }
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
        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')
                {
424 425 426 427 428 429 430
                    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';
                    }
431 432 433
                    i++;
                }
            }
434 435 436
        }
        else
        {
J
jsalling 已提交
437
            /* ignore unknown parameter */
438
            i++;
439 440 441 442 443
        }
    }
    return 0;
}

444
void UnityConcludeFixtureTest(void)
445 446 447 448
{
    if (Unity.CurrentTestIgnored)
    {
        Unity.TestIgnores++;
449
        UNITY_PRINT_EOL();
450 451 452 453 454
    }
    else if (!Unity.CurrentTestFailed)
    {
        if (UnityFixture.Verbose)
        {
455 456
            UnityPrint(" ");
            UnityPrint(UnityStrPass);
457 458
            UNITY_EXEC_TIME_STOP();
            UNITY_PRINT_EXEC_TIME();
459
            UNITY_PRINT_EOL();
460 461
        }
    }
J
jsalling 已提交
462
    else /* Unity.CurrentTestFailed */
463 464
    {
        Unity.TestFailures++;
465
        UNITY_PRINT_EOL();
466 467 468 469 470
    }

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