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