Brian Silverman | f59fe3f | 2020-09-22 21:04:09 -0700 | [diff] [blame] | 1 | #include "aos/events/logging/lzma_encoder.h" |
| 2 | |
Austin Schuh | 3bd4c40 | 2020-11-06 18:19:06 -0800 | [diff] [blame] | 3 | #include "gmock/gmock.h" |
Brian Silverman | f59fe3f | 2020-09-22 21:04:09 -0700 | [diff] [blame] | 4 | #include "gtest/gtest.h" |
| 5 | |
Philipp Schrader | 790cb54 | 2023-07-05 21:06:52 -0700 | [diff] [blame] | 6 | #include "aos/events/logging/buffer_encoder_param_test.h" |
Austin Schuh | 6bdcc37 | 2024-06-27 14:49:11 -0700 | [diff] [blame] | 7 | #include "aos/testing/tmpdir.h" |
Philipp Schrader | 790cb54 | 2023-07-05 21:06:52 -0700 | [diff] [blame] | 8 | #include "aos/util/file.h" |
| 9 | |
Austin Schuh | be91b34 | 2022-06-27 00:53:45 -0700 | [diff] [blame] | 10 | DECLARE_int32(lzma_threads); |
| 11 | |
Brian Silverman | f59fe3f | 2020-09-22 21:04:09 -0700 | [diff] [blame] | 12 | namespace aos::logger::testing { |
| 13 | |
James Kuszmaul | f4bf9fe | 2021-05-10 22:58:24 -0700 | [diff] [blame] | 14 | INSTANTIATE_TEST_SUITE_P( |
Austin Schuh | be91b34 | 2022-06-27 00:53:45 -0700 | [diff] [blame] | 15 | MtLzma, BufferEncoderTest, |
Austin Schuh | 48d10d6 | 2022-10-16 22:19:23 -0700 | [diff] [blame] | 16 | ::testing::Combine(::testing::Values([](size_t max_message_size) { |
Austin Schuh | be91b34 | 2022-06-27 00:53:45 -0700 | [diff] [blame] | 17 | FLAGS_lzma_threads = 3; |
Austin Schuh | 48d10d6 | 2022-10-16 22:19:23 -0700 | [diff] [blame] | 18 | return std::make_unique<LzmaEncoder>(max_message_size, |
| 19 | 2, 4096); |
Austin Schuh | be91b34 | 2022-06-27 00:53:45 -0700 | [diff] [blame] | 20 | }), |
| 21 | ::testing::Values([](std::string_view filename) { |
| 22 | return std::make_unique<LzmaDecoder>(filename); |
| 23 | }), |
| 24 | ::testing::Range(0, 100))); |
| 25 | |
| 26 | INSTANTIATE_TEST_SUITE_P( |
| 27 | MtLzmaThreaded, BufferEncoderTest, |
Austin Schuh | 48d10d6 | 2022-10-16 22:19:23 -0700 | [diff] [blame] | 28 | ::testing::Combine(::testing::Values([](size_t max_message_size) { |
Austin Schuh | be91b34 | 2022-06-27 00:53:45 -0700 | [diff] [blame] | 29 | FLAGS_lzma_threads = 3; |
Austin Schuh | 48d10d6 | 2022-10-16 22:19:23 -0700 | [diff] [blame] | 30 | return std::make_unique<LzmaEncoder>(max_message_size, |
| 31 | 5, 4096); |
Austin Schuh | be91b34 | 2022-06-27 00:53:45 -0700 | [diff] [blame] | 32 | }), |
| 33 | ::testing::Values([](std::string_view filename) { |
| 34 | return std::make_unique<ThreadedLzmaDecoder>(filename); |
| 35 | }), |
| 36 | ::testing::Range(0, 100))); |
| 37 | |
| 38 | INSTANTIATE_TEST_SUITE_P( |
Brian Silverman | f59fe3f | 2020-09-22 21:04:09 -0700 | [diff] [blame] | 39 | Lzma, BufferEncoderTest, |
Austin Schuh | 48d10d6 | 2022-10-16 22:19:23 -0700 | [diff] [blame] | 40 | ::testing::Combine(::testing::Values([](size_t max_message_size) { |
Austin Schuh | be91b34 | 2022-06-27 00:53:45 -0700 | [diff] [blame] | 41 | FLAGS_lzma_threads = 1; |
Austin Schuh | 48d10d6 | 2022-10-16 22:19:23 -0700 | [diff] [blame] | 42 | return std::make_unique<LzmaEncoder>(max_message_size, |
| 43 | 2, 4096); |
Brian Silverman | f59fe3f | 2020-09-22 21:04:09 -0700 | [diff] [blame] | 44 | }), |
| 45 | ::testing::Values([](std::string_view filename) { |
| 46 | return std::make_unique<LzmaDecoder>(filename); |
| 47 | }), |
| 48 | ::testing::Range(0, 100))); |
| 49 | |
Tyler Chatow | 7df6083 | 2021-07-15 21:18:36 -0700 | [diff] [blame] | 50 | INSTANTIATE_TEST_SUITE_P( |
| 51 | LzmaThreaded, BufferEncoderTest, |
Austin Schuh | 48d10d6 | 2022-10-16 22:19:23 -0700 | [diff] [blame] | 52 | ::testing::Combine(::testing::Values([](size_t max_message_size) { |
Austin Schuh | be91b34 | 2022-06-27 00:53:45 -0700 | [diff] [blame] | 53 | FLAGS_lzma_threads = 1; |
Austin Schuh | 48d10d6 | 2022-10-16 22:19:23 -0700 | [diff] [blame] | 54 | return std::make_unique<LzmaEncoder>(max_message_size, |
| 55 | 5, 4096); |
Tyler Chatow | 7df6083 | 2021-07-15 21:18:36 -0700 | [diff] [blame] | 56 | }), |
| 57 | ::testing::Values([](std::string_view filename) { |
| 58 | return std::make_unique<ThreadedLzmaDecoder>(filename); |
| 59 | }), |
| 60 | ::testing::Range(0, 100))); |
| 61 | |
Austin Schuh | 3bd4c40 | 2020-11-06 18:19:06 -0800 | [diff] [blame] | 62 | // Tests that we return as much of the file as we can read if the end is |
| 63 | // corrupted. |
| 64 | TEST_F(BufferEncoderBaseTest, CorruptedBuffer) { |
| 65 | std::uniform_int_distribution<int> quantity_distribution(20, 60); |
Austin Schuh | 6bdcc37 | 2024-06-27 14:49:11 -0700 | [diff] [blame] | 66 | const std::string file_path = aos::testing::TestTmpDir() + "/foo"; |
Austin Schuh | 3bd4c40 | 2020-11-06 18:19:06 -0800 | [diff] [blame] | 67 | |
| 68 | std::vector<std::vector<uint8_t>> encoded_buffers; |
| 69 | { |
| 70 | const int encode_chunks = quantity_distribution(*random_number_generator()); |
Austin Schuh | 48d10d6 | 2022-10-16 22:19:23 -0700 | [diff] [blame] | 71 | const auto encoder = std::make_unique<LzmaEncoder>( |
| 72 | BufferEncoderBaseTest::kMaxMessageSize, 2); |
Austin Schuh | 3bd4c40 | 2020-11-06 18:19:06 -0800 | [diff] [blame] | 73 | encoded_buffers = CreateAndEncode(encode_chunks, encoder.get()); |
| 74 | encoder->Finish(); |
| 75 | |
| 76 | std::string contents = ""; |
| 77 | for (auto span : encoder->queue()) { |
| 78 | absl::StrAppend( |
| 79 | &contents, |
| 80 | std::string_view(reinterpret_cast<const char *>(span.data()), |
| 81 | span.size())); |
| 82 | } |
| 83 | aos::util::WriteStringToFileOrDie( |
| 84 | file_path, contents.substr(0, contents.size() - 200)); |
| 85 | } |
| 86 | |
| 87 | const size_t total_encoded_size = TotalSize(encoded_buffers); |
| 88 | |
| 89 | // Try decoding in multiple random chunkings. |
| 90 | for (int i = 0; i < 20; ++i) { |
| 91 | const auto decoder = std::make_unique<LzmaDecoder>(file_path); |
| 92 | std::vector<std::vector<uint8_t>> decoded_buffers; |
| 93 | size_t total_decoded_size = 0; |
| 94 | while (true) { |
| 95 | const int chunk_size = quantity_distribution(*random_number_generator()); |
| 96 | std::vector<uint8_t> chunk(chunk_size); |
| 97 | const size_t read_result = |
| 98 | decoder->Read(chunk.data(), chunk.data() + chunk_size); |
| 99 | // Eventually we'll get here, once the decoder is really sure it's done. |
| 100 | if (read_result == 0) { |
| 101 | // Sanity check the math in the test code. |
| 102 | LOG(INFO) << "Decoded " << total_decoded_size << " encoded " |
| 103 | << total_encoded_size; |
| 104 | CHECK_EQ(total_decoded_size, TotalSize(decoded_buffers)); |
| 105 | break; |
| 106 | } |
| 107 | // If we're at the end, trim off the 0s so our comparison later works out. |
| 108 | chunk.resize(read_result); |
| 109 | total_decoded_size += read_result; |
| 110 | decoded_buffers.emplace_back(std::move(chunk)); |
| 111 | } |
| 112 | auto flattened_encoded = Flatten(encoded_buffers); |
| 113 | auto flattened_decoded = Flatten(decoded_buffers); |
| 114 | |
| 115 | ASSERT_LE(flattened_decoded.size(), flattened_encoded.size()); |
| 116 | flattened_encoded.resize(flattened_decoded.size()); |
| 117 | |
| 118 | ASSERT_THAT(flattened_decoded, ::testing::Eq(flattened_encoded)); |
| 119 | } |
| 120 | } |
| 121 | |
Brian Silverman | f59fe3f | 2020-09-22 21:04:09 -0700 | [diff] [blame] | 122 | } // namespace aos::logger::testing |