mirror of
https://github.com/ThrowTheSwitch/Unity.git
synced 2026-01-29 19:24:27 +01:00
Split memory from fixtures and make it's own addon
This commit is contained in:
@@ -55,12 +55,7 @@ def build_compiler_fields
|
||||
defines = if $cfg['compiler']['defines']['items'].nil?
|
||||
''
|
||||
else
|
||||
decl = if $is_windows
|
||||
'UNITY_OUTPUT_CHAR_HEADER_DECLARATION=UnityOutputCharSpy_OutputChar(int)'
|
||||
else
|
||||
'UNITY_OUTPUT_CHAR_HEADER_DECLARATION=UnityOutputCharSpy_OutputChar\(int\)'
|
||||
end
|
||||
squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'] + ['UNITY_OUTPUT_CHAR=UnityOutputCharSpy_OutputChar'] + [decl])
|
||||
squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'])
|
||||
end
|
||||
options = squash('', $cfg['compiler']['options'])
|
||||
includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items'])
|
||||
|
||||
17
extras/fixture/readme.md
Normal file
17
extras/fixture/readme.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Unity Fixtures
|
||||
|
||||
This Framework is an optional add-on to Unity. By including unity_framework.h in place of unity.h,
|
||||
you may now work with Unity in a manner similar to CppUTest. This framework adds the concepts of
|
||||
test groups and gives finer control of your tests over the command line.
|
||||
|
||||
This framework is primarily supplied for those working through James Grenning's book on Embedded
|
||||
Test Driven Development, or those coming to Unity from CppUTest. We should note that using this
|
||||
framework glosses over some of the features of Unity, and makes it more difficult
|
||||
to integrate with other testing tools like Ceedling and CMock.
|
||||
|
||||
# Dependency Notification
|
||||
|
||||
Fixtures, by default, uses the Memory addon as well. This is to make it simple for those trying to
|
||||
follow along with James' book. Using them together is completely optional. You may choose to use
|
||||
Fixtures without Memory handling by defining `UNITY_FIXTURE_NO_EXTRAS`. It will then stop automatically
|
||||
pulling in extras and leave you to do it as desired.
|
||||
@@ -1,9 +0,0 @@
|
||||
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]
|
||||
|
||||
This Framework is an optional add-on to Unity. By including unity_framework.h in place of unity.h,
|
||||
you may now work with Unity in a manner similar to CppUTest. This framework adds the concepts of
|
||||
test groups and gives finer control of your tests over the command line.
|
||||
@@ -94,7 +94,6 @@ void UnityTestRunner(unityfunction* setup,
|
||||
}
|
||||
|
||||
Unity.NumberOfTests++;
|
||||
UnityMalloc_StartTest();
|
||||
UnityPointer_Init();
|
||||
|
||||
UNITY_EXEC_TIME_START();
|
||||
@@ -111,8 +110,6 @@ void UnityTestRunner(unityfunction* setup,
|
||||
if (TEST_PROTECT())
|
||||
{
|
||||
UnityPointer_UndoAllSets();
|
||||
if (!Unity.CurrentTestFailed)
|
||||
UnityMalloc_EndTest();
|
||||
}
|
||||
UnityConcludeFixtureTest();
|
||||
}
|
||||
@@ -140,204 +137,6 @@ void UnityIgnoreTest(const char* printableName, const char* group, const char* n
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------- */
|
||||
/* Malloc and free stuff */
|
||||
#define MALLOC_DONT_FAIL -1
|
||||
static int malloc_count;
|
||||
static int malloc_fail_countdown = MALLOC_DONT_FAIL;
|
||||
|
||||
void UnityMalloc_StartTest(void)
|
||||
{
|
||||
malloc_count = 0;
|
||||
malloc_fail_countdown = MALLOC_DONT_FAIL;
|
||||
}
|
||||
|
||||
void UnityMalloc_EndTest(void)
|
||||
{
|
||||
malloc_fail_countdown = MALLOC_DONT_FAIL;
|
||||
if (malloc_count != 0)
|
||||
{
|
||||
UNITY_TEST_FAIL(Unity.CurrentTestLineNumber, "This test leaks!");
|
||||
}
|
||||
}
|
||||
|
||||
void UnityMalloc_MakeMallocFailAfterCount(int countdown)
|
||||
{
|
||||
malloc_fail_countdown = countdown;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
#undef malloc
|
||||
#undef free
|
||||
#undef calloc
|
||||
#undef realloc
|
||||
|
||||
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
|
||||
static unsigned char unity_heap[UNITY_INTERNAL_HEAP_SIZE_BYTES];
|
||||
static size_t heap_index;
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
typedef struct GuardBytes
|
||||
{
|
||||
size_t size;
|
||||
size_t guard_space;
|
||||
} Guard;
|
||||
|
||||
|
||||
#define UNITY_MALLOC_ALIGNMENT (UNITY_POINTER_WIDTH / 8)
|
||||
static const char end[] = "END";
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void* unity_malloc(size_t size)
|
||||
{
|
||||
char* mem;
|
||||
Guard* guard;
|
||||
size_t total_size;
|
||||
|
||||
total_size = sizeof(Guard) + unity_size_round_up(size + sizeof(end));
|
||||
|
||||
if (malloc_fail_countdown != MALLOC_DONT_FAIL)
|
||||
{
|
||||
if (malloc_fail_countdown == 0)
|
||||
return NULL;
|
||||
malloc_fail_countdown--;
|
||||
}
|
||||
|
||||
if (size == 0) return NULL;
|
||||
#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
|
||||
if (guard == NULL) return NULL;
|
||||
malloc_count++;
|
||||
guard->size = size;
|
||||
guard->guard_space = 0;
|
||||
mem = (char*)&(guard[1]);
|
||||
memcpy(&mem[size], end, sizeof(end));
|
||||
|
||||
return (void*)mem;
|
||||
}
|
||||
|
||||
static int isOverrun(void* mem)
|
||||
{
|
||||
Guard* guard = (Guard*)mem;
|
||||
char* memAsChar = (char*)mem;
|
||||
guard--;
|
||||
|
||||
return guard->guard_space != 0 || strcmp(&memAsChar[guard->size], end) != 0;
|
||||
}
|
||||
|
||||
static void release_memory(void* mem)
|
||||
{
|
||||
Guard* guard = (Guard*)mem;
|
||||
guard--;
|
||||
|
||||
malloc_count--;
|
||||
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
|
||||
{
|
||||
size_t block_size;
|
||||
|
||||
block_size = unity_size_round_up(guard->size + sizeof(end));
|
||||
|
||||
if (mem == unity_heap + heap_index - block_size)
|
||||
{
|
||||
heap_index -= (sizeof(Guard) + block_size);
|
||||
}
|
||||
}
|
||||
#else
|
||||
UNITY_FIXTURE_FREE(guard);
|
||||
#endif
|
||||
}
|
||||
|
||||
void unity_free(void* mem)
|
||||
{
|
||||
int overrun;
|
||||
|
||||
if (mem == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
overrun = isOverrun(mem);
|
||||
release_memory(mem);
|
||||
if (overrun)
|
||||
{
|
||||
UNITY_TEST_FAIL(Unity.CurrentTestLineNumber, "Buffer overrun detected during free()");
|
||||
}
|
||||
}
|
||||
|
||||
void* unity_calloc(size_t num, size_t size)
|
||||
{
|
||||
void* mem = unity_malloc(num * size);
|
||||
if (mem == NULL) return NULL;
|
||||
memset(mem, 0, num * size);
|
||||
return mem;
|
||||
}
|
||||
|
||||
void* unity_realloc(void* oldMem, size_t size)
|
||||
{
|
||||
Guard* guard = (Guard*)oldMem;
|
||||
void* newMem;
|
||||
|
||||
if (oldMem == NULL) return unity_malloc(size);
|
||||
|
||||
guard--;
|
||||
if (isOverrun(oldMem))
|
||||
{
|
||||
release_memory(oldMem);
|
||||
UNITY_TEST_FAIL(Unity.CurrentTestLineNumber, "Buffer overrun detected during realloc()");
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
release_memory(oldMem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (guard->size >= size) return oldMem;
|
||||
|
||||
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC /* Optimization if memory is expandable */
|
||||
{
|
||||
size_t old_total_size = unity_size_round_up(guard->size + sizeof(end));
|
||||
|
||||
if ((oldMem == unity_heap + heap_index - old_total_size) &&
|
||||
((heap_index - old_total_size + unity_size_round_up(size + sizeof(end))) <= 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
|
||||
newMem = unity_malloc(size);
|
||||
if (newMem == NULL) return NULL; /* Do not release old memory */
|
||||
memcpy(newMem, oldMem, guard->size);
|
||||
release_memory(oldMem);
|
||||
return newMem;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/*Automatic pointer restoration functions */
|
||||
struct PointerPair
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
#include "unity.h"
|
||||
#include "unity_internals.h"
|
||||
#include "unity_fixture_malloc_overrides.h"
|
||||
#include "unity_fixture_internals.h"
|
||||
|
||||
int UnityMain(int argc, const char* argv[], void (*runAllTests)(void));
|
||||
@@ -77,7 +76,4 @@ int UnityMain(int argc, const char* argv[], void (*runAllTests)(void));
|
||||
#define DOUBLES_EQUAL(expected, actual, delta) TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual))
|
||||
#endif
|
||||
|
||||
/* You must compile with malloc replacement, as defined in unity_fixture_malloc_overrides.h */
|
||||
void UnityMalloc_MakeMallocFailAfterCount(int countdown);
|
||||
|
||||
#endif /* UNITY_FIXTURE_H_ */
|
||||
|
||||
@@ -33,8 +33,6 @@ void UnityTestRunner(unityfunction* setup,
|
||||
const char* file, unsigned int line);
|
||||
|
||||
void UnityIgnoreTest(const char* printableName, const char* group, const char* name);
|
||||
void UnityMalloc_StartTest(void);
|
||||
void UnityMalloc_EndTest(void);
|
||||
int UnityGetCommandLineOptions(int argc, const char* argv[]);
|
||||
void UnityConcludeFixtureTest(void);
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/* 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]
|
||||
* ========================================== */
|
||||
|
||||
#ifndef UNITY_FIXTURE_MALLOC_OVERRIDES_H_
|
||||
#define UNITY_FIXTURE_MALLOC_OVERRIDES_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
|
||||
/* Define this macro to remove the use of stdlib.h, malloc, and free.
|
||||
* Many embedded systems do not have a heap or malloc/free by default.
|
||||
* This internal unity_malloc() provides allocated memory deterministically from
|
||||
* the end of an array only, unity_free() only releases from end-of-array,
|
||||
* blocks are not coalesced, and memory not freed in LIFO order is stranded. */
|
||||
#ifndef UNITY_INTERNAL_HEAP_SIZE_BYTES
|
||||
#define UNITY_INTERNAL_HEAP_SIZE_BYTES 256
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* These functions are used by the Unity Fixture to allocate and release memory
|
||||
* on the heap and can be overridden with platform-specific implementations.
|
||||
* For example, when using FreeRTOS UNITY_FIXTURE_MALLOC becomes pvPortMalloc()
|
||||
* and UNITY_FIXTURE_FREE becomes vPortFree(). */
|
||||
#if !defined(UNITY_FIXTURE_MALLOC) || !defined(UNITY_FIXTURE_FREE)
|
||||
#include <stdlib.h>
|
||||
#define UNITY_FIXTURE_MALLOC(size) malloc(size)
|
||||
#define UNITY_FIXTURE_FREE(ptr) free(ptr)
|
||||
#else
|
||||
extern void* UNITY_FIXTURE_MALLOC(size_t size);
|
||||
extern void UNITY_FIXTURE_FREE(void* ptr);
|
||||
#endif
|
||||
|
||||
#define malloc unity_malloc
|
||||
#define calloc unity_calloc
|
||||
#define realloc unity_realloc
|
||||
#define free unity_free
|
||||
|
||||
void* unity_malloc(size_t size);
|
||||
void* unity_calloc(size_t num, size_t size);
|
||||
void* unity_realloc(void * oldMem, size_t size);
|
||||
void unity_free(void * mem);
|
||||
|
||||
#endif /* UNITY_FIXTURE_MALLOC_OVERRIDES_H_ */
|
||||
@@ -5,17 +5,10 @@ endif
|
||||
#DEBUG = -O0 -g
|
||||
CFLAGS += -std=c99 -pedantic -Wall -Wextra -Werror
|
||||
CFLAGS += $(DEBUG)
|
||||
DEFINES = -D UNITY_OUTPUT_CHAR=UnityOutputCharSpy_OutputChar
|
||||
ifeq ($(OS),Windows_NT)
|
||||
DEFINES += -D UNITY_OUTPUT_CHAR_HEADER_DECLARATION=UnityOutputCharSpy_OutputChar(int)
|
||||
else
|
||||
DEFINES += -D UNITY_OUTPUT_CHAR_HEADER_DECLARATION=UnityOutputCharSpy_OutputChar\(int\)
|
||||
endif
|
||||
SRC = ../src/unity_fixture.c \
|
||||
../../../src/unity.c \
|
||||
unity_fixture_Test.c \
|
||||
unity_fixture_TestRunner.c \
|
||||
unity_output_Spy.c \
|
||||
main/AllTests.c
|
||||
|
||||
INC_DIR = -I../src -I../../../src/
|
||||
|
||||
@@ -11,8 +11,6 @@ static void runAllTests(void)
|
||||
{
|
||||
RUN_TEST_GROUP(UnityFixture);
|
||||
RUN_TEST_GROUP(UnityCommandOptions);
|
||||
RUN_TEST_GROUP(LeakDetection);
|
||||
RUN_TEST_GROUP(InternalMalloc);
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* ========================================== */
|
||||
|
||||
#include "unity_fixture.h"
|
||||
#include "unity_output_Spy.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -44,71 +43,6 @@ TEST(UnityFixture, PointerSetting)
|
||||
TEST_ASSERT_POINTERS_EQUAL(pointer3, (int*)3);
|
||||
}
|
||||
|
||||
TEST(UnityFixture, ForceMallocFail)
|
||||
{
|
||||
void* m;
|
||||
void* mfails;
|
||||
UnityMalloc_MakeMallocFailAfterCount(1);
|
||||
m = malloc(10);
|
||||
CHECK(m);
|
||||
mfails = malloc(10);
|
||||
TEST_ASSERT_POINTERS_EQUAL(0, mfails);
|
||||
free(m);
|
||||
}
|
||||
|
||||
TEST(UnityFixture, ReallocSmallerIsUnchanged)
|
||||
{
|
||||
void* m1 = malloc(10);
|
||||
void* m2 = realloc(m1, 5);
|
||||
TEST_ASSERT_POINTERS_EQUAL(m1, m2);
|
||||
free(m2);
|
||||
}
|
||||
|
||||
TEST(UnityFixture, ReallocSameIsUnchanged)
|
||||
{
|
||||
void* m1 = malloc(10);
|
||||
void* m2 = realloc(m1, 10);
|
||||
TEST_ASSERT_POINTERS_EQUAL(m1, m2);
|
||||
free(m2);
|
||||
}
|
||||
|
||||
TEST(UnityFixture, ReallocLargerNeeded)
|
||||
{
|
||||
void* m1 = malloc(10);
|
||||
void* m2;
|
||||
CHECK(m1);
|
||||
strcpy((char*)m1, "123456789");
|
||||
m2 = realloc(m1, 15);
|
||||
/* CHECK(m1 != m2); //Depends on implementation */
|
||||
STRCMP_EQUAL("123456789", m2);
|
||||
free(m2);
|
||||
}
|
||||
|
||||
TEST(UnityFixture, ReallocNullPointerIsLikeMalloc)
|
||||
{
|
||||
void* m = realloc(0, 15);
|
||||
CHECK(m != 0);
|
||||
free(m);
|
||||
}
|
||||
|
||||
TEST(UnityFixture, ReallocSizeZeroFreesMemAndReturnsNullPointer)
|
||||
{
|
||||
void* m1 = malloc(10);
|
||||
void* m2 = realloc(m1, 0);
|
||||
TEST_ASSERT_POINTERS_EQUAL(0, m2);
|
||||
}
|
||||
|
||||
TEST(UnityFixture, CallocFillsWithZero)
|
||||
{
|
||||
void* m = calloc(3, sizeof(char));
|
||||
char* s = (char*)m;
|
||||
CHECK(m);
|
||||
TEST_ASSERT_BYTES_EQUAL(0, s[0]);
|
||||
TEST_ASSERT_BYTES_EQUAL(0, s[1]);
|
||||
TEST_ASSERT_BYTES_EQUAL(0, s[2]);
|
||||
free(m);
|
||||
}
|
||||
|
||||
static char *p1;
|
||||
static char *p2;
|
||||
|
||||
@@ -140,12 +74,10 @@ TEST(UnityFixture, ConcludeTestIncrementsFailCount)
|
||||
{
|
||||
UNITY_UINT savedFails = Unity.TestFailures;
|
||||
UNITY_UINT savedIgnores = Unity.TestIgnores;
|
||||
UnityOutputCharSpy_Enable(1);
|
||||
Unity.CurrentTestFailed = 1;
|
||||
UnityConcludeFixtureTest(); /* Resets TestFailed for this test to pass */
|
||||
Unity.CurrentTestIgnored = 1;
|
||||
UnityConcludeFixtureTest(); /* Resets TestIgnored */
|
||||
UnityOutputCharSpy_Enable(0);
|
||||
TEST_ASSERT_EQUAL(savedFails + 1, Unity.TestFailures);
|
||||
TEST_ASSERT_EQUAL(savedIgnores + 1, Unity.TestIgnores);
|
||||
Unity.TestFailures = savedFails;
|
||||
@@ -311,235 +243,3 @@ IGNORE_TEST(UnityCommandOptions, TestShouldBeIgnored)
|
||||
{
|
||||
TEST_FAIL_MESSAGE("This test should not run!");
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------ */
|
||||
|
||||
TEST_GROUP(LeakDetection);
|
||||
|
||||
TEST_SETUP(LeakDetection)
|
||||
{
|
||||
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
|
||||
UnityOutputCharSpy_Create(200);
|
||||
#else
|
||||
UnityOutputCharSpy_Create(1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_TEAR_DOWN(LeakDetection)
|
||||
{
|
||||
UnityOutputCharSpy_Destroy();
|
||||
}
|
||||
|
||||
#define EXPECT_ABORT_BEGIN \
|
||||
{ \
|
||||
jmp_buf TestAbortFrame; \
|
||||
memcpy(TestAbortFrame, Unity.AbortFrame, sizeof(jmp_buf)); \
|
||||
if (TEST_PROTECT()) \
|
||||
{
|
||||
|
||||
#define EXPECT_ABORT_END \
|
||||
} \
|
||||
memcpy(Unity.AbortFrame, TestAbortFrame, sizeof(jmp_buf)); \
|
||||
}
|
||||
|
||||
/* This tricky set of defines lets us see if we are using the Spy, returns 1 if true */
|
||||
#ifdef __STDC_VERSION__
|
||||
|
||||
#ifdef UNITY_SUPPORT_VARIADIC_MACROS
|
||||
#define USING_SPY_AS(a) EXPAND_AND_USE_2ND(ASSIGN_VALUE(a), 0)
|
||||
#define ASSIGN_VALUE(a) VAL_##a
|
||||
#define VAL_UnityOutputCharSpy_OutputChar 0, 1
|
||||
#define EXPAND_AND_USE_2ND(a, b) SECOND_PARAM(a, b, throwaway)
|
||||
#define SECOND_PARAM(a, b, ...) b
|
||||
#if USING_SPY_AS(UNITY_OUTPUT_CHAR)
|
||||
#define USING_OUTPUT_SPY /* UNITY_OUTPUT_CHAR = UnityOutputCharSpy_OutputChar */
|
||||
#endif
|
||||
#endif /* UNITY_SUPPORT_VARIADIC_MACROS */
|
||||
|
||||
#else /* __STDC_VERSION__ else */
|
||||
|
||||
#define UnityOutputCharSpy_OutputChar 42
|
||||
#if UNITY_OUTPUT_CHAR == UnityOutputCharSpy_OutputChar /* Works if no -Wundef -Werror */
|
||||
#define USING_OUTPUT_SPY
|
||||
#endif
|
||||
#undef UnityOutputCharSpy_OutputChar
|
||||
|
||||
#endif /* __STDC_VERSION__ */
|
||||
|
||||
TEST(LeakDetection, DetectsLeak)
|
||||
{
|
||||
#ifndef USING_OUTPUT_SPY
|
||||
TEST_IGNORE_MESSAGE("Build with '-D UNITY_OUTPUT_CHAR=UnityOutputCharSpy_OutputChar' to enable tests");
|
||||
#else
|
||||
void* m = malloc(10);
|
||||
TEST_ASSERT_NOT_NULL(m);
|
||||
UnityOutputCharSpy_Enable(1);
|
||||
EXPECT_ABORT_BEGIN
|
||||
UnityMalloc_EndTest();
|
||||
EXPECT_ABORT_END
|
||||
UnityOutputCharSpy_Enable(0);
|
||||
Unity.CurrentTestFailed = 0;
|
||||
CHECK(strstr(UnityOutputCharSpy_Get(), "This test leaks!"));
|
||||
free(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(LeakDetection, BufferOverrunFoundDuringFree)
|
||||
{
|
||||
#ifndef USING_OUTPUT_SPY
|
||||
TEST_IGNORE();
|
||||
#else
|
||||
void* m = malloc(10);
|
||||
char* s = (char*)m;
|
||||
TEST_ASSERT_NOT_NULL(m);
|
||||
s[10] = (char)0xFF;
|
||||
UnityOutputCharSpy_Enable(1);
|
||||
EXPECT_ABORT_BEGIN
|
||||
free(m);
|
||||
EXPECT_ABORT_END
|
||||
UnityOutputCharSpy_Enable(0);
|
||||
Unity.CurrentTestFailed = 0;
|
||||
CHECK(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during free()"));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(LeakDetection, BufferOverrunFoundDuringRealloc)
|
||||
{
|
||||
#ifndef USING_OUTPUT_SPY
|
||||
TEST_IGNORE();
|
||||
#else
|
||||
void* m = malloc(10);
|
||||
char* s = (char*)m;
|
||||
TEST_ASSERT_NOT_NULL(m);
|
||||
s[10] = (char)0xFF;
|
||||
UnityOutputCharSpy_Enable(1);
|
||||
EXPECT_ABORT_BEGIN
|
||||
m = realloc(m, 100);
|
||||
EXPECT_ABORT_END
|
||||
UnityOutputCharSpy_Enable(0);
|
||||
Unity.CurrentTestFailed = 0;
|
||||
CHECK(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during realloc()"));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(LeakDetection, BufferGuardWriteFoundDuringFree)
|
||||
{
|
||||
#ifndef USING_OUTPUT_SPY
|
||||
TEST_IGNORE();
|
||||
#else
|
||||
void* m = malloc(10);
|
||||
char* s = (char*)m;
|
||||
TEST_ASSERT_NOT_NULL(m);
|
||||
s[-1] = (char)0x00; /* Will not detect 0 */
|
||||
s[-2] = (char)0x01;
|
||||
UnityOutputCharSpy_Enable(1);
|
||||
EXPECT_ABORT_BEGIN
|
||||
free(m);
|
||||
EXPECT_ABORT_END
|
||||
UnityOutputCharSpy_Enable(0);
|
||||
Unity.CurrentTestFailed = 0;
|
||||
CHECK(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during free()"));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(LeakDetection, BufferGuardWriteFoundDuringRealloc)
|
||||
{
|
||||
#ifndef USING_OUTPUT_SPY
|
||||
TEST_IGNORE();
|
||||
#else
|
||||
void* m = malloc(10);
|
||||
char* s = (char*)m;
|
||||
TEST_ASSERT_NOT_NULL(m);
|
||||
s[-1] = (char)0x0A;
|
||||
UnityOutputCharSpy_Enable(1);
|
||||
EXPECT_ABORT_BEGIN
|
||||
m = realloc(m, 100);
|
||||
EXPECT_ABORT_END
|
||||
UnityOutputCharSpy_Enable(0);
|
||||
Unity.CurrentTestFailed = 0;
|
||||
CHECK(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during realloc()"));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(LeakDetection, PointerSettingMax)
|
||||
{
|
||||
#ifndef USING_OUTPUT_SPY
|
||||
TEST_IGNORE();
|
||||
#else
|
||||
int i;
|
||||
for (i = 0; i < UNITY_MAX_POINTERS; i++) UT_PTR_SET(pointer1, &int1);
|
||||
UnityOutputCharSpy_Enable(1);
|
||||
EXPECT_ABORT_BEGIN
|
||||
UT_PTR_SET(pointer1, &int1);
|
||||
EXPECT_ABORT_END
|
||||
UnityOutputCharSpy_Enable(0);
|
||||
Unity.CurrentTestFailed = 0;
|
||||
CHECK(strstr(UnityOutputCharSpy_Get(), "Too many pointers set"));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------ */
|
||||
|
||||
TEST_GROUP(InternalMalloc);
|
||||
#define TEST_ASSERT_MEMORY_ALL_FREE_LIFO_ORDER(first_mem_ptr, ptr) \
|
||||
ptr = malloc(10); free(ptr); \
|
||||
TEST_ASSERT_EQUAL_PTR_MESSAGE(first_mem_ptr, ptr, "Memory was stranded, free in LIFO order");
|
||||
|
||||
|
||||
TEST_SETUP(InternalMalloc) { }
|
||||
TEST_TEAR_DOWN(InternalMalloc) { }
|
||||
|
||||
TEST(InternalMalloc, MallocPastBufferFails)
|
||||
{
|
||||
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
|
||||
void* m = malloc(UNITY_INTERNAL_HEAP_SIZE_BYTES/2 + 1);
|
||||
void* n = malloc(UNITY_INTERNAL_HEAP_SIZE_BYTES/2);
|
||||
free(m);
|
||||
TEST_ASSERT_NOT_NULL(m);
|
||||
TEST_ASSERT_NULL(n);
|
||||
TEST_ASSERT_MEMORY_ALL_FREE_LIFO_ORDER(m, n);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(InternalMalloc, CallocPastBufferFails)
|
||||
{
|
||||
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
|
||||
void* m = calloc(1, UNITY_INTERNAL_HEAP_SIZE_BYTES/2 + 1);
|
||||
void* n = calloc(1, UNITY_INTERNAL_HEAP_SIZE_BYTES/2);
|
||||
free(m);
|
||||
TEST_ASSERT_NOT_NULL(m);
|
||||
TEST_ASSERT_NULL(n);
|
||||
TEST_ASSERT_MEMORY_ALL_FREE_LIFO_ORDER(m, n);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(InternalMalloc, MallocThenReallocGrowsMemoryInPlace)
|
||||
{
|
||||
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
|
||||
void* m = malloc(UNITY_INTERNAL_HEAP_SIZE_BYTES/2 + 1);
|
||||
void* n = realloc(m, UNITY_INTERNAL_HEAP_SIZE_BYTES/2 + 9);
|
||||
free(n);
|
||||
TEST_ASSERT_NOT_NULL(m);
|
||||
TEST_ASSERT_EQUAL(m, n);
|
||||
TEST_ASSERT_MEMORY_ALL_FREE_LIFO_ORDER(m, n);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(InternalMalloc, ReallocFailDoesNotFreeMem)
|
||||
{
|
||||
#ifdef UNITY_EXCLUDE_STDLIB_MALLOC
|
||||
void* m = malloc(UNITY_INTERNAL_HEAP_SIZE_BYTES/2);
|
||||
void* n1 = malloc(10);
|
||||
void* out_of_mem = realloc(n1, UNITY_INTERNAL_HEAP_SIZE_BYTES/2 + 1);
|
||||
void* n2 = malloc(10);
|
||||
|
||||
free(n2);
|
||||
if (out_of_mem == NULL) free(n1);
|
||||
free(m);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(m); /* Got a real memory location */
|
||||
TEST_ASSERT_NULL(out_of_mem); /* The realloc should have failed */
|
||||
TEST_ASSERT_NOT_EQUAL(n2, n1); /* If n1 != n2 then realloc did not free n1 */
|
||||
TEST_ASSERT_MEMORY_ALL_FREE_LIFO_ORDER(m, n2);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -10,13 +10,6 @@
|
||||
TEST_GROUP_RUNNER(UnityFixture)
|
||||
{
|
||||
RUN_TEST_CASE(UnityFixture, PointerSetting);
|
||||
RUN_TEST_CASE(UnityFixture, ForceMallocFail);
|
||||
RUN_TEST_CASE(UnityFixture, ReallocSmallerIsUnchanged);
|
||||
RUN_TEST_CASE(UnityFixture, ReallocSameIsUnchanged);
|
||||
RUN_TEST_CASE(UnityFixture, ReallocLargerNeeded);
|
||||
RUN_TEST_CASE(UnityFixture, ReallocNullPointerIsLikeMalloc);
|
||||
RUN_TEST_CASE(UnityFixture, ReallocSizeZeroFreesMemAndReturnsNullPointer);
|
||||
RUN_TEST_CASE(UnityFixture, CallocFillsWithZero);
|
||||
RUN_TEST_CASE(UnityFixture, PointerSet);
|
||||
RUN_TEST_CASE(UnityFixture, FreeNULLSafety);
|
||||
RUN_TEST_CASE(UnityFixture, ConcludeTestIncrementsFailCount);
|
||||
@@ -37,21 +30,3 @@ TEST_GROUP_RUNNER(UnityCommandOptions)
|
||||
RUN_TEST_CASE(UnityCommandOptions, GroupFilterReallyFilters);
|
||||
RUN_TEST_CASE(UnityCommandOptions, TestShouldBeIgnored);
|
||||
}
|
||||
|
||||
TEST_GROUP_RUNNER(LeakDetection)
|
||||
{
|
||||
RUN_TEST_CASE(LeakDetection, DetectsLeak);
|
||||
RUN_TEST_CASE(LeakDetection, BufferOverrunFoundDuringFree);
|
||||
RUN_TEST_CASE(LeakDetection, BufferOverrunFoundDuringRealloc);
|
||||
RUN_TEST_CASE(LeakDetection, BufferGuardWriteFoundDuringFree);
|
||||
RUN_TEST_CASE(LeakDetection, BufferGuardWriteFoundDuringRealloc);
|
||||
RUN_TEST_CASE(LeakDetection, PointerSettingMax);
|
||||
}
|
||||
|
||||
TEST_GROUP_RUNNER(InternalMalloc)
|
||||
{
|
||||
RUN_TEST_CASE(InternalMalloc, MallocPastBufferFails);
|
||||
RUN_TEST_CASE(InternalMalloc, CallocPastBufferFails);
|
||||
RUN_TEST_CASE(InternalMalloc, MallocThenReallocGrowsMemoryInPlace);
|
||||
RUN_TEST_CASE(InternalMalloc, ReallocFailDoesNotFreeMem);
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/* 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]
|
||||
* ========================================== */
|
||||
|
||||
|
||||
#include "unity_output_Spy.h"
|
||||
#include "unity_fixture.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static int size;
|
||||
static int count;
|
||||
static char* buffer;
|
||||
static int spy_enable;
|
||||
|
||||
void UnityOutputCharSpy_Create(int s)
|
||||
{
|
||||
size = (s > 0) ? s : 0;
|
||||
count = 0;
|
||||
spy_enable = 0;
|
||||
buffer = malloc((size_t)size);
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(buffer, "Internal malloc failed in Spy Create():" __FILE__);
|
||||
memset(buffer, 0, (size_t)size);
|
||||
}
|
||||
|
||||
void UnityOutputCharSpy_Destroy(void)
|
||||
{
|
||||
size = 0;
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void UnityOutputCharSpy_OutputChar(int c)
|
||||
{
|
||||
if (spy_enable)
|
||||
{
|
||||
if (count < (size-1))
|
||||
buffer[count++] = (char)c;
|
||||
}
|
||||
else
|
||||
{
|
||||
putchar(c);
|
||||
}
|
||||
}
|
||||
|
||||
const char * UnityOutputCharSpy_Get(void)
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void UnityOutputCharSpy_Enable(int enable)
|
||||
{
|
||||
spy_enable = enable;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/* 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]
|
||||
* ========================================== */
|
||||
|
||||
#ifndef D_unity_output_Spy_H
|
||||
#define D_unity_output_Spy_H
|
||||
|
||||
void UnityOutputCharSpy_Create(int s);
|
||||
void UnityOutputCharSpy_Destroy(void);
|
||||
void UnityOutputCharSpy_OutputChar(int c);
|
||||
const char * UnityOutputCharSpy_Get(void);
|
||||
void UnityOutputCharSpy_Enable(int enable);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user