Unit Testing framework based on http://cpputest.github.io/

CppUTest

Where to find more information

Getting test reports on the console

You may need to tailor the file src/Platforms/mbed/UtestPlatform.cpp to your needs. In particular, if you want console output, you might want to look at the function PlatformSpecificPutchar().

Quick introduction (some code!)

To write your first test, all you need is a new cpp file with a TEST_GROUP and a TEST, like:

#include "CppUTest/TestHarness.h"

TEST_GROUP(FirstTestGroup)
{
};

TEST(FirstTestGroup, FirstTest)
{
   FAIL("Fail me!");
}

This test will fail.

You can add new tests to the test group by just writing more tests in the file, like this:

TEST(FirstTestGroup, SecondTest)
{
   STRCMP_EQUAL("hello", "world");
   LONGS_EQUAL(1, 2);
   CHECK(false);
}

You do need to trigger the tests from somewhere in your program. It could look something like:

#include "CppUTest/TestRegistry.h"
#include "CppUTest/CommandLineTestRunner.h"

int main(int ac, char** av)
{
    ....
    unsigned failureCount = 0;
    {
        ConsoleTestOutput output;
        CommandLineTestRunner runner(ac, av, &output, TestRegistry::getCurrentRegistry());
        failureCount = runner.runAllTestsMain();
    }

    if (failureCount == 0) {
        console.printf("PASSED\r\n");
    }
    ...
}

For more information, We’d recommend to read the manual or, even better, check some existing tests such as SimpleStringTest or (a bit more complicated) MemoryLeakDetectorTest or the mocking tests or just check out the Cheat Sheet.

