1 /*
2 * Copyright (C) 2016, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <array>
18 #include <tuple>
19 #include <vector>
20
21 #include "gtest/gtest.h"
22
23 #include "wifilogd/message_buffer.h"
24
25 namespace android {
26 namespace wifilogd {
27 namespace {
28
29 constexpr size_t kBufferSizeBytes = 1024;
30 constexpr size_t kHeaderSizeBytes = MessageBuffer::GetHeaderSize();
31 constexpr std::array<uint8_t, 1> kSmallestMessage{};
32 constexpr std::array<uint8_t, kBufferSizeBytes - kHeaderSizeBytes>
33 kLargestMessage{};
34
35 class MessageBufferTest : public ::testing::Test {
36 public:
MessageBufferTest()37 MessageBufferTest() : buffer_{kBufferSizeBytes} {}
38
39 protected:
FillBufferWithMultipleMessages()40 size_t FillBufferWithMultipleMessages() {
41 constexpr std::array<uint8_t, kHeaderSizeBytes> message{};
42 static_assert(kBufferSizeBytes % (kHeaderSizeBytes + message.size()) == 0,
43 "messages will not fill buffer to capacity");
44 size_t n_written;
45 for (n_written = 0;
46 n_written < kBufferSizeBytes / (kHeaderSizeBytes + message.size());
47 ++n_written) {
48 EXPECT_TRUE(buffer_.Append(message.data(), message.size()));
49 }
50 EXPECT_EQ(0U, buffer_.GetFreeSize());
51 return n_written;
52 }
53
GetNextMessageAsByteVector()54 std::vector<uint8_t> GetNextMessageAsByteVector() {
55 const uint8_t* start;
56 size_t len;
57 std::tie(start, len) = buffer_.ConsumeNextMessage();
58 return {start, start + len};
59 }
60
61 MessageBuffer buffer_;
62 };
63
64 } // namespace
65
TEST_F(MessageBufferTest,AppendMinimalOnEmptyBufferSucceeds)66 TEST_F(MessageBufferTest, AppendMinimalOnEmptyBufferSucceeds) {
67 EXPECT_TRUE(buffer_.Append(kSmallestMessage.data(), kSmallestMessage.size()));
68 }
69
TEST_F(MessageBufferTest,AppendMaximalOnEmptyBufferSucceeds)70 TEST_F(MessageBufferTest, AppendMaximalOnEmptyBufferSucceeds) {
71 EXPECT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
72 }
73
TEST_F(MessageBufferTest,AppendMaximalAfterFillAndClearSucceeds)74 TEST_F(MessageBufferTest, AppendMaximalAfterFillAndClearSucceeds) {
75 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
76 ASSERT_FALSE(buffer_.CanFitNow(1));
77
78 buffer_.Clear();
79 EXPECT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
80 }
81
TEST_F(MessageBufferTest,AppendUnalignedMessagesDoesNotCrash)82 TEST_F(MessageBufferTest, AppendUnalignedMessagesDoesNotCrash) {
83 // Odd-length messages should trigger alignment problems, if any such
84 // problems exist. We'll need more than one, though, since the first header
85 // might be aligned by default.
86 constexpr std::array<uint8_t, 1> message{};
87 while (buffer_.CanFitNow(message.size())) {
88 ASSERT_TRUE(buffer_.Append(message.data(), message.size()));
89 }
90 }
91
TEST_F(MessageBufferTest,AppendLargerThanBufferFails)92 TEST_F(MessageBufferTest, AppendLargerThanBufferFails) {
93 constexpr std::array<uint8_t, kBufferSizeBytes + 1> oversized_message{};
94 EXPECT_FALSE(
95 buffer_.Append(oversized_message.data(), oversized_message.size()));
96 }
97
TEST_F(MessageBufferTest,AppendLargerThanFreeSpaceFails)98 TEST_F(MessageBufferTest, AppendLargerThanFreeSpaceFails) {
99 constexpr size_t expected_free = kBufferSizeBytes - kHeaderSizeBytes;
100 ASSERT_FALSE(buffer_.CanFitNow(expected_free + 1));
101
102 constexpr std::array<uint8_t, expected_free + 1> oversized_message{};
103 EXPECT_FALSE(
104 buffer_.Append(oversized_message.data(), oversized_message.size()));
105 }
106
TEST_F(MessageBufferTest,AppendMultipleMessagesToFillBufferDoesNotCrash)107 TEST_F(MessageBufferTest, AppendMultipleMessagesToFillBufferDoesNotCrash) {
108 FillBufferWithMultipleMessages();
109 }
110
TEST_F(MessageBufferTest,CanFitNowIsCorrectOnFreshBuffer)111 TEST_F(MessageBufferTest, CanFitNowIsCorrectOnFreshBuffer) {
112 EXPECT_TRUE(buffer_.CanFitNow(kLargestMessage.size()));
113 EXPECT_FALSE(buffer_.CanFitNow(kLargestMessage.size() + 1));
114 }
115
TEST_F(MessageBufferTest,CanFitNowIsCorrectAfterSmallWrite)116 TEST_F(MessageBufferTest, CanFitNowIsCorrectAfterSmallWrite) {
117 ASSERT_TRUE(buffer_.Append(kSmallestMessage.data(), kSmallestMessage.size()));
118
119 constexpr size_t expected_free =
120 kBufferSizeBytes - (kSmallestMessage.size() + kHeaderSizeBytes) -
121 kHeaderSizeBytes;
122 EXPECT_TRUE(buffer_.CanFitNow(expected_free));
123 EXPECT_FALSE(buffer_.CanFitNow(expected_free + 1));
124 }
125
TEST_F(MessageBufferTest,CanFitNowIsCorrectOnFullBuffer)126 TEST_F(MessageBufferTest, CanFitNowIsCorrectOnFullBuffer) {
127 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
128 EXPECT_FALSE(buffer_.CanFitNow(1));
129 }
130
TEST_F(MessageBufferTest,CanFitNowIsCorrectOnRewoundBuffer)131 TEST_F(MessageBufferTest, CanFitNowIsCorrectOnRewoundBuffer) {
132 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
133 buffer_.Rewind();
134 EXPECT_FALSE(buffer_.CanFitNow(1));
135 }
136
TEST_F(MessageBufferTest,CanFitNowIsCorrectAfterClear)137 TEST_F(MessageBufferTest, CanFitNowIsCorrectAfterClear) {
138 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
139 ASSERT_FALSE(buffer_.CanFitNow(1));
140
141 buffer_.Clear();
142 EXPECT_TRUE(buffer_.CanFitNow(kLargestMessage.size()));
143 }
144
TEST_F(MessageBufferTest,CanFitEverIsCorrectOnFreshBuffer)145 TEST_F(MessageBufferTest, CanFitEverIsCorrectOnFreshBuffer) {
146 EXPECT_TRUE(buffer_.CanFitEver(kLargestMessage.size()));
147 EXPECT_FALSE(buffer_.CanFitEver(kLargestMessage.size() + 1));
148 }
149
TEST_F(MessageBufferTest,CanFitEverIsCorrectAfterSmallWrite)150 TEST_F(MessageBufferTest, CanFitEverIsCorrectAfterSmallWrite) {
151 ASSERT_TRUE(buffer_.Append(kSmallestMessage.data(), kSmallestMessage.size()));
152 EXPECT_TRUE(buffer_.CanFitEver(kLargestMessage.size()));
153 EXPECT_FALSE(buffer_.CanFitEver(kLargestMessage.size() + 1));
154 }
155
TEST_F(MessageBufferTest,CanFitEverIsCorrectOnFullBuffer)156 TEST_F(MessageBufferTest, CanFitEverIsCorrectOnFullBuffer) {
157 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
158 EXPECT_TRUE(buffer_.CanFitEver(kLargestMessage.size()));
159 EXPECT_FALSE(buffer_.CanFitEver(kLargestMessage.size() + 1));
160 }
161
TEST_F(MessageBufferTest,CanFitEverIsCorrectAfterRewind)162 TEST_F(MessageBufferTest, CanFitEverIsCorrectAfterRewind) {
163 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
164 buffer_.Rewind();
165 EXPECT_TRUE(buffer_.CanFitEver(kLargestMessage.size()));
166 EXPECT_FALSE(buffer_.CanFitEver(kLargestMessage.size() + 1));
167 }
168
TEST_F(MessageBufferTest,CanFitEverIsCorrectAfterClear)169 TEST_F(MessageBufferTest, CanFitEverIsCorrectAfterClear) {
170 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
171 buffer_.Clear();
172 EXPECT_TRUE(buffer_.CanFitEver(kLargestMessage.size()));
173 EXPECT_FALSE(buffer_.CanFitEver(kLargestMessage.size() + 1));
174 }
175
TEST_F(MessageBufferTest,ConsumeNextMessageReturnsNullOnFreshBuffer)176 TEST_F(MessageBufferTest, ConsumeNextMessageReturnsNullOnFreshBuffer) {
177 const std::tuple<const uint8_t*, size_t> expected{nullptr, 0};
178 EXPECT_EQ(expected, buffer_.ConsumeNextMessage());
179 }
180
TEST_F(MessageBufferTest,ConsumeNextMessageReturnsNullAfterFillAndClear)181 TEST_F(MessageBufferTest, ConsumeNextMessageReturnsNullAfterFillAndClear) {
182 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
183 buffer_.Clear();
184
185 const std::tuple<const uint8_t*, size_t> expected{nullptr, 0};
186 EXPECT_EQ(expected, buffer_.ConsumeNextMessage());
187 }
188
TEST_F(MessageBufferTest,ConsumeNextMessageCanReadMinimalMessage)189 TEST_F(MessageBufferTest, ConsumeNextMessageCanReadMinimalMessage) {
190 ASSERT_TRUE(buffer_.Append(kSmallestMessage.data(), kSmallestMessage.size()));
191
192 const auto& ptr_and_size = buffer_.ConsumeNextMessage();
193 EXPECT_NE(nullptr, std::get<0>(ptr_and_size));
194 EXPECT_EQ(kSmallestMessage.size(), std::get<1>(ptr_and_size));
195 }
196
TEST_F(MessageBufferTest,ConsumeNextMessageCanReadMaximalMessage)197 TEST_F(MessageBufferTest, ConsumeNextMessageCanReadMaximalMessage) {
198 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
199
200 const auto& ptr_and_size = buffer_.ConsumeNextMessage();
201 EXPECT_NE(nullptr, std::get<0>(ptr_and_size));
202 EXPECT_EQ(kLargestMessage.size(), std::get<1>(ptr_and_size));
203 }
204
TEST_F(MessageBufferTest,ConsumeNextMessageReturnsNullAfterMinimalMessageIsConsumed)205 TEST_F(MessageBufferTest,
206 ConsumeNextMessageReturnsNullAfterMinimalMessageIsConsumed) {
207 ASSERT_TRUE(buffer_.Append(kSmallestMessage.data(), kSmallestMessage.size()));
208 buffer_.ConsumeNextMessage();
209
210 constexpr std::tuple<const uint8_t*, size_t> expected{nullptr, 0};
211 EXPECT_EQ(expected, buffer_.ConsumeNextMessage());
212 }
213
TEST_F(MessageBufferTest,ConsumeNextMessageReturnsNullAfterMaximalMessageIsConsumed)214 TEST_F(MessageBufferTest,
215 ConsumeNextMessageReturnsNullAfterMaximalMessageIsConsumed) {
216 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
217 buffer_.ConsumeNextMessage();
218
219 constexpr std::tuple<const uint8_t*, size_t> expected{nullptr, 0};
220 EXPECT_EQ(expected, buffer_.ConsumeNextMessage());
221 }
222
TEST_F(MessageBufferTest,ConsumeNextMessageCanRetreiveAllMessagesFromFullBuffer)223 TEST_F(MessageBufferTest,
224 ConsumeNextMessageCanRetreiveAllMessagesFromFullBuffer) {
225 const size_t n_written = FillBufferWithMultipleMessages();
226 size_t n_read = 0;
227 while (std::get<0>(buffer_.ConsumeNextMessage())) {
228 ++n_read;
229 }
230 EXPECT_EQ(n_written, n_read);
231
232 constexpr std::tuple<const uint8_t*, size_t> expected{nullptr, 0};
233 EXPECT_EQ(expected, buffer_.ConsumeNextMessage());
234 }
235
TEST_F(MessageBufferTest,ConsumeNextMessageCanRetreiveAllMessagesFromRewoundBuffer)236 TEST_F(MessageBufferTest,
237 ConsumeNextMessageCanRetreiveAllMessagesFromRewoundBuffer) {
238 const size_t n_written = FillBufferWithMultipleMessages();
239 while (std::get<0>(buffer_.ConsumeNextMessage())) {
240 // Silently consume message
241 }
242 buffer_.Rewind();
243
244 size_t n_read = 0;
245 while (std::get<0>(buffer_.ConsumeNextMessage())) {
246 ++n_read;
247 }
248 EXPECT_EQ(n_written, n_read);
249 }
250
TEST_F(MessageBufferTest,ConsumeNextMessageCanRetreiveMultipleUnaliagnedMessages)251 TEST_F(MessageBufferTest,
252 ConsumeNextMessageCanRetreiveMultipleUnaliagnedMessages) {
253 // As in AppendUnalignedMessagesDoesNotCrash, odd-length messages should
254 // trigger alignment problems, if any such problems exist.
255 const std::array<uint8_t, 1> message{};
256 size_t n_written = 0;
257 while (buffer_.CanFitNow(message.size())) {
258 ASSERT_TRUE(buffer_.Append(message.data(), message.size()));
259 ++n_written;
260 }
261
262 size_t n_read = 0;
263 while (std::get<0>(buffer_.ConsumeNextMessage())) {
264 ++n_read;
265 }
266 EXPECT_EQ(n_written, n_read);
267 }
268
TEST_F(MessageBufferTest,ConsumeNextMessageReturnsOurMessages)269 TEST_F(MessageBufferTest, ConsumeNextMessageReturnsOurMessages) {
270 const std::vector<uint8_t> message1{{'h', 'e', 'l', 'l', 'o'}};
271 const std::vector<uint8_t> message2{{'w', 'o', 'r', 'l', 'd'}};
272 ASSERT_TRUE(
273 buffer_.Append(message1.data(), static_cast<uint16_t>(message1.size())));
274 ASSERT_TRUE(
275 buffer_.Append(message2.data(), static_cast<uint16_t>(message2.size())));
276 EXPECT_EQ(message1, GetNextMessageAsByteVector());
277 EXPECT_EQ(message2, GetNextMessageAsByteVector());
278 }
279
TEST_F(MessageBufferTest,GetFreeSizeIsCorrectOnFreshBuffer)280 TEST_F(MessageBufferTest, GetFreeSizeIsCorrectOnFreshBuffer) {
281 EXPECT_EQ(kBufferSizeBytes, buffer_.GetFreeSize());
282 }
283
TEST_F(MessageBufferTest,GetFreeSizeIsCorrectAfterSmallWrite)284 TEST_F(MessageBufferTest, GetFreeSizeIsCorrectAfterSmallWrite) {
285 ASSERT_TRUE(buffer_.Append(kSmallestMessage.data(), kSmallestMessage.size()));
286 EXPECT_EQ(kBufferSizeBytes - kHeaderSizeBytes - kSmallestMessage.size(),
287 buffer_.GetFreeSize());
288 }
289
TEST_F(MessageBufferTest,GetFreeSizeIsCorrectOnFullBuffer)290 TEST_F(MessageBufferTest, GetFreeSizeIsCorrectOnFullBuffer) {
291 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
292 EXPECT_EQ(0U, buffer_.GetFreeSize());
293 }
294
TEST_F(MessageBufferTest,GetFreeSizeIsCorrectAfterRewindOfFullBuffer)295 TEST_F(MessageBufferTest, GetFreeSizeIsCorrectAfterRewindOfFullBuffer) {
296 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
297 buffer_.Rewind();
298 EXPECT_EQ(0U, buffer_.GetFreeSize());
299 }
300
TEST_F(MessageBufferTest,GetFreeSizeIsCorrectAfterClear)301 TEST_F(MessageBufferTest, GetFreeSizeIsCorrectAfterClear) {
302 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
303 buffer_.Clear();
304 EXPECT_EQ(kBufferSizeBytes, buffer_.GetFreeSize());
305 }
306
TEST_F(MessageBufferTest,RewindDoesNotAffectWritePointer)307 TEST_F(MessageBufferTest, RewindDoesNotAffectWritePointer) {
308 const std::vector<uint8_t> message1{{'h', 'e', 'l', 'l', 'o'}};
309 ASSERT_TRUE(
310 buffer_.Append(message1.data(), static_cast<uint16_t>(message1.size())));
311 buffer_.Rewind();
312
313 const std::vector<uint8_t> message2{{'w', 'o', 'r', 'l', 'd'}};
314 ASSERT_TRUE(
315 buffer_.Append(message2.data(), static_cast<uint16_t>(message2.size())));
316
317 EXPECT_EQ(message1, GetNextMessageAsByteVector());
318 EXPECT_EQ(message2, GetNextMessageAsByteVector());
319 }
320
321 // Per
322 // github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#death-tests,
323 // death tests should be specially named.
324 using MessageBufferDeathTest = MessageBufferTest;
325
TEST_F(MessageBufferDeathTest,AppendZeroBytesCausesDeath)326 TEST_F(MessageBufferDeathTest, AppendZeroBytesCausesDeath) {
327 constexpr std::array<uint8_t, 1> message{};
328 EXPECT_DEATH(buffer_.Append(message.data(), 0), "Check failed");
329 }
330
TEST_F(MessageBufferDeathTest,ConstructionOfUselesslySmallBufferCausesDeath)331 TEST_F(MessageBufferDeathTest, ConstructionOfUselesslySmallBufferCausesDeath) {
332 EXPECT_DEATH(MessageBuffer{kHeaderSizeBytes}, "Check failed");
333 }
334
335 } // namespace wifilogd
336 } // namespace android
337