blob: e765bd931be70173cef2a5a8b95a7efc38b5600f [file] [log] [blame]
Ed Tanousb2539062024-03-12 16:58:35 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
3#ifdef HAVE_ZSTD
4#include "zstd_decompressor.hpp"
5
6#include <boost/asio/buffer.hpp>
7
8#include <algorithm>
9#include <array>
10#include <cstddef>
11#include <optional>
12#include <span>
13
14#include <gmock/gmock.h>
15#include <gtest/gtest.h>
16
17using ::testing::Each;
18using ::testing::Eq;
19
20namespace zstd
21{
22namespace
23{
24
25TEST(Zstd, EmptyFile)
26{
27 std::array<unsigned char, 13> empty{0x28, 0xb5, 0x2f, 0xfd, 0x24,
28 0x00, 0x01, 0x00, 0x00, 0x99,
29 0xe9, 0xd8, 0x51};
30
31 ZstdDecompressor comp;
32 std::optional<boost::asio::const_buffer> out =
33 comp.decompress(boost::asio::buffer(empty));
34 ASSERT_TRUE(out);
35 if (!out)
36 {
37 return;
38 }
39 EXPECT_TRUE(out->size() == 0);
40}
41
42TEST(Zstd, ZerosFile)
43{
44 // A 1MB file of all zeros created using
45 // dd if=/dev/zero of=zeros-file bs=1024 count=1024
46 // zstd -c zeros-file | xxd -i
47 std::array<unsigned char, 54> zeros = {
48 0x28, 0xb5, 0x2f, 0xfd, 0xa4, 0x00, 0x00, 0x10, 0x00, 0x54, 0x00,
49 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0xfb, 0xff, 0x39, 0xc0, 0x02,
50 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x10,
51 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00,
52 0x10, 0x00, 0x03, 0x00, 0x10, 0x00, 0xf1, 0x3e, 0x16, 0xe1};
53
54 for (size_t chunkSize :
55 std::to_array<size_t>({1U, 2U, 4U, 8U, 16U, zeros.size()}))
56 {
57 ZstdDecompressor comp;
58 std::span<unsigned char> data = std::span(zeros);
59 size_t read = 0;
60 while (!data.empty())
61 {
62 std::span<unsigned char> chunk =
63 data.subspan(0, std::min(chunkSize, data.size()));
64 std::optional<boost::asio::const_buffer> out = comp.decompress(
65 boost::asio::buffer(chunk.data(), chunk.size()));
66 ASSERT_TRUE(out);
67 if (out)
68 {
69 EXPECT_THAT(
70 std::span(static_cast<const unsigned char*>(out->data()),
71 out->size()),
72 Each(Eq(0)));
73 read += out->size();
74 }
75 data = data.subspan(chunk.size());
76 }
77
78 EXPECT_EQ(read, 1024 * 1024);
79 }
80}
81
82TEST(Zstd, OnesFile)
83{
84 // A 1MB file of all ones created using
85 // dd if=/dev/zero bs=1024 count=1024 | tr "\000" "\377" > ones.txt
86 // zstd -c ones-file | xxd -i
87 std::array<unsigned char, 54> ones = {
88 0x28, 0xb5, 0x2f, 0xfd, 0xa4, 0x00, 0x00, 0x10, 0x00, 0x54, 0x00,
89 0x00, 0x10, 0xff, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x39, 0xc0, 0x02,
90 0x02, 0x00, 0x10, 0xff, 0x02, 0x00, 0x10, 0xff, 0x02, 0x00, 0x10,
91 0xff, 0x02, 0x00, 0x10, 0xff, 0x02, 0x00, 0x10, 0xff, 0x02, 0x00,
92 0x10, 0xff, 0x03, 0x00, 0x10, 0xff, 0xb4, 0xc8, 0xba, 0x13};
93
94 for (size_t chunkSize :
95 std::to_array<size_t>({1U, 2U, 4U, 8U, 16U, ones.size()}))
96 {
97 ZstdDecompressor comp;
98 std::span<unsigned char> data = std::span(ones);
99 size_t read = 0;
100 while (!data.empty())
101 {
102 std::span<unsigned char> chunk =
103 data.subspan(0, std::min(chunkSize, data.size()));
104 std::optional<boost::asio::const_buffer> out = comp.decompress(
105 boost::asio::buffer(chunk.data(), chunk.size()));
106 ASSERT_TRUE(out);
107 if (out)
108 {
109 EXPECT_THAT(
110 std::span(static_cast<const unsigned char*>(out->data()),
111 out->size()),
112 Each(Eq(0xFF)));
113 read += out->size();
114 }
115 data = data.subspan(chunk.size());
116 }
117
118 EXPECT_EQ(read, 1024 * 1024);
119 }
120}
121
122} // namespace
123} // namespace zstd
124#endif