| // Copyright 2023 The Centipede Authors. |
| // |
| // 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 |
| // |
| // https://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 "./centipede/execution_metadata.h" |
| |
| #include <vector> |
| |
| #include "gmock/gmock.h" |
| #include "gtest/gtest.h" |
| |
| namespace centipede { |
| namespace { |
| |
| using ::testing::IsEmpty; |
| using ::testing::UnorderedElementsAreArray; |
| |
| TEST(ExecutionMetadata, ForEachCmpEntryEnumeratesEntriesInRawBytes) { |
| ExecutionMetadata metadata{.cmp_data = { |
| 2, // size |
| 1, 2, // a |
| 3, 4, // b |
| 0, // zero-sized entry |
| 3, // size |
| 5, 6, 7, // a |
| 8, 9, 10, // b |
| }}; |
| std::vector<std::pair<ByteSpan, ByteSpan>> enumeration_result; |
| EXPECT_TRUE(metadata.ForEachCmpEntry( |
| [&](ByteSpan a, ByteSpan b) { enumeration_result.emplace_back(a, b); })); |
| |
| EXPECT_THAT( |
| enumeration_result, |
| UnorderedElementsAreArray(std::vector<std::pair<ByteSpan, ByteSpan>>{ |
| {{1, 2}, {3, 4}}, |
| {{}, {}}, |
| {{5, 6, 7}, {8, 9, 10}}, |
| })); |
| } |
| |
| TEST(ExecutionMetadata, ForEachCmpEntryHandlesEmptyCmpData) { |
| auto noop_callback = [](ByteSpan, ByteSpan) {}; |
| EXPECT_TRUE(ExecutionMetadata{.cmp_data = {}}.ForEachCmpEntry(noop_callback)); |
| } |
| |
| TEST(ExecutionMetadata, |
| ForEachCmpEntryReturnsFalseOnCmpDataWithNotEnoughBytes) { |
| auto noop_callback = [](ByteSpan, ByteSpan) {}; |
| const auto bad_metadata_1 = ExecutionMetadata{.cmp_data = {3, 1, 2, 3}}; |
| EXPECT_FALSE(bad_metadata_1.ForEachCmpEntry(noop_callback)); |
| const auto bad_metadata_2 = ExecutionMetadata{.cmp_data = {3, 1, 2, 3, 4, 5}}; |
| EXPECT_FALSE(bad_metadata_2.ForEachCmpEntry(noop_callback)); |
| } |
| |
| TEST(ExecutionMetadata, ForEachCmpEntryEnumeratesEntriesFromAppendCmpEntry) { |
| ExecutionMetadata metadata; |
| ASSERT_TRUE(metadata.AppendCmpEntry({1, 2}, {3, 4})); |
| std::vector<std::pair<ByteSpan, ByteSpan>> enumeration_result; |
| EXPECT_TRUE(metadata.ForEachCmpEntry( |
| [&](ByteSpan a, ByteSpan b) { enumeration_result.emplace_back(a, b); })); |
| EXPECT_THAT( |
| enumeration_result, |
| UnorderedElementsAreArray(std::vector<std::pair<ByteSpan, ByteSpan>>{ |
| {{1, 2}, {3, 4}}, |
| })); |
| } |
| |
| TEST(ExecutionMetadata, AppendCmpEntryReturnsFalseAndSkipsOnBadArgs) { |
| ExecutionMetadata metadata; |
| // Sizes don't match. |
| EXPECT_FALSE(metadata.AppendCmpEntry({}, {1})); |
| ByteArray long_byte_array; |
| long_byte_array.resize(256); |
| // Args too long. |
| EXPECT_FALSE(metadata.AppendCmpEntry(long_byte_array, long_byte_array)); |
| // Should leave no entries and keep metadata well-formed. |
| std::vector<std::pair<ByteSpan, ByteSpan>> enumeration_result; |
| EXPECT_TRUE(metadata.ForEachCmpEntry( |
| [&](ByteSpan a, ByteSpan b) { enumeration_result.emplace_back(a, b); })); |
| EXPECT_THAT(enumeration_result, IsEmpty()); |
| } |
| |
| TEST(ExecutionMetadata, ReadAndWriteKeepsCmpEntries) { |
| ExecutionMetadata metadata_in; |
| ASSERT_TRUE(metadata_in.AppendCmpEntry({1, 2}, {3, 4})); |
| SharedMemoryBlobSequence blobseq("test", /*size=*/1024, |
| /*use_posix_shmem=*/false); |
| EXPECT_TRUE(metadata_in.Write(/*tag=*/1, blobseq)); |
| blobseq.Reset(); |
| Blob blob = blobseq.Read(); |
| ExecutionMetadata metadata_out; |
| metadata_out.Read(blob); |
| std::vector<std::pair<ByteSpan, ByteSpan>> enumeration_result; |
| EXPECT_TRUE(metadata_out.ForEachCmpEntry( |
| [&](ByteSpan a, ByteSpan b) { enumeration_result.emplace_back(a, b); })); |
| EXPECT_THAT( |
| enumeration_result, |
| UnorderedElementsAreArray(std::vector<std::pair<ByteSpan, ByteSpan>>{ |
| {{1, 2}, {3, 4}}, |
| })); |
| } |
| |
| } // namespace |
| } // namespace centipede |