Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 205 additions & 0 deletions vm9252-TestAllocator.c++
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// -------------------------------------
// projects/allocator/TestAllocator1.c++
// Copyright (C) 2015
// Glenn P. Downing
// -------------------------------------

#include <algorithm> // count
#include <memory> // allocator

#include "gtest/gtest.h"

#include "Allocator.h"

template <typename A>
struct TestAllAllocators : testing::Test {
typedef A allocator_type;
typedef typename A::value_type value_type;
typedef typename A::size_type size_type;
typedef typename A::pointer pointer;
};

typedef testing::Types<std::allocator<int>, std::allocator<double>, my_allocator<int, 100>, my_allocator<double, 100>> allocatorTypes;
TYPED_TEST_CASE(TestAllAllocators, allocatorTypes);

TYPED_TEST(TestAllAllocators, constuct_1) {
typedef typename TestFixture::allocator_type allocator_type;
typedef typename TestFixture::value_type value_type;
typedef typename TestFixture::size_type size_type;
typedef typename TestFixture::pointer pointer;
allocator_type x;
const size_type size = 1;
const value_type value = 2;
const pointer p = x.allocate(size);
if (p) {
x.construct(p, value);
EXPECT_EQ(value, *p);
x.destroy(p);
x.deallocate(p, size);
}
}

TYPED_TEST(TestAllAllocators, construct_many) {
typedef typename TestFixture::allocator_type allocator_type;
typedef typename TestFixture::value_type value_type;
typedef typename TestFixture::size_type size_type;
typedef typename TestFixture::pointer pointer;
allocator_type x;
const size_type size = 10;
const value_type value = 2;
const pointer begin = x.allocate(size);
if (begin) {
pointer end = begin + size;
pointer p = begin;
while (p != end) {
x.construct(p, value);
++p;
}
EXPECT_EQ(size, std::count(begin, end, value));
while (begin != end) {
--end;
x.destroy(end);
}
x.deallocate(begin, size);
}
}

// --------------
// TestAllocator
// --------------

template <typename T>
struct TestTypes : testing::Test {
typedef T type;
static constexpr std::size_t size = sizeof(T);
};

struct vec3 { float ar[3]; };
typedef testing::Types<char, int, double, vec3> dataTypes;
TYPED_TEST_CASE(TestTypes, dataTypes);

TYPED_TEST(TestTypes, allocator_size) {
using type = typename TestFixture::type;
#define test(size, expectError) {\
bool errorCaught = false;\
try { my_allocator<type, size> x; }\
catch (const std::bad_alloc& e) { errorCaught = true; }\
EXPECT_EQ(expectError, errorCaught);\
}
test(0, true);
test(TestFixture::size, true);
test(TestFixture::size + 7, true);
test(TestFixture::size + 8, false);
test(TestFixture::size + 9, false);
#undef test
}

TYPED_TEST(TestTypes, alloc_1) {
using type = typename TestFixture::type;
my_allocator<type, TestFixture::size + 8> x;

type* const p = x.allocate(1);
EXPECT_TRUE(p);
x.deallocate(p, 1);
}

TYPED_TEST(TestTypes, alloc_2) {
using type = typename TestFixture::type;
my_allocator<type, (TestFixture::size + 8) * 2> x;

type* const p1 = x.allocate(1);
type* const p2 = x.allocate(1);
EXPECT_TRUE(p1);
EXPECT_TRUE(p2);
}

TYPED_TEST(TestTypes, alloc_2_contiguous) {
using type = typename TestFixture::type;
my_allocator<type, TestFixture::size * 2 + 8> x;

type* const p = x.allocate(2);
EXPECT_TRUE(p);
}

TYPED_TEST(TestTypes, alloc_dealloc_alloc) {
using type = typename TestFixture::type;
my_allocator<type, TestFixture::size * 2 + 8> x;

type* const p = x.allocate(2);
x.deallocate(p, 1);
EXPECT_TRUE(p);
}

