diff options
Diffstat (limited to 'src/test/common/test_allocate_unique.cc')
-rw-r--r-- | src/test/common/test_allocate_unique.cc | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/test/common/test_allocate_unique.cc b/src/test/common/test_allocate_unique.cc new file mode 100644 index 000000000..94cb025a4 --- /dev/null +++ b/src/test/common/test_allocate_unique.cc @@ -0,0 +1,97 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2020 Red Hat + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "common/allocate_unique.h" +#include <string> +#include <vector> +#include <gtest/gtest.h> + +namespace { + +// allocation events recorded by logging_allocator +struct event { + size_t size; + bool allocated; // true for allocate(), false for deallocate() +}; +using event_log = std::vector<event>; + +template <typename T> +struct logging_allocator { + event_log *const log; + + using value_type = T; + + explicit logging_allocator(event_log *log) : log(log) {} + logging_allocator(const logging_allocator& other) : log(other.log) {} + + template <typename U> + logging_allocator(const logging_allocator<U>& other) : log(other.log) {} + + T* allocate(size_t n) + { + auto p = std::allocator<T>{}.allocate(n); + log->emplace_back(event{n * sizeof(T), true}); + return p; + } + void deallocate(T* p, size_t n) + { + std::allocator<T>{}.deallocate(p, n); + if (p) { + log->emplace_back(event{n * sizeof(T), false}); + } + } +}; + +} // anonymous namespace + +namespace ceph { + +TEST(AllocateUnique, Allocate) +{ + event_log log; + auto alloc = logging_allocator<char>{&log}; + { + auto p = allocate_unique<char>(alloc, 'a'); + static_assert(std::is_same_v<decltype(p), + std::unique_ptr<char, deallocator<logging_allocator<char>>>>); + ASSERT_TRUE(p); + ASSERT_EQ(1, log.size()); + EXPECT_EQ(1, log.front().size); + EXPECT_EQ(true, log.front().allocated); + } + ASSERT_EQ(2, log.size()); + EXPECT_EQ(1, log.back().size); + EXPECT_EQ(false, log.back().allocated); +} + +TEST(AllocateUnique, RebindAllocate) +{ + event_log log; + auto alloc = logging_allocator<char>{&log}; + { + auto p = allocate_unique<std::string>(alloc, "a"); + static_assert(std::is_same_v<decltype(p), + std::unique_ptr<std::string, + deallocator<logging_allocator<std::string>>>>); + ASSERT_TRUE(p); + ASSERT_EQ(1, log.size()); + EXPECT_EQ(sizeof(std::string), log.front().size); + EXPECT_EQ(true, log.front().allocated); + } + ASSERT_EQ(2, log.size()); + EXPECT_EQ(sizeof(std::string), log.back().size); + EXPECT_EQ(false, log.back().allocated); +} + +} // namespace ceph |