test/util_allocator.cpp

Sat, 16 Apr 2022 20:17:01 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 16 Apr 2022 20:17:01 +0200
changeset 518
74d0372f5c6f
parent 500
test/util_allocator.c@eb9e7bd40a8e
child 571
f83583a0bbac
permissions
-rw-r--r--

improve testing allocator + add tests for it

universe@422 1 /*
universe@422 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@422 3 *
universe@422 4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
universe@422 5 *
universe@422 6 * Redistribution and use in source and binary forms, with or without
universe@422 7 * modification, are permitted provided that the following conditions are met:
universe@422 8 *
universe@422 9 * 1. Redistributions of source code must retain the above copyright
universe@422 10 * notice, this list of conditions and the following disclaimer.
universe@422 11 *
universe@422 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@422 13 * notice, this list of conditions and the following disclaimer in the
universe@422 14 * documentation and/or other materials provided with the distribution.
universe@422 15 *
universe@422 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@422 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@422 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@422 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@422 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@422 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@422 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@422 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@422 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@422 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@422 26 * POSSIBILITY OF SUCH DAMAGE.
universe@422 27 */
universe@422 28
universe@422 29 #include "util_allocator.h"
universe@422 30
universe@422 31 void *cx_malloc_testing(void *d, size_t n) {
universe@518 32 auto data = reinterpret_cast<CxTestingAllocator *>(d);
universe@422 33 void *ptr = malloc(n);
universe@422 34 data->alloc_total++;
universe@518 35 if (ptr == nullptr) {
universe@422 36 data->alloc_failed++;
universe@422 37 } else {
universe@518 38 data->tracked.insert(ptr);
universe@422 39 }
universe@422 40 return ptr;
universe@422 41 }
universe@422 42
universe@422 43 void *cx_realloc_testing(void *d, void *mem, size_t n) {
universe@518 44 auto data = reinterpret_cast<CxTestingAllocator *>(d);
universe@422 45 void *ptr = realloc(mem, n);
universe@422 46 if (ptr == mem) {
universe@422 47 return ptr;
universe@422 48 } else {
universe@422 49 data->alloc_total++;
universe@518 50 if (ptr == nullptr) {
universe@422 51 data->alloc_failed++;
universe@422 52 } else {
universe@422 53 data->free_total++;
universe@518 54 if (data->tracked.erase(mem) == 0) {
universe@422 55 data->free_failed++;
universe@422 56 }
universe@518 57 data->tracked.insert(ptr);
universe@422 58 }
universe@422 59 return ptr;
universe@422 60 }
universe@422 61 }
universe@422 62
universe@422 63 void *cx_calloc_testing(void *d, size_t nelem, size_t n) {
universe@518 64 auto data = reinterpret_cast<CxTestingAllocator *>(d);
universe@422 65 void *ptr = calloc(nelem, n);
universe@422 66 data->alloc_total++;
universe@518 67 if (ptr == nullptr) {
universe@422 68 data->alloc_failed++;
universe@422 69 } else {
universe@518 70 data->tracked.insert(ptr);
universe@422 71 }
universe@422 72 return ptr;
universe@422 73 }
universe@422 74
universe@422 75 void cx_free_testing(void *d, void *mem) {
universe@518 76 auto data = reinterpret_cast<CxTestingAllocator *>(d);
universe@422 77 data->free_total++;
universe@518 78 if (data->tracked.erase(mem) == 0) {
universe@422 79 data->free_failed++;
universe@422 80 // do not even attempt to free mem, because it is likely to segfault
universe@422 81 } else {
universe@422 82 free(mem);
universe@422 83 }
universe@422 84 }
universe@422 85
universe@422 86 cx_allocator_class cx_testing_allocator_class = {
universe@422 87 cx_malloc_testing,
universe@422 88 cx_realloc_testing,
universe@422 89 cx_calloc_testing,
universe@422 90 cx_free_testing
universe@422 91 };
universe@422 92
universe@518 93 CxTestingAllocator::CxTestingAllocator() : CxAllocator() {
universe@518 94 cl = &cx_testing_allocator_class;
universe@518 95 data = this;
universe@422 96 }
universe@422 97
universe@518 98 bool CxTestingAllocator::verify() const {
universe@518 99 return tracked.empty() && alloc_failed == 0 && free_failed == 0 && alloc_total == free_total;
universe@422 100 }
universe@518 101
universe@518 102 // SELF-TEST
universe@518 103
universe@518 104 #include <gtest/gtest.h>
universe@518 105
universe@518 106 TEST(TestingAllocator, ExpectFree) {
universe@518 107 CxTestingAllocator allocator;
universe@518 108
universe@518 109 ASSERT_TRUE(allocator.verify());
universe@518 110 auto ptr = cxMalloc(&allocator, 16);
universe@518 111 ASSERT_NE(ptr, nullptr);
universe@518 112 EXPECT_FALSE(allocator.verify());
universe@518 113
universe@518 114 cxFree(&allocator, ptr);
universe@518 115 EXPECT_TRUE(allocator.verify());
universe@518 116 }
universe@518 117
universe@518 118 TEST(TestingAllocator, DetectDoubleFree) {
universe@518 119 CxTestingAllocator allocator;
universe@518 120
universe@518 121 ASSERT_TRUE(allocator.verify());
universe@518 122 auto ptr = cxMalloc(&allocator, 16);
universe@518 123 ASSERT_NE(ptr, nullptr);
universe@518 124
universe@518 125 cxFree(&allocator, ptr);
universe@518 126 EXPECT_TRUE(allocator.verify());
universe@518 127 ASSERT_NO_FATAL_FAILURE(cxFree(&allocator, ptr));
universe@518 128 EXPECT_FALSE(allocator.verify());
universe@518 129 }
universe@518 130
universe@518 131 TEST(TestingAllocator, FreeUntracked) {
universe@518 132 CxTestingAllocator allocator;
universe@518 133
universe@518 134 auto ptr = malloc(16);
universe@518 135 ASSERT_TRUE(allocator.verify());
universe@518 136 ASSERT_NO_FATAL_FAILURE(cxFree(&allocator, ptr));
universe@518 137 EXPECT_FALSE(allocator.verify());
universe@518 138 ASSERT_NO_FATAL_FAILURE(free(ptr));
universe@518 139 }
universe@518 140
universe@518 141 TEST(TestingAllocator, FullLifecycleWithRealloc) {
universe@518 142 CxTestingAllocator allocator;
universe@518 143 ASSERT_TRUE(allocator.verify());
universe@518 144 auto ptr = cxMalloc(&allocator, 16);
universe@518 145 ASSERT_NE(ptr, nullptr);
universe@518 146 EXPECT_EQ(allocator.tracked.size(), 1);
universe@518 147 ptr = cxRealloc(&allocator, ptr, 256);
universe@518 148 ASSERT_NE(ptr, nullptr);
universe@518 149 EXPECT_EQ(allocator.tracked.size(), 1);
universe@518 150 cxFree(&allocator, ptr);
universe@518 151 EXPECT_TRUE(allocator.verify());
universe@518 152 }
universe@518 153
universe@518 154 TEST(TestingAllocator, CallocInitializes) {
universe@518 155 CxTestingAllocator allocator;
universe@518 156 const char* zeros[16] = {0};
universe@518 157 auto ptr = cxCalloc(&allocator, 16, 1);
universe@518 158 EXPECT_EQ(memcmp(ptr, zeros, 16), 0);
universe@518 159 cxFree(&allocator, ptr);
universe@518 160 EXPECT_TRUE(allocator.verify());
universe@518 161 }

mercurial