/* * 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