| /* |
| * Copyright (C) 2016, The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <array> |
| |
| #include "gtest/gtest.h" |
| |
| #include "wifilogd/byte_buffer.h" |
| #include "wifilogd/local_utils.h" |
| #include "wifilogd/memory_reader.h" |
| |
| namespace android { |
| namespace wifilogd { |
| |
| using local_utils::GetMaxVal; |
| |
| TEST(MemoryReaderTest, BoolConversionNonEmptyBufferYieldsTrue) { |
| constexpr std::array<uint8_t, 1> buffer{}; |
| MemoryReader memory_reader(buffer.data(), buffer.size()); |
| EXPECT_TRUE(memory_reader); |
| } |
| |
| TEST(MemoryReaderTest, BoolConversionEmptyBufferYieldsFalse) { |
| constexpr std::array<uint8_t, 0> buffer{}; |
| MemoryReader memory_reader(buffer.data(), buffer.size()); |
| EXPECT_FALSE(memory_reader); |
| } |
| |
| TEST(MemoryReaderTest, BoolConversionNullBufferYieldsFalse) { |
| MemoryReader memory_reader(nullptr, 10); |
| EXPECT_FALSE(memory_reader); |
| } |
| |
| TEST(MemoryReaderTest, CopyAssignmentWorks) { |
| constexpr std::array<uint8_t, 3> buffer{{1, 2, 3}}; |
| |
| MemoryReader reader1{buffer.data(), buffer.size()}; |
| EXPECT_EQ(buffer[0], *reader1.GetBytesOrDie(sizeof(uint8_t))); |
| |
| // A copy of reader1 should reflect the byte already read. |
| MemoryReader reader2 = reader1; |
| EXPECT_EQ(buffer[1], *reader2.GetBytesOrDie(sizeof(uint8_t))); |
| |
| // reader1 should _not_ reflect the additional read on reader2. |
| EXPECT_GT(reader1.size(), reader2.size()); |
| } |
| |
| TEST(MemoryReaderTest, CopyConstructionWorks) { |
| constexpr std::array<uint8_t, 3> buffer{{1, 2, 3}}; |
| |
| MemoryReader reader1{buffer.data(), buffer.size()}; |
| EXPECT_EQ(buffer[0], *reader1.GetBytesOrDie(sizeof(uint8_t))); |
| |
| // A copy of reader1 should reflect the byte already read. |
| MemoryReader reader2(reader1); |
| EXPECT_EQ(buffer[1], *reader2.GetBytesOrDie(sizeof(uint8_t))); |
| |
| // reader1 should _not_ reflect the additional read on reader2. |
| EXPECT_GT(reader1.size(), reader2.size()); |
| } |
| |
| TEST(MemoryReaderTest, CopyOutOrDieCopiesData) { |
| constexpr struct Message { |
| int a; |
| char b; |
| } original_message{5, 'c'}; |
| const auto& duplicate_message = |
| MemoryReader(&original_message, sizeof(original_message)) |
| .CopyOutOrDie<Message>(); |
| EXPECT_EQ(original_message.a, duplicate_message.a); |
| EXPECT_EQ(original_message.b, duplicate_message.b); |
| } |
| |
| TEST(MemoryReaderTest, CopyOutOrDieWorksForMultipleObjects) { |
| constexpr struct M1 { |
| int a; |
| char b; |
| } first_message{1, 'a'}; |
| constexpr struct M2 { |
| uint64_t a; |
| uint64_t b; |
| } second_message{0, GetMaxVal(second_message.b)}; |
| const auto& buf = ByteBuffer<sizeof(first_message) + sizeof(second_message)>() |
| .AppendOrDie(&first_message, sizeof(first_message)) |
| .AppendOrDie(&second_message, sizeof(second_message)); |
| |
| MemoryReader memory_reader(buf.data(), buf.size()); |
| const auto& copy_of_first_message = memory_reader.CopyOutOrDie<M1>(); |
| const auto& copy_of_second_message = memory_reader.CopyOutOrDie<M2>(); |
| EXPECT_EQ(first_message.a, copy_of_first_message.a); |
| EXPECT_EQ(first_message.b, copy_of_first_message.b); |
| EXPECT_EQ(second_message.a, copy_of_second_message.a); |
| EXPECT_EQ(second_message.b, copy_of_second_message.b); |
| } |
| |
| TEST(MemoryReaderTest, GetBytesOrDieSucceedsOnSmallRead) { |
| constexpr std::array<uint8_t, 1024> buffer{}; |
| MemoryReader memory_reader(buffer.data(), buffer.size()); |
| EXPECT_EQ(buffer.data(), memory_reader.GetBytesOrDie(1)); |
| } |
| |
| TEST(MemoryReaderTest, GetBytesOrDieSucceedsOnFullRead) { |
| constexpr std::array<uint8_t, 1024> buffer{}; |
| MemoryReader memory_reader(buffer.data(), buffer.size()); |
| EXPECT_EQ(buffer.data(), memory_reader.GetBytesOrDie(buffer.size())); |
| } |
| |
| TEST(MemoryReaderTest, GetBytesOrDieCanConsumeFullBufferInParts) { |
| constexpr std::array<uint8_t, 1024> buffer{}; |
| static_assert(buffer.size() % 2 == 0, "Test will not consume whole buffer"); |
| MemoryReader memory_reader(buffer.data(), buffer.size()); |
| EXPECT_EQ(buffer.data(), memory_reader.GetBytesOrDie(buffer.size() / 2)); |
| EXPECT_EQ(buffer.data() + buffer.size() / 2, |
| memory_reader.GetBytesOrDie(buffer.size() / 2)); |
| } |
| |
| TEST(MemoryReaderTest, SizeIsCorrectForNonEmptyBuffer) { |
| constexpr std::array<uint8_t, 1> buffer{}; |
| MemoryReader memory_reader(buffer.data(), buffer.size()); |
| EXPECT_EQ(buffer.size(), memory_reader.size()); |
| } |
| |
| TEST(MemoryReaderTest, SizeIsCorrectForEmptyBuffer) { |
| constexpr std::array<uint8_t, 0> buffer{}; |
| MemoryReader memory_reader(buffer.data(), buffer.size()); |
| EXPECT_EQ(buffer.size(), memory_reader.size()); |
| } |
| |
| TEST(MemoryReaderTest, SizeIsCorrectAfterSmallRead) { |
| constexpr std::array<uint8_t, 1024> buffer{}; |
| MemoryReader memory_reader(buffer.data(), buffer.size()); |
| memory_reader.GetBytesOrDie(1); |
| EXPECT_EQ(buffer.size() - 1, memory_reader.size()); |
| } |
| |
| TEST(MemoryReaderTest, SizeIsCorrectAfterFullRead) { |
| constexpr std::array<uint8_t, 1024> buffer{}; |
| MemoryReader memory_reader(buffer.data(), buffer.size()); |
| memory_reader.GetBytesOrDie(buffer.size()); |
| EXPECT_EQ(0U, memory_reader.size()); |
| } |
| |
| TEST(MemoryReaderTest, SizeIsZeroForNullBuffer) { |
| MemoryReader memory_reader(nullptr, 0); |
| EXPECT_EQ(0U, memory_reader.size()); |
| } |
| |
| // Per |
| // github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#death-tests, |
| // death tests should be specially named. |
| |
| TEST(MemoryReaderDeathTest, CopyOutOrDieWithNullBufferCausesDeath) { |
| constexpr struct Message { |
| int a; |
| char b; |
| } original{5, 'c'}; |
| EXPECT_DEATH(MemoryReader(nullptr, sizeof(original)).CopyOutOrDie<Message>(), |
| "Check failed"); |
| } |
| |
| TEST(MemoryReaderDeathTest, CopyOutOrDieWithShortBufferCausesDeath) { |
| constexpr struct Message { |
| int a; |
| char b; |
| } original{5, 'c'}; |
| EXPECT_DEATH( |
| MemoryReader(&original, sizeof(original) - 1).CopyOutOrDie<Message>(), |
| "Check failed"); |
| } |
| |
| TEST(MemoryReaderDeathTest, CopyOutOrDieOverrunWithMultipleReadsCausesDeath) { |
| constexpr struct Message { |
| int a; |
| char b; |
| } message{5, 'c'}; |
| MemoryReader memory_reader(&message, sizeof(message)); |
| memory_reader.CopyOutOrDie<Message>(); |
| EXPECT_DEATH(memory_reader.CopyOutOrDie<Message>(), "Check failed"); |
| } |
| |
| TEST(MemoryReaderTest, GetBytesOrDieWithNullBufferCausesDeath) { |
| constexpr std::array<uint8_t, 1024> buffer{}; |
| MemoryReader memory_reader(nullptr, buffer.size()); |
| EXPECT_DEATH(memory_reader.GetBytesOrDie(buffer.size()), "Check failed"); |
| } |
| |
| TEST(MemoryReaderTest, GetBytesOrDieWithShortBufferCausesDeath) { |
| constexpr std::array<uint8_t, 1024> buffer{}; |
| MemoryReader memory_reader(buffer.data(), buffer.size()); |
| EXPECT_DEATH(memory_reader.GetBytesOrDie(buffer.size() + 1), "Check failed"); |
| } |
| |
| TEST(MemoryReaderTest, GetBytesOrDieOverrunWithMultipleReadsCausesDeath) { |
| constexpr std::array<uint8_t, 1024> buffer{}; |
| MemoryReader memory_reader(buffer.data(), buffer.size()); |
| EXPECT_EQ(buffer.data(), memory_reader.GetBytesOrDie(buffer.size())); |
| EXPECT_DEATH(memory_reader.GetBytesOrDie(1), "Check failed"); |
| } |
| |
| } // namespace wifilogd |
| } // namespace android |