xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/common/quiche_simple_arena_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 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/common/quiche_simple_arena.h"
6 
7 #include <string>
8 #include <vector>
9 
10 #include "absl/strings/string_view.h"
11 #include "quiche/common/platform/api/quiche_test.h"
12 
13 namespace quiche {
14 namespace {
15 
16 size_t kDefaultBlockSize = 2048;
17 const char kTestString[] = "This is a decently long test string.";
18 
TEST(QuicheSimpleArenaTest,NoAllocationOnConstruction)19 TEST(QuicheSimpleArenaTest, NoAllocationOnConstruction) {
20   QuicheSimpleArena arena(kDefaultBlockSize);
21   EXPECT_EQ(0u, arena.status().bytes_allocated());
22 }
23 
TEST(QuicheSimpleArenaTest,Memdup)24 TEST(QuicheSimpleArenaTest, Memdup) {
25   QuicheSimpleArena arena(kDefaultBlockSize);
26   const size_t length = strlen(kTestString);
27   char* c = arena.Memdup(kTestString, length);
28   EXPECT_NE(nullptr, c);
29   EXPECT_NE(c, kTestString);
30   EXPECT_EQ(absl::string_view(c, length), kTestString);
31 }
32 
TEST(QuicheSimpleArenaTest,MemdupLargeString)33 TEST(QuicheSimpleArenaTest, MemdupLargeString) {
34   QuicheSimpleArena arena(10 /* block size */);
35   const size_t length = strlen(kTestString);
36   char* c = arena.Memdup(kTestString, length);
37   EXPECT_NE(nullptr, c);
38   EXPECT_NE(c, kTestString);
39   EXPECT_EQ(absl::string_view(c, length), kTestString);
40 }
41 
TEST(QuicheSimpleArenaTest,MultipleBlocks)42 TEST(QuicheSimpleArenaTest, MultipleBlocks) {
43   QuicheSimpleArena arena(40 /* block size */);
44   std::vector<std::string> strings = {
45       "One decently long string.", "Another string.",
46       "A third string that will surely go in a different block."};
47   std::vector<absl::string_view> copies;
48   for (const std::string& s : strings) {
49     absl::string_view sp(arena.Memdup(s.data(), s.size()), s.size());
50     copies.push_back(sp);
51   }
52   EXPECT_EQ(strings.size(), copies.size());
53   for (size_t i = 0; i < strings.size(); ++i) {
54     EXPECT_EQ(copies[i], strings[i]);
55   }
56 }
57 
TEST(QuicheSimpleArenaTest,UseAfterReset)58 TEST(QuicheSimpleArenaTest, UseAfterReset) {
59   QuicheSimpleArena arena(kDefaultBlockSize);
60   const size_t length = strlen(kTestString);
61   char* c = arena.Memdup(kTestString, length);
62   arena.Reset();
63   c = arena.Memdup(kTestString, length);
64   EXPECT_NE(nullptr, c);
65   EXPECT_NE(c, kTestString);
66   EXPECT_EQ(absl::string_view(c, length), kTestString);
67 }
68 
TEST(QuicheSimpleArenaTest,Free)69 TEST(QuicheSimpleArenaTest, Free) {
70   QuicheSimpleArena arena(kDefaultBlockSize);
71   const size_t length = strlen(kTestString);
72   // Freeing memory not owned by the arena should be a no-op, and freeing
73   // before any allocations from the arena should be a no-op.
74   arena.Free(const_cast<char*>(kTestString), length);
75   char* c1 = arena.Memdup("Foo", 3);
76   char* c2 = arena.Memdup(kTestString, length);
77   arena.Free(const_cast<char*>(kTestString), length);
78   char* c3 = arena.Memdup("Bar", 3);
79   char* c4 = arena.Memdup(kTestString, length);
80   EXPECT_NE(c1, c2);
81   EXPECT_NE(c1, c3);
82   EXPECT_NE(c1, c4);
83   EXPECT_NE(c2, c3);
84   EXPECT_NE(c2, c4);
85   EXPECT_NE(c3, c4);
86   // Freeing c4 should succeed, since it was the most recent allocation.
87   arena.Free(c4, length);
88   // Freeing c2 should be a no-op.
89   arena.Free(c2, length);
90   // c5 should reuse memory that was previously used by c4.
91   char* c5 = arena.Memdup("Baz", 3);
92   EXPECT_EQ(c4, c5);
93 }
94 
TEST(QuicheSimpleArenaTest,Alloc)95 TEST(QuicheSimpleArenaTest, Alloc) {
96   QuicheSimpleArena arena(kDefaultBlockSize);
97   const size_t length = strlen(kTestString);
98   char* c1 = arena.Alloc(length);
99   char* c2 = arena.Alloc(2 * length);
100   char* c3 = arena.Alloc(3 * length);
101   char* c4 = arena.Memdup(kTestString, length);
102   EXPECT_EQ(c1 + length, c2);
103   EXPECT_EQ(c2 + 2 * length, c3);
104   EXPECT_EQ(c3 + 3 * length, c4);
105   EXPECT_EQ(absl::string_view(c4, length), kTestString);
106 }
107 
TEST(QuicheSimpleArenaTest,Realloc)108 TEST(QuicheSimpleArenaTest, Realloc) {
109   QuicheSimpleArena arena(kDefaultBlockSize);
110   const size_t length = strlen(kTestString);
111   // Simple realloc that fits in the block.
112   char* c1 = arena.Memdup(kTestString, length);
113   char* c2 = arena.Realloc(c1, length, 2 * length);
114   EXPECT_TRUE(c1);
115   EXPECT_EQ(c1, c2);
116   EXPECT_EQ(absl::string_view(c1, length), kTestString);
117   // Multiple reallocs.
118   char* c3 = arena.Memdup(kTestString, length);
119   EXPECT_EQ(c2 + 2 * length, c3);
120   EXPECT_EQ(absl::string_view(c3, length), kTestString);
121   char* c4 = arena.Realloc(c3, length, 2 * length);
122   EXPECT_EQ(c3, c4);
123   EXPECT_EQ(absl::string_view(c4, length), kTestString);
124   char* c5 = arena.Realloc(c4, 2 * length, 3 * length);
125   EXPECT_EQ(c4, c5);
126   EXPECT_EQ(absl::string_view(c5, length), kTestString);
127   char* c6 = arena.Memdup(kTestString, length);
128   EXPECT_EQ(c5 + 3 * length, c6);
129   EXPECT_EQ(absl::string_view(c6, length), kTestString);
130   // Realloc that does not fit in the remainder of the first block.
131   char* c7 = arena.Realloc(c6, length, kDefaultBlockSize);
132   EXPECT_EQ(absl::string_view(c7, length), kTestString);
133   arena.Free(c7, kDefaultBlockSize);
134   char* c8 = arena.Memdup(kTestString, length);
135   EXPECT_NE(c6, c7);
136   EXPECT_EQ(c7, c8);
137   EXPECT_EQ(absl::string_view(c8, length), kTestString);
138 }
139 
140 }  // namespace
141 }  // namespace quiche
142