Committer:
rgrover1
Date:
Tue Jan 28 09:27:41 2014 +0000
Revision:
0:0b799af9d58e
Child:
1:4769360130ed
CppUTest unit test framework.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 0:0b799af9d58e 1 /*
rgrover1 0:0b799af9d58e 2 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
rgrover1 0:0b799af9d58e 3 * All rights reserved.
rgrover1 0:0b799af9d58e 4 *
rgrover1 0:0b799af9d58e 5 * Redistribution and use in source and binary forms, with or without
rgrover1 0:0b799af9d58e 6 * modification, are permitted provided that the following conditions are met:
rgrover1 0:0b799af9d58e 7 * * Redistributions of source code must retain the above copyright
rgrover1 0:0b799af9d58e 8 * notice, this list of conditions and the following disclaimer.
rgrover1 0:0b799af9d58e 9 * * Redistributions in binary form must reproduce the above copyright
rgrover1 0:0b799af9d58e 10 * notice, this list of conditions and the following disclaimer in the
rgrover1 0:0b799af9d58e 11 * documentation and/or other materials provided with the distribution.
rgrover1 0:0b799af9d58e 12 * * Neither the name of the <organization> nor the
rgrover1 0:0b799af9d58e 13 * names of its contributors may be used to endorse or promote products
rgrover1 0:0b799af9d58e 14 * derived from this software without specific prior written permission.
rgrover1 0:0b799af9d58e 15 *
rgrover1 0:0b799af9d58e 16 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
rgrover1 0:0b799af9d58e 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
rgrover1 0:0b799af9d58e 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
rgrover1 0:0b799af9d58e 19 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
rgrover1 0:0b799af9d58e 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
rgrover1 0:0b799af9d58e 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
rgrover1 0:0b799af9d58e 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
rgrover1 0:0b799af9d58e 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
rgrover1 0:0b799af9d58e 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
rgrover1 0:0b799af9d58e 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
rgrover1 0:0b799af9d58e 26 */
rgrover1 0:0b799af9d58e 27
rgrover1 0:0b799af9d58e 28 #include "CppUTest/TestHarness.h"
rgrover1 0:0b799af9d58e 29 #include "CppUTest/MemoryLeakWarningPlugin.h"
rgrover1 0:0b799af9d58e 30 #include "CppUTest/MemoryLeakDetector.h"
rgrover1 0:0b799af9d58e 31 #include "CppUTest/TestMemoryAllocator.h"
rgrover1 0:0b799af9d58e 32 #include "CppUTest/PlatformSpecificFunctions.h"
rgrover1 0:0b799af9d58e 33
rgrover1 0:0b799af9d58e 34 /********** Enabling and disabling for C also *********/
rgrover1 0:0b799af9d58e 35
rgrover1 0:0b799af9d58e 36 #if CPPUTEST_USE_MEM_LEAK_DETECTION
rgrover1 0:0b799af9d58e 37
rgrover1 0:0b799af9d58e 38 static void* mem_leak_malloc(size_t size, const char* file, int line)
rgrover1 0:0b799af9d58e 39 {
rgrover1 0:0b799af9d58e 40 return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentMallocAllocator(), size, file, line, true);
rgrover1 0:0b799af9d58e 41 }
rgrover1 0:0b799af9d58e 42
rgrover1 0:0b799af9d58e 43 static void mem_leak_free(void* buffer, const char* file, int line)
rgrover1 0:0b799af9d58e 44 {
rgrover1 0:0b799af9d58e 45 MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) buffer);
rgrover1 0:0b799af9d58e 46 MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentMallocAllocator(), (char*) buffer, file, line, true);
rgrover1 0:0b799af9d58e 47 }
rgrover1 0:0b799af9d58e 48
rgrover1 0:0b799af9d58e 49 static void* mem_leak_realloc(void* memory, size_t size, const char* file, int line)
rgrover1 0:0b799af9d58e 50 {
rgrover1 0:0b799af9d58e 51 return MemoryLeakWarningPlugin::getGlobalDetector()->reallocMemory(getCurrentMallocAllocator(), (char*) memory, size, file, line, true);
rgrover1 0:0b799af9d58e 52 }
rgrover1 0:0b799af9d58e 53
rgrover1 0:0b799af9d58e 54 #endif
rgrover1 0:0b799af9d58e 55
rgrover1 0:0b799af9d58e 56 static void* normal_malloc(size_t size, const char*, int)
rgrover1 0:0b799af9d58e 57 {
rgrover1 0:0b799af9d58e 58 return PlatformSpecificMalloc(size);
rgrover1 0:0b799af9d58e 59 }
rgrover1 0:0b799af9d58e 60
rgrover1 0:0b799af9d58e 61 static void* normal_realloc(void* memory, size_t size, const char*, int)
rgrover1 0:0b799af9d58e 62 {
rgrover1 0:0b799af9d58e 63 return PlatformSpecificRealloc(memory, size);
rgrover1 0:0b799af9d58e 64 }
rgrover1 0:0b799af9d58e 65
rgrover1 0:0b799af9d58e 66 static void normal_free(void* buffer, const char*, int)
rgrover1 0:0b799af9d58e 67 {
rgrover1 0:0b799af9d58e 68 PlatformSpecificFree(buffer);
rgrover1 0:0b799af9d58e 69 }
rgrover1 0:0b799af9d58e 70
rgrover1 0:0b799af9d58e 71 #if CPPUTEST_USE_MEM_LEAK_DETECTION
rgrover1 0:0b799af9d58e 72 static void *(*malloc_fptr)(size_t size, const char* file, int line) = mem_leak_malloc;
rgrover1 0:0b799af9d58e 73 static void (*free_fptr)(void* mem, const char* file, int line) = mem_leak_free;
rgrover1 0:0b799af9d58e 74 static void*(*realloc_fptr)(void* memory, size_t size, const char* file, int line) = mem_leak_realloc;
rgrover1 0:0b799af9d58e 75 #else
rgrover1 0:0b799af9d58e 76 static void *(*malloc_fptr)(size_t size, const char* file, int line) = normal_malloc;
rgrover1 0:0b799af9d58e 77 static void (*free_fptr)(void* mem, const char* file, int line) = normal_free;
rgrover1 0:0b799af9d58e 78 static void*(*realloc_fptr)(void* memory, size_t size, const char* file, int line) = normal_realloc;
rgrover1 0:0b799af9d58e 79 #endif
rgrover1 0:0b799af9d58e 80
rgrover1 0:0b799af9d58e 81 void* cpputest_malloc_location_with_leak_detection(size_t size, const char* file, int line)
rgrover1 0:0b799af9d58e 82 {
rgrover1 0:0b799af9d58e 83 return malloc_fptr(size, file, line);
rgrover1 0:0b799af9d58e 84 }
rgrover1 0:0b799af9d58e 85
rgrover1 0:0b799af9d58e 86 void* cpputest_realloc_location_with_leak_detection(void* memory, size_t size, const char* file, int line)
rgrover1 0:0b799af9d58e 87 {
rgrover1 0:0b799af9d58e 88 return realloc_fptr(memory, size, file, line);
rgrover1 0:0b799af9d58e 89 }
rgrover1 0:0b799af9d58e 90
rgrover1 0:0b799af9d58e 91 void cpputest_free_location_with_leak_detection(void* buffer, const char* file, int line)
rgrover1 0:0b799af9d58e 92 {
rgrover1 0:0b799af9d58e 93 free_fptr(buffer, file, line);
rgrover1 0:0b799af9d58e 94 }
rgrover1 0:0b799af9d58e 95
rgrover1 0:0b799af9d58e 96 /********** C++ *************/
rgrover1 0:0b799af9d58e 97
rgrover1 0:0b799af9d58e 98 #if CPPUTEST_USE_MEM_LEAK_DETECTION
rgrover1 0:0b799af9d58e 99 #undef new
rgrover1 0:0b799af9d58e 100
rgrover1 0:0b799af9d58e 101 #if CPPUTEST_USE_STD_CPP_LIB
rgrover1 0:0b799af9d58e 102 #define UT_THROW_BAD_ALLOC_WHEN_NULL(memory) if (memory == NULL) throw std::bad_alloc();
rgrover1 0:0b799af9d58e 103 #else
rgrover1 0:0b799af9d58e 104 #define UT_THROW_BAD_ALLOC_WHEN_NULL(memory)
rgrover1 0:0b799af9d58e 105 #endif
rgrover1 0:0b799af9d58e 106
rgrover1 0:0b799af9d58e 107 static void* mem_leak_operator_new (size_t size) UT_THROW(std::bad_alloc)
rgrover1 0:0b799af9d58e 108 {
rgrover1 0:0b799af9d58e 109 void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size);
rgrover1 0:0b799af9d58e 110 UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
rgrover1 0:0b799af9d58e 111 return memory;
rgrover1 0:0b799af9d58e 112 }
rgrover1 0:0b799af9d58e 113
rgrover1 0:0b799af9d58e 114 static void* mem_leak_operator_new_nothrow (size_t size) UT_NOTHROW
rgrover1 0:0b799af9d58e 115 {
rgrover1 0:0b799af9d58e 116 return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size);
rgrover1 0:0b799af9d58e 117 }
rgrover1 0:0b799af9d58e 118
rgrover1 0:0b799af9d58e 119 static void* mem_leak_operator_new_debug (size_t size, const char* file, int line) UT_THROW(std::bad_alloc)
rgrover1 0:0b799af9d58e 120 {
rgrover1 0:0b799af9d58e 121 void *memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size, (char*) file, line);
rgrover1 0:0b799af9d58e 122 UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
rgrover1 0:0b799af9d58e 123 return memory;
rgrover1 0:0b799af9d58e 124 }
rgrover1 0:0b799af9d58e 125
rgrover1 0:0b799af9d58e 126 static void* mem_leak_operator_new_array (size_t size) UT_THROW(std::bad_alloc)
rgrover1 0:0b799af9d58e 127 {
rgrover1 0:0b799af9d58e 128 void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size);
rgrover1 0:0b799af9d58e 129 UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
rgrover1 0:0b799af9d58e 130 return memory;
rgrover1 0:0b799af9d58e 131 }
rgrover1 0:0b799af9d58e 132
rgrover1 0:0b799af9d58e 133 static void* mem_leak_operator_new_array_nothrow (size_t size) UT_NOTHROW
rgrover1 0:0b799af9d58e 134 {
rgrover1 0:0b799af9d58e 135 return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size);
rgrover1 0:0b799af9d58e 136 }
rgrover1 0:0b799af9d58e 137
rgrover1 0:0b799af9d58e 138 static void* mem_leak_operator_new_array_debug (size_t size, const char* file, int line) UT_THROW(std::bad_alloc)
rgrover1 0:0b799af9d58e 139 {
rgrover1 0:0b799af9d58e 140 void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size, (char*) file, line);
rgrover1 0:0b799af9d58e 141 UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
rgrover1 0:0b799af9d58e 142 return memory;
rgrover1 0:0b799af9d58e 143 }
rgrover1 0:0b799af9d58e 144
rgrover1 0:0b799af9d58e 145 static void mem_leak_operator_delete (void* mem) UT_NOTHROW
rgrover1 0:0b799af9d58e 146 {
rgrover1 0:0b799af9d58e 147 MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) mem);
rgrover1 0:0b799af9d58e 148 MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentNewAllocator(), (char*) mem);
rgrover1 0:0b799af9d58e 149 }
rgrover1 0:0b799af9d58e 150
rgrover1 0:0b799af9d58e 151 static void mem_leak_operator_delete_array (void* mem) UT_NOTHROW
rgrover1 0:0b799af9d58e 152 {
rgrover1 0:0b799af9d58e 153 MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) mem);
rgrover1 0:0b799af9d58e 154 MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentNewArrayAllocator(), (char*) mem);
rgrover1 0:0b799af9d58e 155 }
rgrover1 0:0b799af9d58e 156
rgrover1 0:0b799af9d58e 157 static void* normal_operator_new (size_t size) UT_THROW(std::bad_alloc)
rgrover1 0:0b799af9d58e 158 {
rgrover1 0:0b799af9d58e 159 void* memory = PlatformSpecificMalloc(size);
rgrover1 0:0b799af9d58e 160 UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
rgrover1 0:0b799af9d58e 161 return memory;
rgrover1 0:0b799af9d58e 162 }
rgrover1 0:0b799af9d58e 163
rgrover1 0:0b799af9d58e 164 static void* normal_operator_new_nothrow (size_t size) UT_NOTHROW
rgrover1 0:0b799af9d58e 165 {
rgrover1 0:0b799af9d58e 166 return PlatformSpecificMalloc(size);
rgrover1 0:0b799af9d58e 167 }
rgrover1 0:0b799af9d58e 168
rgrover1 0:0b799af9d58e 169 static void* normal_operator_new_debug (size_t size, const char* /*file*/, int /*line*/) UT_THROW(std::bad_alloc)
rgrover1 0:0b799af9d58e 170 {
rgrover1 0:0b799af9d58e 171 void* memory = PlatformSpecificMalloc(size);
rgrover1 0:0b799af9d58e 172 UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
rgrover1 0:0b799af9d58e 173 return memory;
rgrover1 0:0b799af9d58e 174 }
rgrover1 0:0b799af9d58e 175
rgrover1 0:0b799af9d58e 176 static void* normal_operator_new_array (size_t size) UT_THROW(std::bad_alloc)
rgrover1 0:0b799af9d58e 177 {
rgrover1 0:0b799af9d58e 178 void* memory = PlatformSpecificMalloc(size);
rgrover1 0:0b799af9d58e 179 UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
rgrover1 0:0b799af9d58e 180 return memory;
rgrover1 0:0b799af9d58e 181 }
rgrover1 0:0b799af9d58e 182
rgrover1 0:0b799af9d58e 183 static void* normal_operator_new_array_nothrow (size_t size) UT_NOTHROW
rgrover1 0:0b799af9d58e 184 {
rgrover1 0:0b799af9d58e 185 return PlatformSpecificMalloc(size);
rgrover1 0:0b799af9d58e 186 }
rgrover1 0:0b799af9d58e 187
rgrover1 0:0b799af9d58e 188 static void* normal_operator_new_array_debug (size_t size, const char* /*file*/, int /*line*/) UT_THROW(std::bad_alloc)
rgrover1 0:0b799af9d58e 189 {
rgrover1 0:0b799af9d58e 190 void* memory = PlatformSpecificMalloc(size);
rgrover1 0:0b799af9d58e 191 UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
rgrover1 0:0b799af9d58e 192 return memory;
rgrover1 0:0b799af9d58e 193 }
rgrover1 0:0b799af9d58e 194
rgrover1 0:0b799af9d58e 195 static void normal_operator_delete (void* mem) UT_NOTHROW
rgrover1 0:0b799af9d58e 196 {
rgrover1 0:0b799af9d58e 197 PlatformSpecificFree(mem);
rgrover1 0:0b799af9d58e 198 }
rgrover1 0:0b799af9d58e 199
rgrover1 0:0b799af9d58e 200 static void normal_operator_delete_array (void* mem) UT_NOTHROW
rgrover1 0:0b799af9d58e 201 {
rgrover1 0:0b799af9d58e 202 PlatformSpecificFree(mem);
rgrover1 0:0b799af9d58e 203 }
rgrover1 0:0b799af9d58e 204
rgrover1 0:0b799af9d58e 205 static void *(*operator_new_fptr)(size_t size) UT_THROW(std::bad_alloc) = mem_leak_operator_new;
rgrover1 0:0b799af9d58e 206 static void *(*operator_new_nothrow_fptr)(size_t size) UT_NOTHROW = mem_leak_operator_new_nothrow;
rgrover1 0:0b799af9d58e 207 static void *(*operator_new_debug_fptr)(size_t size, const char* file, int line) UT_THROW(std::bad_alloc) = mem_leak_operator_new_debug;
rgrover1 0:0b799af9d58e 208 static void *(*operator_new_array_fptr)(size_t size) UT_THROW(std::bad_alloc) = mem_leak_operator_new_array;
rgrover1 0:0b799af9d58e 209 static void *(*operator_new_array_nothrow_fptr)(size_t size) UT_NOTHROW = mem_leak_operator_new_array_nothrow;
rgrover1 0:0b799af9d58e 210 static void *(*operator_new_array_debug_fptr)(size_t size, const char* file, int line) UT_THROW(std::bad_alloc) = mem_leak_operator_new_array_debug;
rgrover1 0:0b799af9d58e 211 static void (*operator_delete_fptr)(void* mem) UT_NOTHROW = mem_leak_operator_delete;
rgrover1 0:0b799af9d58e 212 static void (*operator_delete_array_fptr)(void* mem) UT_NOTHROW = mem_leak_operator_delete_array;
rgrover1 0:0b799af9d58e 213
rgrover1 0:0b799af9d58e 214 void* operator new(size_t size) UT_THROW(std::bad_alloc)
rgrover1 0:0b799af9d58e 215 {
rgrover1 0:0b799af9d58e 216 return operator_new_fptr(size);
rgrover1 0:0b799af9d58e 217 }
rgrover1 0:0b799af9d58e 218
rgrover1 0:0b799af9d58e 219 void* operator new(size_t size, const char* file, int line) UT_THROW(std::bad_alloc)
rgrover1 0:0b799af9d58e 220 {
rgrover1 0:0b799af9d58e 221 return operator_new_debug_fptr(size, file, line);
rgrover1 0:0b799af9d58e 222 }
rgrover1 0:0b799af9d58e 223
rgrover1 0:0b799af9d58e 224 void operator delete(void* mem) UT_NOTHROW
rgrover1 0:0b799af9d58e 225 {
rgrover1 0:0b799af9d58e 226 operator_delete_fptr(mem);
rgrover1 0:0b799af9d58e 227 }
rgrover1 0:0b799af9d58e 228
rgrover1 0:0b799af9d58e 229 void operator delete(void* mem, const char*, int) UT_NOTHROW
rgrover1 0:0b799af9d58e 230 {
rgrover1 0:0b799af9d58e 231 operator_delete_fptr(mem);
rgrover1 0:0b799af9d58e 232 }
rgrover1 0:0b799af9d58e 233
rgrover1 0:0b799af9d58e 234 void* operator new[](size_t size) UT_THROW(std::bad_alloc)
rgrover1 0:0b799af9d58e 235 {
rgrover1 0:0b799af9d58e 236 return operator_new_array_fptr(size);
rgrover1 0:0b799af9d58e 237 }
rgrover1 0:0b799af9d58e 238
rgrover1 0:0b799af9d58e 239 void* operator new [](size_t size, const char* file, int line) UT_THROW(std::bad_alloc)
rgrover1 0:0b799af9d58e 240 {
rgrover1 0:0b799af9d58e 241 return operator_new_array_debug_fptr(size, file, line);
rgrover1 0:0b799af9d58e 242 }
rgrover1 0:0b799af9d58e 243
rgrover1 0:0b799af9d58e 244 void operator delete[](void* mem) UT_NOTHROW
rgrover1 0:0b799af9d58e 245 {
rgrover1 0:0b799af9d58e 246 operator_delete_array_fptr(mem);
rgrover1 0:0b799af9d58e 247 }
rgrover1 0:0b799af9d58e 248
rgrover1 0:0b799af9d58e 249 void operator delete[](void* mem, const char*, int) UT_NOTHROW
rgrover1 0:0b799af9d58e 250 {
rgrover1 0:0b799af9d58e 251 operator_delete_array_fptr(mem);
rgrover1 0:0b799af9d58e 252 }
rgrover1 0:0b799af9d58e 253
rgrover1 0:0b799af9d58e 254
rgrover1 0:0b799af9d58e 255 #if CPPUTEST_USE_STD_CPP_LIB
rgrover1 0:0b799af9d58e 256
rgrover1 0:0b799af9d58e 257 void* operator new(size_t size, const std::nothrow_t&) UT_NOTHROW
rgrover1 0:0b799af9d58e 258 {
rgrover1 0:0b799af9d58e 259 return operator_new_nothrow_fptr(size);
rgrover1 0:0b799af9d58e 260 }
rgrover1 0:0b799af9d58e 261
rgrover1 0:0b799af9d58e 262 void* operator new[](size_t size, const std::nothrow_t&) UT_NOTHROW
rgrover1 0:0b799af9d58e 263 {
rgrover1 0:0b799af9d58e 264 return operator_new_array_nothrow_fptr(size);
rgrover1 0:0b799af9d58e 265 }
rgrover1 0:0b799af9d58e 266
rgrover1 0:0b799af9d58e 267 #else
rgrover1 0:0b799af9d58e 268
rgrover1 0:0b799af9d58e 269 /* Have a similar method. This avoid unused operator_new_nothrow_fptr warning */
rgrover1 0:0b799af9d58e 270
rgrover1 0:0b799af9d58e 271 extern void* operator_new_nothrow(size_t size) UT_NOTHROW;
rgrover1 0:0b799af9d58e 272 extern void* operator_new_array_nothrow(size_t size) UT_NOTHROW;
rgrover1 0:0b799af9d58e 273
rgrover1 0:0b799af9d58e 274 void* operator_new_nothrow(size_t size) UT_NOTHROW
rgrover1 0:0b799af9d58e 275 {
rgrover1 0:0b799af9d58e 276 return operator_new_nothrow_fptr(size);
rgrover1 0:0b799af9d58e 277 }
rgrover1 0:0b799af9d58e 278
rgrover1 0:0b799af9d58e 279 void* operator_new_array_nothrow(size_t size) UT_NOTHROW
rgrover1 0:0b799af9d58e 280 {
rgrover1 0:0b799af9d58e 281 return operator_new_array_nothrow_fptr(size);
rgrover1 0:0b799af9d58e 282 }
rgrover1 0:0b799af9d58e 283
rgrover1 0:0b799af9d58e 284 #endif
rgrover1 0:0b799af9d58e 285 #endif
rgrover1 0:0b799af9d58e 286
rgrover1 0:0b799af9d58e 287 void MemoryLeakWarningPlugin::turnOffNewDeleteOverloads()
rgrover1 0:0b799af9d58e 288 {
rgrover1 0:0b799af9d58e 289 #if CPPUTEST_USE_MEM_LEAK_DETECTION
rgrover1 0:0b799af9d58e 290 operator_new_fptr = normal_operator_new;
rgrover1 0:0b799af9d58e 291 operator_new_nothrow_fptr = normal_operator_new_nothrow;
rgrover1 0:0b799af9d58e 292 operator_new_debug_fptr = normal_operator_new_debug;
rgrover1 0:0b799af9d58e 293 operator_new_array_fptr = normal_operator_new_array;
rgrover1 0:0b799af9d58e 294 operator_new_array_nothrow_fptr = normal_operator_new_array_nothrow;
rgrover1 0:0b799af9d58e 295 operator_new_array_debug_fptr = normal_operator_new_array_debug;
rgrover1 0:0b799af9d58e 296 operator_delete_fptr = normal_operator_delete;
rgrover1 0:0b799af9d58e 297 operator_delete_array_fptr = normal_operator_delete_array;
rgrover1 0:0b799af9d58e 298 malloc_fptr = normal_malloc;
rgrover1 0:0b799af9d58e 299 realloc_fptr = normal_realloc;
rgrover1 0:0b799af9d58e 300 free_fptr = normal_free;
rgrover1 0:0b799af9d58e 301
rgrover1 0:0b799af9d58e 302 #endif
rgrover1 0:0b799af9d58e 303 }
rgrover1 0:0b799af9d58e 304
rgrover1 0:0b799af9d58e 305 void MemoryLeakWarningPlugin::turnOnNewDeleteOverloads()
rgrover1 0:0b799af9d58e 306 {
rgrover1 0:0b799af9d58e 307 #if CPPUTEST_USE_MEM_LEAK_DETECTION
rgrover1 0:0b799af9d58e 308 operator_new_fptr = mem_leak_operator_new;
rgrover1 0:0b799af9d58e 309 operator_new_nothrow_fptr = mem_leak_operator_new_nothrow;
rgrover1 0:0b799af9d58e 310 operator_new_debug_fptr = mem_leak_operator_new_debug;
rgrover1 0:0b799af9d58e 311 operator_new_array_fptr = mem_leak_operator_new_array;
rgrover1 0:0b799af9d58e 312 operator_new_array_nothrow_fptr = mem_leak_operator_new_array_nothrow;
rgrover1 0:0b799af9d58e 313 operator_new_array_debug_fptr = mem_leak_operator_new_array_debug;
rgrover1 0:0b799af9d58e 314 operator_delete_fptr = mem_leak_operator_delete;
rgrover1 0:0b799af9d58e 315 operator_delete_array_fptr = mem_leak_operator_delete_array;
rgrover1 0:0b799af9d58e 316 malloc_fptr = mem_leak_malloc;
rgrover1 0:0b799af9d58e 317 realloc_fptr = mem_leak_realloc;
rgrover1 0:0b799af9d58e 318 free_fptr = mem_leak_free;
rgrover1 0:0b799af9d58e 319 #endif
rgrover1 0:0b799af9d58e 320 }
rgrover1 0:0b799af9d58e 321
rgrover1 0:0b799af9d58e 322 void crash_on_allocation_number(unsigned alloc_number)
rgrover1 0:0b799af9d58e 323 {
rgrover1 0:0b799af9d58e 324 static CrashOnAllocationAllocator crashAllocator;
rgrover1 0:0b799af9d58e 325 crashAllocator.setNumberToCrashOn(alloc_number);
rgrover1 0:0b799af9d58e 326 setCurrentMallocAllocator(&crashAllocator);
rgrover1 0:0b799af9d58e 327 setCurrentNewAllocator(&crashAllocator);
rgrover1 0:0b799af9d58e 328 setCurrentNewArrayAllocator(&crashAllocator);
rgrover1 0:0b799af9d58e 329 }
rgrover1 0:0b799af9d58e 330
rgrover1 0:0b799af9d58e 331 class MemoryLeakWarningReporter: public MemoryLeakFailure
rgrover1 0:0b799af9d58e 332 {
rgrover1 0:0b799af9d58e 333 public:
rgrover1 0:0b799af9d58e 334 virtual ~MemoryLeakWarningReporter()
rgrover1 0:0b799af9d58e 335 {
rgrover1 0:0b799af9d58e 336 }
rgrover1 0:0b799af9d58e 337
rgrover1 0:0b799af9d58e 338 virtual void fail(char* fail_string)
rgrover1 0:0b799af9d58e 339 {
rgrover1 0:0b799af9d58e 340 UtestShell* currentTest = UtestShell::getCurrent();
rgrover1 0:0b799af9d58e 341 currentTest->failWith(FailFailure(currentTest, currentTest->getName().asCharString(), currentTest->getLineNumber(), fail_string), TestTerminatorWithoutExceptions());
rgrover1 0:0b799af9d58e 342 }
rgrover1 0:0b799af9d58e 343 };
rgrover1 0:0b799af9d58e 344
rgrover1 0:0b799af9d58e 345 static MemoryLeakFailure* globalReporter = 0;
rgrover1 0:0b799af9d58e 346 static MemoryLeakDetector* globalDetector = 0;
rgrover1 0:0b799af9d58e 347
rgrover1 0:0b799af9d58e 348 MemoryLeakDetector* MemoryLeakWarningPlugin::getGlobalDetector()
rgrover1 0:0b799af9d58e 349 {
rgrover1 0:0b799af9d58e 350 if (globalDetector == 0) {
rgrover1 0:0b799af9d58e 351 turnOffNewDeleteOverloads();
rgrover1 0:0b799af9d58e 352
rgrover1 0:0b799af9d58e 353 globalReporter = new MemoryLeakWarningReporter;
rgrover1 0:0b799af9d58e 354 globalDetector = new MemoryLeakDetector(globalReporter);
rgrover1 0:0b799af9d58e 355
rgrover1 0:0b799af9d58e 356 turnOnNewDeleteOverloads();
rgrover1 0:0b799af9d58e 357 }
rgrover1 0:0b799af9d58e 358 return globalDetector;
rgrover1 0:0b799af9d58e 359 }
rgrover1 0:0b799af9d58e 360
rgrover1 0:0b799af9d58e 361 MemoryLeakFailure* MemoryLeakWarningPlugin::getGlobalFailureReporter()
rgrover1 0:0b799af9d58e 362 {
rgrover1 0:0b799af9d58e 363 return globalReporter;
rgrover1 0:0b799af9d58e 364 }
rgrover1 0:0b799af9d58e 365
rgrover1 0:0b799af9d58e 366 void MemoryLeakWarningPlugin::destroyGlobalDetectorAndTurnOffMemoryLeakDetectionInDestructor(bool des)
rgrover1 0:0b799af9d58e 367 {
rgrover1 0:0b799af9d58e 368 destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_ = des;
rgrover1 0:0b799af9d58e 369 }
rgrover1 0:0b799af9d58e 370
rgrover1 0:0b799af9d58e 371 void MemoryLeakWarningPlugin::setGlobalDetector(MemoryLeakDetector* detector, MemoryLeakFailure* reporter)
rgrover1 0:0b799af9d58e 372 {
rgrover1 0:0b799af9d58e 373 globalDetector = detector;
rgrover1 0:0b799af9d58e 374 globalReporter = reporter;
rgrover1 0:0b799af9d58e 375 }
rgrover1 0:0b799af9d58e 376
rgrover1 0:0b799af9d58e 377 void MemoryLeakWarningPlugin::destroyGlobalDetector()
rgrover1 0:0b799af9d58e 378 {
rgrover1 0:0b799af9d58e 379 turnOffNewDeleteOverloads();
rgrover1 0:0b799af9d58e 380 delete globalDetector;
rgrover1 0:0b799af9d58e 381 delete globalReporter;
rgrover1 0:0b799af9d58e 382 globalDetector = NULL;
rgrover1 0:0b799af9d58e 383 }
rgrover1 0:0b799af9d58e 384
rgrover1 0:0b799af9d58e 385
rgrover1 0:0b799af9d58e 386 MemoryLeakWarningPlugin* MemoryLeakWarningPlugin::firstPlugin_ = 0;
rgrover1 0:0b799af9d58e 387
rgrover1 0:0b799af9d58e 388 MemoryLeakWarningPlugin* MemoryLeakWarningPlugin::getFirstPlugin()
rgrover1 0:0b799af9d58e 389 {
rgrover1 0:0b799af9d58e 390 return firstPlugin_;
rgrover1 0:0b799af9d58e 391 }
rgrover1 0:0b799af9d58e 392
rgrover1 0:0b799af9d58e 393 MemoryLeakDetector* MemoryLeakWarningPlugin::getMemoryLeakDetector()
rgrover1 0:0b799af9d58e 394 {
rgrover1 0:0b799af9d58e 395 return memLeakDetector_;
rgrover1 0:0b799af9d58e 396 }
rgrover1 0:0b799af9d58e 397
rgrover1 0:0b799af9d58e 398 void MemoryLeakWarningPlugin::ignoreAllLeaksInTest()
rgrover1 0:0b799af9d58e 399 {
rgrover1 0:0b799af9d58e 400 ignoreAllWarnings_ = true;
rgrover1 0:0b799af9d58e 401 }
rgrover1 0:0b799af9d58e 402
rgrover1 0:0b799af9d58e 403 void MemoryLeakWarningPlugin::expectLeaksInTest(int n)
rgrover1 0:0b799af9d58e 404 {
rgrover1 0:0b799af9d58e 405 expectedLeaks_ = n;
rgrover1 0:0b799af9d58e 406 }
rgrover1 0:0b799af9d58e 407
rgrover1 0:0b799af9d58e 408 MemoryLeakWarningPlugin::MemoryLeakWarningPlugin(const SimpleString& name, MemoryLeakDetector* localDetector) :
rgrover1 0:0b799af9d58e 409 TestPlugin(name), ignoreAllWarnings_(false), destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_(false), expectedLeaks_(0)
rgrover1 0:0b799af9d58e 410 {
rgrover1 0:0b799af9d58e 411 if (firstPlugin_ == 0) firstPlugin_ = this;
rgrover1 0:0b799af9d58e 412
rgrover1 0:0b799af9d58e 413 if (localDetector) memLeakDetector_ = localDetector;
rgrover1 0:0b799af9d58e 414 else memLeakDetector_ = getGlobalDetector();
rgrover1 0:0b799af9d58e 415
rgrover1 0:0b799af9d58e 416 memLeakDetector_->enable();
rgrover1 0:0b799af9d58e 417 }
rgrover1 0:0b799af9d58e 418
rgrover1 0:0b799af9d58e 419 MemoryLeakWarningPlugin::~MemoryLeakWarningPlugin()
rgrover1 0:0b799af9d58e 420 {
rgrover1 0:0b799af9d58e 421 if (destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_) {
rgrover1 0:0b799af9d58e 422 MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
rgrover1 0:0b799af9d58e 423 MemoryLeakWarningPlugin::destroyGlobalDetector();
rgrover1 0:0b799af9d58e 424 }
rgrover1 0:0b799af9d58e 425 }
rgrover1 0:0b799af9d58e 426
rgrover1 0:0b799af9d58e 427 void MemoryLeakWarningPlugin::preTestAction(UtestShell& /*test*/, TestResult& result)
rgrover1 0:0b799af9d58e 428 {
rgrover1 0:0b799af9d58e 429 memLeakDetector_->startChecking();
rgrover1 0:0b799af9d58e 430 failureCount_ = result.getFailureCount();
rgrover1 0:0b799af9d58e 431 }
rgrover1 0:0b799af9d58e 432
rgrover1 0:0b799af9d58e 433 void MemoryLeakWarningPlugin::postTestAction(UtestShell& test, TestResult& result)
rgrover1 0:0b799af9d58e 434 {
rgrover1 0:0b799af9d58e 435 memLeakDetector_->stopChecking();
rgrover1 0:0b799af9d58e 436 int leaks = memLeakDetector_->totalMemoryLeaks(mem_leak_period_checking);
rgrover1 0:0b799af9d58e 437
rgrover1 0:0b799af9d58e 438 if (!ignoreAllWarnings_ && expectedLeaks_ != leaks && failureCount_ == result.getFailureCount()) {
rgrover1 0:0b799af9d58e 439 TestFailure f(&test, memLeakDetector_->report(mem_leak_period_checking));
rgrover1 0:0b799af9d58e 440 result.addFailure(f);
rgrover1 0:0b799af9d58e 441 }
rgrover1 0:0b799af9d58e 442 memLeakDetector_->markCheckingPeriodLeaksAsNonCheckingPeriod();
rgrover1 0:0b799af9d58e 443 ignoreAllWarnings_ = false;
rgrover1 0:0b799af9d58e 444 expectedLeaks_ = 0;
rgrover1 0:0b799af9d58e 445 }
rgrover1 0:0b799af9d58e 446
rgrover1 0:0b799af9d58e 447 const char* MemoryLeakWarningPlugin::FinalReport(int toBeDeletedLeaks)
rgrover1 0:0b799af9d58e 448 {
rgrover1 0:0b799af9d58e 449 int leaks = memLeakDetector_->totalMemoryLeaks(mem_leak_period_enabled);
rgrover1 0:0b799af9d58e 450 if (leaks != toBeDeletedLeaks) return memLeakDetector_->report(mem_leak_period_enabled);
rgrover1 0:0b799af9d58e 451 return "";
rgrover1 0:0b799af9d58e 452 }
rgrover1 0:0b799af9d58e 453
rgrover1 0:0b799af9d58e 454