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: 37 MessageBufferTest() : buffer_{kBufferSizeBytes} {} 38 39 protected: 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 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 66 TEST_F(MessageBufferTest, AppendMinimalOnEmptyBufferSucceeds) { 67 EXPECT_TRUE(buffer_.Append(kSmallestMessage.data(), kSmallestMessage.size())); 68 } 69 70 TEST_F(MessageBufferTest, AppendMaximalOnEmptyBufferSucceeds) { 71 EXPECT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size())); 72 } 73 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 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 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 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 107 TEST_F(MessageBufferTest, AppendMultipleMessagesToFillBufferDoesNotCrash) { 108 FillBufferWithMultipleMessages(); 109 } 110 111 TEST_F(MessageBufferTest, CanFitNowIsCorrectOnFreshBuffer) { 112 EXPECT_TRUE(buffer_.CanFitNow(kLargestMessage.size())); 113 EXPECT_FALSE(buffer_.CanFitNow(kLargestMessage.size() + 1)); 114 } 115 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 126 TEST_F(MessageBufferTest, CanFitNowIsCorrectOnFullBuffer) { 127 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size())); 128 EXPECT_FALSE(buffer_.CanFitNow(1)); 129 } 130 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 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 145 TEST_F(MessageBufferTest, CanFitEverIsCorrectOnFreshBuffer) { 146 EXPECT_TRUE(buffer_.CanFitEver(kLargestMessage.size())); 147 EXPECT_FALSE(buffer_.CanFitEver(kLargestMessage.size() + 1)); 148 } 149 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 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 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 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 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 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 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 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 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 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 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 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 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 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 280 TEST_F(MessageBufferTest, GetFreeSizeIsCorrectOnFreshBuffer) { 281 EXPECT_EQ(kBufferSizeBytes, buffer_.GetFreeSize()); 282 } 283 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 290 TEST_F(MessageBufferTest, GetFreeSizeIsCorrectOnFullBuffer) { 291 ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size())); 292 EXPECT_EQ(0U, buffer_.GetFreeSize()); 293 } 294 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 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 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 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 331 TEST_F(MessageBufferDeathTest, ConstructionOfUselesslySmallBufferCausesDeath) { 332 EXPECT_DEATH(MessageBuffer{kHeaderSizeBytes}, "Check failed"); 333 } 334 335 } // namespace wifilogd 336 } // namespace android 337