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