aboutsummaryrefslogtreecommitdiff
path: root/pw_allocator/allocator_metric_proxy_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'pw_allocator/allocator_metric_proxy_test.cc')
-rw-r--r--pw_allocator/allocator_metric_proxy_test.cc175
1 files changed, 175 insertions, 0 deletions
diff --git a/pw_allocator/allocator_metric_proxy_test.cc b/pw_allocator/allocator_metric_proxy_test.cc
new file mode 100644
index 000000000..cfc94b2f0
--- /dev/null
+++ b/pw_allocator/allocator_metric_proxy_test.cc
@@ -0,0 +1,175 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#include "pw_allocator/allocator_metric_proxy.h"
+
+#include "gtest/gtest.h"
+#include "pw_allocator/allocator_testing.h"
+
+namespace pw::allocator {
+namespace {
+
+// Test fixtures.
+
+class AllocatorMetricProxyTest : public ::testing::Test {
+ protected:
+ AllocatorMetricProxyTest() : allocator(0) {}
+
+ void SetUp() override { allocator.Initialize(*wrapped); }
+
+ AllocatorMetricProxy allocator;
+
+ private:
+ test::AllocatorForTestWithBuffer<256> wrapped;
+};
+
+// Unit tests.
+
+TEST_F(AllocatorMetricProxyTest, InitiallyZero) {
+ EXPECT_EQ(allocator.used(), 0U);
+ EXPECT_EQ(allocator.peak(), 0U);
+ EXPECT_EQ(allocator.count(), 0U);
+}
+
+TEST_F(AllocatorMetricProxyTest, MetricsInitialized) {
+ auto& memusage = allocator.memusage();
+ EXPECT_EQ(memusage.metrics().size(), 3U);
+ EXPECT_EQ(memusage.children().size(), 0U);
+}
+
+TEST_F(AllocatorMetricProxyTest, AllocateDeallocate) {
+ constexpr Layout layout = Layout::Of<uint32_t[2]>();
+ void* ptr = allocator.Allocate(layout);
+ ASSERT_NE(ptr, nullptr);
+ EXPECT_EQ(allocator.used(), sizeof(uint32_t) * 2);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 2);
+ EXPECT_EQ(allocator.count(), 1U);
+
+ allocator.Deallocate(ptr, layout);
+ EXPECT_EQ(allocator.used(), 0U);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 2);
+ EXPECT_EQ(allocator.count(), 0U);
+}
+
+TEST_F(AllocatorMetricProxyTest, AllocateFailure) {
+ constexpr Layout layout = Layout::Of<uint32_t[0x10000000U]>();
+ void* ptr = allocator.Allocate(layout);
+ EXPECT_EQ(ptr, nullptr);
+ EXPECT_EQ(allocator.used(), 0U);
+ EXPECT_EQ(allocator.peak(), 0U);
+ EXPECT_EQ(allocator.count(), 0U);
+}
+
+TEST_F(AllocatorMetricProxyTest, AllocateDeallocateMultiple) {
+ constexpr Layout layout1 = Layout::Of<uint32_t[3]>();
+ void* ptr1 = allocator.Allocate(layout1);
+ ASSERT_NE(ptr1, nullptr);
+ EXPECT_EQ(allocator.used(), sizeof(uint32_t) * 3);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 3);
+ EXPECT_EQ(allocator.count(), 1U);
+
+ constexpr Layout layout2 = Layout::Of<uint32_t[2]>();
+ void* ptr2 = allocator.Allocate(layout2);
+ ASSERT_NE(ptr2, nullptr);
+ EXPECT_EQ(allocator.used(), sizeof(uint32_t) * 5);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 5);
+ EXPECT_EQ(allocator.count(), 2U);
+
+ allocator.Deallocate(ptr1, layout1);
+ EXPECT_EQ(allocator.used(), sizeof(uint32_t) * 2);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 5);
+ EXPECT_EQ(allocator.count(), 1U);
+
+ allocator.Deallocate(ptr2, layout2);
+ EXPECT_EQ(allocator.used(), 0U);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 5);
+ EXPECT_EQ(allocator.count(), 0U);
+}
+
+TEST_F(AllocatorMetricProxyTest, ResizeLarger) {
+ constexpr Layout old_layout = Layout::Of<uint32_t[3]>();
+ void* ptr = allocator.Allocate(old_layout);
+ ASSERT_NE(ptr, nullptr);
+ EXPECT_EQ(allocator.used(), sizeof(uint32_t) * 3);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 3);
+ EXPECT_EQ(allocator.count(), 1U);
+
+ constexpr Layout new_layout = Layout::Of<uint32_t[5]>();
+ EXPECT_TRUE(allocator.Resize(ptr, old_layout, new_layout.size()));
+ EXPECT_EQ(allocator.used(), sizeof(uint32_t) * 5);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 5);
+ EXPECT_EQ(allocator.count(), 1U);
+
+ allocator.Deallocate(ptr, new_layout);
+ EXPECT_EQ(allocator.used(), 0U);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 5);
+ EXPECT_EQ(allocator.count(), 0U);
+}
+
+TEST_F(AllocatorMetricProxyTest, ResizeSmaller) {
+ constexpr Layout old_layout = Layout::Of<uint32_t[2]>();
+ void* ptr = allocator.Allocate(old_layout);
+ ASSERT_NE(ptr, nullptr);
+ EXPECT_EQ(allocator.used(), sizeof(uint32_t) * 2);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 2);
+ EXPECT_EQ(allocator.count(), 1U);
+
+ constexpr Layout new_layout = Layout::Of<uint32_t>();
+ EXPECT_TRUE(allocator.Resize(ptr, old_layout, new_layout.size()));
+ EXPECT_EQ(allocator.used(), sizeof(uint32_t));
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 2);
+ EXPECT_EQ(allocator.count(), 1U);
+
+ allocator.Deallocate(ptr, new_layout);
+ EXPECT_EQ(allocator.used(), 0U);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 2);
+ EXPECT_EQ(allocator.count(), 0U);
+}
+
+TEST_F(AllocatorMetricProxyTest, Reallocate) {
+ constexpr Layout old_layout = Layout::Of<uint32_t[2]>();
+ void* ptr1 = allocator.Allocate(old_layout);
+ ASSERT_NE(ptr1, nullptr);
+ EXPECT_EQ(allocator.used(), sizeof(uint32_t) * 2);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 2);
+ EXPECT_EQ(allocator.count(), 1U);
+
+ // Make a second allocation to force reallocation.
+ void* ptr2 = allocator.Allocate(old_layout);
+ ASSERT_NE(ptr2, nullptr);
+ EXPECT_EQ(allocator.used(), sizeof(uint32_t) * 4);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 4);
+ EXPECT_EQ(allocator.count(), 2U);
+
+ // Reallocating allocates before deallocating, leading to higher peaks.
+ constexpr Layout new_layout = Layout::Of<uint32_t[4]>();
+ void* new_ptr = allocator.Reallocate(ptr1, old_layout, new_layout.size());
+ EXPECT_NE(new_ptr, nullptr);
+ EXPECT_EQ(allocator.used(), sizeof(uint32_t) * 6);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 8);
+ EXPECT_EQ(allocator.count(), 2U);
+
+ allocator.Deallocate(new_ptr, new_layout);
+ EXPECT_EQ(allocator.used(), sizeof(uint32_t) * 2);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 8);
+ EXPECT_EQ(allocator.count(), 1U);
+
+ allocator.Deallocate(ptr2, old_layout);
+ EXPECT_EQ(allocator.used(), 0U);
+ EXPECT_EQ(allocator.peak(), sizeof(uint32_t) * 8);
+ EXPECT_EQ(allocator.count(), 0U);
+}
+
+} // namespace
+} // namespace pw::allocator