TYPED_TEST(TestTypes, alloc_fail) {
using type = typename TestFixture::type;
my_allocator<type, TestFixture::size + 8> x;

bool caught = false;
try { type* const p = x.allocate(2); }
catch (std::bad_alloc& x) { caught = true; }
EXPECT_TRUE(caught);
}

TYPED_TEST(TestTypes, dealloc_coalesce) {
using type = typename TestFixture::type;
my_allocator<type, (TestFixture::size + 8) * 5> x;

type* const p[5] = { x.allocate(1), x.allocate(1), x.allocate(1), x.allocate(1), x.allocate(1) };
for (const auto& it : p) {
EXPECT_TRUE(it);
x.deallocate(it, 1);
}
type* const p2 = x.allocate(5);
EXPECT_TRUE(p2);
x.deallocate(p2, 1);
}

TYPED_TEST(TestTypes, dealloc_coalesce_unordered) {
using type = typename TestFixture::type;
my_allocator<type, (TestFixture::size + 8) * 5> x;

type* const p[5] = { x.allocate(1), x.allocate(1), x.allocate(1), x.allocate(1), x.allocate(1) };
for (const auto& it : {2, 4, 1, 0, 3}) {
EXPECT_TRUE(p[it]);
x.deallocate(p[it], 1);
}
type* const p2 = x.allocate(5);
EXPECT_TRUE(p2);
x.deallocate(p2, 5);
}

TYPED_TEST(TestTypes, dealloc_null) {
using type = typename TestFixture::type;
my_allocator<type, (TestFixture::size + 8) * 5> x;

bool errorCaught = false;
try { x.deallocate(nullptr, 1); }
catch (const std::invalid_argument& e) { errorCaught = true; }
EXPECT_TRUE(errorCaught);
}

TYPED_TEST(TestTypes, dealloc_freed) {
using type = typename TestFixture::type;
my_allocator<type, (TestFixture::size + 8) * 5> x;
type* const p = x.allocate(1);
x.deallocate(p, 1);

bool errorCaught = false;
try { x.deallocate(p, 1); }
catch (const std::invalid_argument& e) { errorCaught = true; }
EXPECT_TRUE(errorCaught);
}

// --------------
// Test special cases
// --------------

TEST(TestAllocatorIndex, const_index) {
const my_allocator<int, 100> x;
EXPECT_EQ(x[0], 92);
}

TEST(TestAllocatorIndex, index) {
my_allocator<int, 100> x;
EXPECT_EQ(x[0], 92);
}
165 changes: 165 additions & 0 deletions vm9252-TestAllocator.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
==4041== Memcheck, a memory error detector
==4041== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4041== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==4041== Command: ./TestAllocator
==4041==
Running main() from gtest_main.cc
[==========] Running 50 tests from 9 test cases.
[----------] Global test environment set-up.
[----------] 2 tests from TestAllAllocators/0, where TypeParam = std::allocator<int>
[ RUN ] TestAllAllocators/0.constuct_1
[ OK ] TestAllAllocators/0.constuct_1 (13 ms)
[ RUN ] TestAllAllocators/0.construct_many
[ OK ] TestAllAllocators/0.construct_many (5 ms)
[----------] 2 tests from TestAllAllocators/0 (29 ms total)

[----------] 2 tests from TestAllAllocators/1, where TypeParam = std::allocator<double>
[ RUN ] TestAllAllocators/1.constuct_1
[ OK ] TestAllAllocators/1.constuct_1 (5 ms)
[ RUN ] TestAllAllocators/1.construct_many
[ OK ] TestAllAllocators/1.construct_many (4 ms)
[----------] 2 tests from TestAllAllocators/1 (9 ms total)

[----------] 2 tests from TestAllAllocators/2, where TypeParam = my_allocator<int, 100ul>
[ RUN ] TestAllAllocators/2.constuct_1
[ OK ] TestAllAllocators/2.constuct_1 (9 ms)
[ RUN ] TestAllAllocators/2.construct_many
[ OK ] TestAllAllocators/2.construct_many (3 ms)
[----------] 2 tests from TestAllAllocators/2 (12 ms total)

