1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "quiche/quic/core/quic_arena_scoped_ptr.h"
6
7 #include "quiche/quic/core/quic_one_block_arena.h"
8 #include "quiche/quic/platform/api/quic_test.h"
9
10 namespace quic::test {
11 namespace {
12
13 enum class TestParam { kFromHeap, kFromArena };
14
15 struct TestObject {
TestObjectquic::test::__anon167ed7390111::TestObject16 explicit TestObject(uintptr_t value) : value(value) { buffer.resize(1024); }
17 uintptr_t value;
18
19 // Ensure that we have a non-trivial destructor that will leak memory if it's
20 // not called.
21 std::vector<char> buffer;
22 };
23
24 // Used by ::testing::PrintToStringParamName().
PrintToString(const TestParam & p)25 std::string PrintToString(const TestParam& p) {
26 switch (p) {
27 case TestParam::kFromHeap:
28 return "heap";
29 case TestParam::kFromArena:
30 return "arena";
31 }
32 QUICHE_DCHECK(false);
33 return "?";
34 }
35
36 class QuicArenaScopedPtrParamTest : public QuicTestWithParam<TestParam> {
37 protected:
CreateObject(uintptr_t value)38 QuicArenaScopedPtr<TestObject> CreateObject(uintptr_t value) {
39 QuicArenaScopedPtr<TestObject> ptr;
40 switch (GetParam()) {
41 case TestParam::kFromHeap:
42 ptr = QuicArenaScopedPtr<TestObject>(new TestObject(value));
43 QUICHE_CHECK(!ptr.is_from_arena());
44 break;
45 case TestParam::kFromArena:
46 ptr = arena_.New<TestObject>(value);
47 QUICHE_CHECK(ptr.is_from_arena());
48 break;
49 }
50 return ptr;
51 }
52
53 private:
54 QuicOneBlockArena<1024> arena_;
55 };
56
57 INSTANTIATE_TEST_SUITE_P(QuicArenaScopedPtrParamTest,
58 QuicArenaScopedPtrParamTest,
59 testing::Values(TestParam::kFromHeap,
60 TestParam::kFromArena),
61 ::testing::PrintToStringParamName());
62
TEST_P(QuicArenaScopedPtrParamTest,NullObjects)63 TEST_P(QuicArenaScopedPtrParamTest, NullObjects) {
64 QuicArenaScopedPtr<TestObject> def;
65 QuicArenaScopedPtr<TestObject> null(nullptr);
66 EXPECT_EQ(def, null);
67 EXPECT_EQ(def, nullptr);
68 EXPECT_EQ(null, nullptr);
69 }
70
TEST_P(QuicArenaScopedPtrParamTest,FromArena)71 TEST_P(QuicArenaScopedPtrParamTest, FromArena) {
72 QuicOneBlockArena<1024> arena_;
73 EXPECT_TRUE(arena_.New<TestObject>(0).is_from_arena());
74 EXPECT_FALSE(
75 QuicArenaScopedPtr<TestObject>(new TestObject(0)).is_from_arena());
76 }
77
TEST_P(QuicArenaScopedPtrParamTest,Assign)78 TEST_P(QuicArenaScopedPtrParamTest, Assign) {
79 QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
80 ptr = CreateObject(54321);
81 EXPECT_EQ(54321u, ptr->value);
82 }
83
TEST_P(QuicArenaScopedPtrParamTest,MoveConstruct)84 TEST_P(QuicArenaScopedPtrParamTest, MoveConstruct) {
85 QuicArenaScopedPtr<TestObject> ptr1 = CreateObject(12345);
86 QuicArenaScopedPtr<TestObject> ptr2(std::move(ptr1));
87 EXPECT_EQ(nullptr, ptr1);
88 EXPECT_EQ(12345u, ptr2->value);
89 }
90
TEST_P(QuicArenaScopedPtrParamTest,Accessors)91 TEST_P(QuicArenaScopedPtrParamTest, Accessors) {
92 QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
93 EXPECT_EQ(12345u, (*ptr).value);
94 EXPECT_EQ(12345u, ptr->value);
95 // We explicitly want to test that get() returns a valid pointer to the data,
96 // but the call looks redundant.
97 EXPECT_EQ(12345u, ptr.get()->value); // NOLINT
98 }
99
TEST_P(QuicArenaScopedPtrParamTest,Reset)100 TEST_P(QuicArenaScopedPtrParamTest, Reset) {
101 QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
102 ptr.reset(new TestObject(54321));
103 EXPECT_EQ(54321u, ptr->value);
104 }
105
TEST_P(QuicArenaScopedPtrParamTest,Swap)106 TEST_P(QuicArenaScopedPtrParamTest, Swap) {
107 QuicArenaScopedPtr<TestObject> ptr1 = CreateObject(12345);
108 QuicArenaScopedPtr<TestObject> ptr2 = CreateObject(54321);
109 ptr1.swap(ptr2);
110 EXPECT_EQ(12345u, ptr2->value);
111 EXPECT_EQ(54321u, ptr1->value);
112 }
113
114 } // namespace
115 } // namespace quic::test
116