blob: e765bd931be70173cef2a5a8b95a7efc38b5600f [file] [log] [blame]
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright OpenBMC Authors
#ifdef HAVE_ZSTD
#include "zstd_decompressor.hpp"
#include <boost/asio/buffer.hpp>
#include <algorithm>
#include <array>
#include <cstddef>
#include <optional>
#include <span>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
using ::testing::Each;
using ::testing::Eq;
namespace zstd
{
namespace
{
TEST(Zstd, EmptyFile)
{
std::array<unsigned char, 13> empty{0x28, 0xb5, 0x2f, 0xfd, 0x24,
0x00, 0x01, 0x00, 0x00, 0x99,
0xe9, 0xd8, 0x51};
ZstdDecompressor comp;
std::optional<boost::asio::const_buffer> out =
comp.decompress(boost::asio::buffer(empty));
ASSERT_TRUE(out);
if (!out)
{
return;
}
EXPECT_TRUE(out->size() == 0);
}
TEST(Zstd, ZerosFile)
{
// A 1MB file of all zeros created using
// dd if=/dev/zero of=zeros-file bs=1024 count=1024
// zstd -c zeros-file | xxd -i
std::array<unsigned char, 54> zeros = {
0x28, 0xb5, 0x2f, 0xfd, 0xa4, 0x00, 0x00, 0x10, 0x00, 0x54, 0x00,
0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0xfb, 0xff, 0x39, 0xc0, 0x02,
0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x10,
0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00,
0x10, 0x00, 0x03, 0x00, 0x10, 0x00, 0xf1, 0x3e, 0x16, 0xe1};
for (size_t chunkSize :
std::to_array<size_t>({1U, 2U, 4U, 8U, 16U, zeros.size()}))
{
ZstdDecompressor comp;
std::span<unsigned char> data = std::span(zeros);
size_t read = 0;
while (!data.empty())
{
std::span<unsigned char> chunk =
data.subspan(0, std::min(chunkSize, data.size()));
std::optional<boost::asio::const_buffer> out = comp.decompress(
boost::asio::buffer(chunk.data(), chunk.size()));
ASSERT_TRUE(out);
if (out)
{
EXPECT_THAT(
std::span(static_cast<const unsigned char*>(out->data()),
out->size()),
Each(Eq(0)));
read += out->size();
}
data = data.subspan(chunk.size());
}
EXPECT_EQ(read, 1024 * 1024);
}
}
TEST(Zstd, OnesFile)
{
// A 1MB file of all ones created using
// dd if=/dev/zero bs=1024 count=1024 | tr "\000" "\377" > ones.txt
// zstd -c ones-file | xxd -i
std::array<unsigned char, 54> ones = {
0x28, 0xb5, 0x2f, 0xfd, 0xa4, 0x00, 0x00, 0x10, 0x00, 0x54, 0x00,
0x00, 0x10, 0xff, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x39, 0xc0, 0x02,
0x02, 0x00, 0x10, 0xff, 0x02, 0x00, 0x10, 0xff, 0x02, 0x00, 0x10,
0xff, 0x02, 0x00, 0x10, 0xff, 0x02, 0x00, 0x10, 0xff, 0x02, 0x00,
0x10, 0xff, 0x03, 0x00, 0x10, 0xff, 0xb4, 0xc8, 0xba, 0x13};
for (size_t chunkSize :
std::to_array<size_t>({1U, 2U, 4U, 8U, 16U, ones.size()}))
{
ZstdDecompressor comp;
std::span<unsigned char> data = std::span(ones);
size_t read = 0;
while (!data.empty())
{
std::span<unsigned char> chunk =
data.subspan(0, std::min(chunkSize, data.size()));
std::optional<boost::asio::const_buffer> out = comp.decompress(
boost::asio::buffer(chunk.data(), chunk.size()));
ASSERT_TRUE(out);
if (out)
{
EXPECT_THAT(
std::span(static_cast<const unsigned char*>(out->data()),
out->size()),
Each(Eq(0xFF)));
read += out->size();
}
data = data.subspan(chunk.size());
}
EXPECT_EQ(read, 1024 * 1024);
}
}
} // namespace
} // namespace zstd
#endif