[----------] 2 tests from TestAllAllocators/3, where TypeParam = my_allocator<double, 100ul>
[ RUN ] TestAllAllocators/3.constuct_1
[ OK ] TestAllAllocators/3.constuct_1 (9 ms)
[ RUN ] TestAllAllocators/3.construct_many
[ OK ] TestAllAllocators/3.construct_many (4 ms)
[----------] 2 tests from TestAllAllocators/3 (13 ms total)

[----------] 10 tests from TestTypes/0, where TypeParam = char
[ RUN ] TestTypes/0.allocator_size
[ OK ] TestTypes/0.allocator_size (40 ms)
[ RUN ] TestTypes/0.alloc_1
[ OK ] TestTypes/0.alloc_1 (5 ms)
[ RUN ] TestTypes/0.alloc_2
[ OK ] TestTypes/0.alloc_2 (7 ms)
[ RUN ] TestTypes/0.alloc_2_contiguous
[ OK ] TestTypes/0.alloc_2_contiguous (3 ms)
[ RUN ] TestTypes/0.alloc_dealloc_alloc
[ OK ] TestTypes/0.alloc_dealloc_alloc (3 ms)
[ RUN ] TestTypes/0.alloc_fail
[ OK ] TestTypes/0.alloc_fail (3 ms)
[ RUN ] TestTypes/0.dealloc_coalesce
[ OK ] TestTypes/0.dealloc_coalesce (10 ms)
[ RUN ] TestTypes/0.dealloc_coalesce_unordered
[ OK ] TestTypes/0.dealloc_coalesce_unordered (5 ms)
[ RUN ] TestTypes/0.dealloc_null
[ OK ] TestTypes/0.dealloc_null (5 ms)
[ RUN ] TestTypes/0.dealloc_freed
[ OK ] TestTypes/0.dealloc_freed (2 ms)
[----------] 10 tests from TestTypes/0 (85 ms total)

[----------] 10 tests from TestTypes/1, where TypeParam = int
[ RUN ] TestTypes/1.allocator_size
[ OK ] TestTypes/1.allocator_size (9 ms)
[ RUN ] TestTypes/1.alloc_1
[ OK ] TestTypes/1.alloc_1 (5 ms)
[ RUN ] TestTypes/1.alloc_2
[ OK ] TestTypes/1.alloc_2 (7 ms)
[ RUN ] TestTypes/1.alloc_2_contiguous
[ OK ] TestTypes/1.alloc_2_contiguous (5 ms)
[ RUN ] TestTypes/1.alloc_dealloc_alloc
[ OK ] TestTypes/1.alloc_dealloc_alloc (3 ms)
[ RUN ] TestTypes/1.alloc_fail
[ OK ] TestTypes/1.alloc_fail (3 ms)
[ RUN ] TestTypes/1.dealloc_coalesce
[ OK ] TestTypes/1.dealloc_coalesce (10 ms)
[ RUN ] TestTypes/1.dealloc_coalesce_unordered
[ OK ] TestTypes/1.dealloc_coalesce_unordered (4 ms)
[ RUN ] TestTypes/1.dealloc_null
[ OK ] TestTypes/1.dealloc_null (2 ms)
[ RUN ] TestTypes/1.dealloc_freed
[ OK ] TestTypes/1.dealloc_freed (3 ms)
[----------] 10 tests from TestTypes/1 (52 ms total)

