blob: 2a56740917bb03d8e891e615e0d25817717be67c [file] [log] [blame]
Brian Silvermanf59fe3f2020-09-22 21:04:09 -07001#include "aos/events/logging/lzma_encoder.h"
2
3#include "aos/events/logging/buffer_encoder_param_test.h"
Austin Schuh3bd4c402020-11-06 18:19:06 -08004#include "aos/util/file.h"
5#include "gmock/gmock.h"
Brian Silvermanf59fe3f2020-09-22 21:04:09 -07006#include "gtest/gtest.h"
7
8namespace aos::logger::testing {
9
10INSTANTIATE_TEST_CASE_P(
11 Lzma, BufferEncoderTest,
12 ::testing::Combine(::testing::Values([]() {
13 return std::make_unique<LzmaEncoder>(2);
14 }),
15 ::testing::Values([](std::string_view filename) {
16 return std::make_unique<LzmaDecoder>(filename);
17 }),
18 ::testing::Range(0, 100)));
19
Austin Schuh3bd4c402020-11-06 18:19:06 -080020// Tests that we return as much of the file as we can read if the end is
21// corrupted.
22TEST_F(BufferEncoderBaseTest, CorruptedBuffer) {
23 std::uniform_int_distribution<int> quantity_distribution(20, 60);
24 const char *const test_dir = CHECK_NOTNULL(getenv("TEST_TMPDIR"));
25 const std::string file_path = std::string(test_dir) + "/foo";
26
27 std::vector<std::vector<uint8_t>> encoded_buffers;
28 {
29 const int encode_chunks = quantity_distribution(*random_number_generator());
30 const auto encoder = std::make_unique<LzmaEncoder>(2);
31 encoded_buffers = CreateAndEncode(encode_chunks, encoder.get());
32 encoder->Finish();
33
34 std::string contents = "";
35 for (auto span : encoder->queue()) {
36 absl::StrAppend(
37 &contents,
38 std::string_view(reinterpret_cast<const char *>(span.data()),
39 span.size()));
40 }
41 aos::util::WriteStringToFileOrDie(
42 file_path, contents.substr(0, contents.size() - 200));
43 }
44
45 const size_t total_encoded_size = TotalSize(encoded_buffers);
46
47 // Try decoding in multiple random chunkings.
48 for (int i = 0; i < 20; ++i) {
49 const auto decoder = std::make_unique<LzmaDecoder>(file_path);
50 std::vector<std::vector<uint8_t>> decoded_buffers;
51 size_t total_decoded_size = 0;
52 while (true) {
53 const int chunk_size = quantity_distribution(*random_number_generator());
54 std::vector<uint8_t> chunk(chunk_size);
55 const size_t read_result =
56 decoder->Read(chunk.data(), chunk.data() + chunk_size);
57 // Eventually we'll get here, once the decoder is really sure it's done.
58 if (read_result == 0) {
59 // Sanity check the math in the test code.
60 LOG(INFO) << "Decoded " << total_decoded_size << " encoded "
61 << total_encoded_size;
62 CHECK_EQ(total_decoded_size, TotalSize(decoded_buffers));
63 break;
64 }
65 // If we're at the end, trim off the 0s so our comparison later works out.
66 chunk.resize(read_result);
67 total_decoded_size += read_result;
68 decoded_buffers.emplace_back(std::move(chunk));
69 }
70 auto flattened_encoded = Flatten(encoded_buffers);
71 auto flattened_decoded = Flatten(decoded_buffers);
72
73 ASSERT_LE(flattened_decoded.size(), flattened_encoded.size());
74 flattened_encoded.resize(flattened_decoded.size());
75
76 ASSERT_THAT(flattened_decoded, ::testing::Eq(flattened_encoded));
77 }
78}
79
Brian Silvermanf59fe3f2020-09-22 21:04:09 -070080} // namespace aos::logger::testing