pool_test.cc
Go to the documentation of this file.
1 /* Copyright (c) 2016, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <gtest/gtest.h>
16 
17 #include <openssl/pool.h>
18 
19 #include "internal.h"
20 #include "../test/test_util.h"
21 
22 #if defined(OPENSSL_THREADS)
23 #include <chrono>
24 #include <thread>
25 #endif
26 
27 
28 TEST(PoolTest, Unpooled) {
29  static const uint8_t kData[4] = {1, 2, 3, 4};
30  bssl::UniquePtr<CRYPTO_BUFFER> buf(
31  CRYPTO_BUFFER_new(kData, sizeof(kData), nullptr));
33 
34  EXPECT_EQ(Bytes(kData),
36 
37  // Test that reference-counting works properly.
38  bssl::UniquePtr<CRYPTO_BUFFER> buf2 = bssl::UpRef(buf);
39 
40  bssl::UniquePtr<CRYPTO_BUFFER> buf_static(
41  CRYPTO_BUFFER_new_from_static_data_unsafe(kData, sizeof(kData), nullptr));
42  ASSERT_TRUE(buf_static);
43  EXPECT_EQ(kData, CRYPTO_BUFFER_data(buf_static.get()));
44  EXPECT_EQ(sizeof(kData), CRYPTO_BUFFER_len(buf_static.get()));
45 
46  // Test that reference-counting works properly.
47  bssl::UniquePtr<CRYPTO_BUFFER> buf_static2 = bssl::UpRef(buf_static);
48 }
49 
50 TEST(PoolTest, Empty) {
51  bssl::UniquePtr<CRYPTO_BUFFER> buf(CRYPTO_BUFFER_new(nullptr, 0, nullptr));
53 
54  EXPECT_EQ(Bytes(""),
56 
57  bssl::UniquePtr<CRYPTO_BUFFER> buf_static(
58  CRYPTO_BUFFER_new_from_static_data_unsafe(nullptr, 0, nullptr));
59  ASSERT_TRUE(buf_static);
60 
61  EXPECT_EQ(nullptr, CRYPTO_BUFFER_data(buf_static.get()));
62  EXPECT_EQ(0u, CRYPTO_BUFFER_len(buf_static.get()));
63 }
64 
65 TEST(PoolTest, Pooled) {
66  bssl::UniquePtr<CRYPTO_BUFFER_POOL> pool(CRYPTO_BUFFER_POOL_new());
68 
69  static const uint8_t kData1[4] = {1, 2, 3, 4};
70  bssl::UniquePtr<CRYPTO_BUFFER> buf(
71  CRYPTO_BUFFER_new(kData1, sizeof(kData1), pool.get()));
75 
76  bssl::UniquePtr<CRYPTO_BUFFER> buf2(
77  CRYPTO_BUFFER_new(kData1, sizeof(kData1), pool.get()));
80  CRYPTO_BUFFER_len(buf2.get())));
81 
82  EXPECT_EQ(buf.get(), buf2.get()) << "CRYPTO_BUFFER_POOL did not dedup data.";
83 
84  // Different inputs do not get deduped.
85  static const uint8_t kData2[4] = {5, 6, 7, 8};
86  bssl::UniquePtr<CRYPTO_BUFFER> buf3(
87  CRYPTO_BUFFER_new(kData2, sizeof(kData2), pool.get()));
88  ASSERT_TRUE(buf3);
90  CRYPTO_BUFFER_len(buf3.get())));
91  EXPECT_NE(buf.get(), buf3.get());
92 
93  // When the last refcount on |buf3| is dropped, it is removed from the pool.
94  buf3 = nullptr;
95  EXPECT_EQ(1u, lh_CRYPTO_BUFFER_num_items(pool->bufs));
96 
97  // Static buffers participate in pooling.
99  pool.get()));
100  ASSERT_TRUE(buf3);
101  EXPECT_EQ(kData2, CRYPTO_BUFFER_data(buf3.get()));
102  EXPECT_EQ(sizeof(kData2), CRYPTO_BUFFER_len(buf3.get()));
103  EXPECT_NE(buf.get(), buf3.get());
104 
105  bssl::UniquePtr<CRYPTO_BUFFER> buf4(
106  CRYPTO_BUFFER_new(kData2, sizeof(kData2), pool.get()));
107  EXPECT_EQ(buf4.get(), buf3.get());
108 
109  bssl::UniquePtr<CRYPTO_BUFFER> buf5(CRYPTO_BUFFER_new_from_static_data_unsafe(
110  kData2, sizeof(kData2), pool.get()));
111  EXPECT_EQ(buf5.get(), buf3.get());
112 
113  // When creating a static buffer, if there is already a non-static buffer, it
114  // replaces the old buffer.
115  bssl::UniquePtr<CRYPTO_BUFFER> buf6(CRYPTO_BUFFER_new_from_static_data_unsafe(
116  kData1, sizeof(kData1), pool.get()));
117  ASSERT_TRUE(buf6);
118  EXPECT_EQ(kData1, CRYPTO_BUFFER_data(buf6.get()));
119  EXPECT_EQ(sizeof(kData1), CRYPTO_BUFFER_len(buf6.get()));
120  EXPECT_NE(buf.get(), buf6.get());
121 
122  // Subsequent lookups of |kData1| should return |buf6|.
123  bssl::UniquePtr<CRYPTO_BUFFER> buf7(
124  CRYPTO_BUFFER_new(kData1, sizeof(kData1), pool.get()));
125  EXPECT_EQ(buf7.get(), buf6.get());
126 }
127 
128 #if defined(OPENSSL_THREADS)
129 TEST(PoolTest, Threads) {
130  bssl::UniquePtr<CRYPTO_BUFFER_POOL> pool(CRYPTO_BUFFER_POOL_new());
131  ASSERT_TRUE(pool);
132 
133  // Race threads making pooled |CRYPTO_BUFFER|s.
134  static const uint8_t kData[4] = {1, 2, 3, 4};
135  static const uint8_t kData2[3] = {4, 5, 6};
136  bssl::UniquePtr<CRYPTO_BUFFER> buf, buf2, buf3;
137  {
138  std::thread thread([&] {
139  buf.reset(CRYPTO_BUFFER_new(kData, sizeof(kData), pool.get()));
140  });
141  std::thread thread2([&] {
142  buf2.reset(CRYPTO_BUFFER_new(kData, sizeof(kData), pool.get()));
143  });
144  buf3.reset(CRYPTO_BUFFER_new(kData2, sizeof(kData2), pool.get()));
145  thread.join();
146  thread2.join();
147  }
148 
149  ASSERT_TRUE(buf);
150  ASSERT_TRUE(buf2);
151  ASSERT_TRUE(buf3);
152  EXPECT_EQ(buf.get(), buf2.get()) << "CRYPTO_BUFFER_POOL did not dedup data.";
153  EXPECT_NE(buf.get(), buf3.get())
154  << "CRYPTO_BUFFER_POOL incorrectly deduped data.";
155  EXPECT_EQ(Bytes(kData),
158  CRYPTO_BUFFER_len(buf3.get())));
159 
160  // Reference-counting of |CRYPTO_BUFFER| interacts with pooling. Race an
161  // increment and free.
162  {
163  bssl::UniquePtr<CRYPTO_BUFFER> buf_ref;
164  std::thread thread([&] { buf_ref = bssl::UpRef(buf); });
165  buf2.reset();
166  thread.join();
167  }
168 
169  // |buf|'s data is still valid.
170  EXPECT_EQ(Bytes(kData), Bytes(CRYPTO_BUFFER_data(buf.get()),
171  CRYPTO_BUFFER_len(buf.get())));
172 
173  // Race a thread re-creating the |CRYPTO_BUFFER| with another thread freeing
174  // it. Do this twice with sleeps so ThreadSanitizer can observe two different
175  // interleavings. Ideally we would run this test under a tool that could
176  // search all interleavings.
177  {
178  std::thread thread([&] {
179  std::this_thread::sleep_for(std::chrono::milliseconds(1));
180  buf.reset();
181  });
182  buf2.reset(CRYPTO_BUFFER_new(kData, sizeof(kData), pool.get()));
183  thread.join();
184 
185  ASSERT_TRUE(buf2);
187  CRYPTO_BUFFER_len(buf2.get())));
188  buf = std::move(buf2);
189  }
190 
191  {
192  std::thread thread([&] { buf.reset(); });
193  std::this_thread::sleep_for(std::chrono::milliseconds(1));
194  buf2.reset(CRYPTO_BUFFER_new(kData, sizeof(kData), pool.get()));
195  thread.join();
196 
197  ASSERT_TRUE(buf2);
199  CRYPTO_BUFFER_len(buf2.get())));
200  buf = std::move(buf2);
201  }
202 
203  // Finally, race the frees.
204  {
205  buf2 = bssl::UpRef(buf);
206  std::thread thread([&] { buf.reset(); });
207  std::thread thread2([&] { buf3.reset(); });
208  buf2.reset();
209  thread.join();
210  thread2.join();
211  }
212 }
213 #endif
Bytes
Definition: boringssl-with-bazel/src/crypto/test/test_util.h:38
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
kData1
static const char * kData1[]
Definition: crypto_test_data.cc:223
CRYPTO_BUFFER_len
#define CRYPTO_BUFFER_len
Definition: boringssl_prefix_symbols.h:1118
TEST
TEST(PoolTest, Unpooled)
Definition: pool_test.cc:28
u
OPENSSL_EXPORT pem_password_cb void * u
Definition: pem.h:351
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2028
pool.h
CRYPTO_BUFFER_new_from_static_data_unsafe
#define CRYPTO_BUFFER_new_from_static_data_unsafe
Definition: boringssl_prefix_symbols.h:1121
CRYPTO_BUFFER_new
#define CRYPTO_BUFFER_new
Definition: boringssl_prefix_symbols.h:1119
CRYPTO_BUFFER_POOL_new
#define CRYPTO_BUFFER_POOL_new
Definition: boringssl_prefix_symbols.h:1113
Empty
Definition: abseil-cpp/absl/container/internal/compressed_tuple_test.cc:33
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1973
buf2
static char buf2[32]
Definition: test-fs.c:127
pool
InternalDescriptorPool * pool
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:807
internal.h
kData2
static const char * kData2[]
Definition: crypto_test_data.cc:283
thread
static uv_thread_t thread
Definition: test-async-null-cb.c:29
CRYPTO_BUFFER_data
#define CRYPTO_BUFFER_data
Definition: boringssl_prefix_symbols.h:1115


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:44