[----------] 10 tests from TestTypes/2, where TypeParam = double
[ RUN ] TestTypes/2.allocator_size
[ OK ] TestTypes/2.allocator_size (10 ms)
[ RUN ] TestTypes/2.alloc_1
[ OK ] TestTypes/2.alloc_1 (4 ms)
[ RUN ] TestTypes/2.alloc_2
[ OK ] TestTypes/2.alloc_2 (7 ms)
[ RUN ] TestTypes/2.alloc_2_contiguous
[ OK ] TestTypes/2.alloc_2_contiguous (5 ms)
[ RUN ] TestTypes/2.alloc_dealloc_alloc
[ OK ] TestTypes/2.alloc_dealloc_alloc (4 ms)
[ RUN ] TestTypes/2.alloc_fail
[ OK ] TestTypes/2.alloc_fail (3 ms)
[ RUN ] TestTypes/2.dealloc_coalesce
[ OK ] TestTypes/2.dealloc_coalesce (10 ms)
[ RUN ] TestTypes/2.dealloc_coalesce_unordered
[ OK ] TestTypes/2.dealloc_coalesce_unordered (5 ms)
[ RUN ] TestTypes/2.dealloc_null
[ OK ] TestTypes/2.dealloc_null (2 ms)
[ RUN ] TestTypes/2.dealloc_freed
[ OK ] TestTypes/2.dealloc_freed (3 ms)
[----------] 10 tests from TestTypes/2 (53 ms total)

[----------] 10 tests from TestTypes/3, where TypeParam = vec3
[ RUN ] TestTypes/3.allocator_size
[ OK ] TestTypes/3.allocator_size (9 ms)
[ RUN ] TestTypes/3.alloc_1
[ OK ] TestTypes/3.alloc_1 (5 ms)
[ RUN ] TestTypes/3.alloc_2
[ OK ] TestTypes/3.alloc_2 (7 ms)
[ RUN ] TestTypes/3.alloc_2_contiguous
[ OK ] TestTypes/3.alloc_2_contiguous (5 ms)
[ RUN ] TestTypes/3.alloc_dealloc_alloc
[ OK ] TestTypes/3.alloc_dealloc_alloc (3 ms)
[ RUN ] TestTypes/3.alloc_fail
[ OK ] TestTypes/3.alloc_fail (3 ms)
[ RUN ] TestTypes/3.dealloc_coalesce
[ OK ] TestTypes/3.dealloc_coalesce (11 ms)
[ RUN ] TestTypes/3.dealloc_coalesce_unordered
[ OK ] TestTypes/3.dealloc_coalesce_unordered (4 ms)
[ RUN ] TestTypes/3.dealloc_null
[ OK ] TestTypes/3.dealloc_null (3 ms)
[ RUN ] TestTypes/3.dealloc_freed
[ OK ] TestTypes/3.dealloc_freed (2 ms)
[----------] 10 tests from TestTypes/3 (52 ms total)

[----------] 2 tests from TestAllocatorIndex
[ RUN ] TestAllocatorIndex.const_index
[ OK ] TestAllocatorIndex.const_index (2 ms)
[ RUN ] TestAllocatorIndex.index
[ OK ] TestAllocatorIndex.index (1 ms)
[----------] 2 tests from TestAllocatorIndex (3 ms total)

[----------] Global test environment tear-down
[==========] 50 tests from 9 test cases ran. (348 ms total)
[ PASSED ] 50 tests.
==4041==
==4041== HEAP SUMMARY:
==4041== in use at exit: 72,704 bytes in 1 blocks
==4041== total heap usage: 1,076 allocs, 1,075 frees, 265,882 bytes allocated
==4041==
==4041== LEAK SUMMARY:
==4041== definitely lost: 0 bytes in 0 blocks
==4041== indirectly lost: 0 bytes in 0 blocks
==4041== possibly lost: 0 bytes in 0 blocks
==4041== still reachable: 72,704 bytes in 1 blocks
==4041== suppressed: 0 bytes in 0 blocks
==4041== Rerun with --leak-check=full to see details of leaked memory
==4041==
==4041== For counts of detected and suppressed errors, rerun with: -v
==4041== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
File 'Allocator.h'
Lines executed:98.63% of 73
Branches executed:73.82% of 932
Taken at least once:46.35% of 932
Calls executed:52.02% of 767
Creating 'Allocator.h.gcov'
File 'TestAllocator.c++'
Lines executed:100.00% of 112
Branches executed:58.87% of 1556
Taken at least once:30.46% of 1556
Calls executed:43.86% of 1703
Creating 'TestAllocator.c++.gcov'