blob: a7d6d352e186e6ae3b8e12f14459e53da057721e [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/zxdump/types.h>
#include <gtest/gtest.h>
#include "dump-file.h"
#include "test-file.h"
#include "test-tool-process.h"
namespace {
using namespace std::literals;
TEST(ZxdumpTests, DumpFileBadOpen) {
auto result = zxdump::internal::DumpFile::Open({});
EXPECT_TRUE(result.is_error());
}
TEST(ZxdumpTests, DumpFileMmap) {
const std::string test_data = "test data";
zxdump::testing::TestFile test_file;
fputs(test_data.c_str(), test_file.stdio());
auto file = zxdump::internal::DumpFile::Open(test_file.RewoundFd(), true);
ASSERT_TRUE(file.is_ok()) << file.error_value();
EXPECT_EQ(file->size(), test_data.size());
EXPECT_EQ(file->size_bytes(), test_data.size());
auto bytes = file->ReadEphemeral({0, test_data.size()});
ASSERT_TRUE(bytes.is_ok()) << bytes.error_value();
std::string_view str{
reinterpret_cast<const char*>(bytes->data()),
bytes->size(),
};
EXPECT_EQ(str, test_data);
}
TEST(ZxdumpTests, DumpFileStdio) {
const std::string test_data = "test data";
zxdump::testing::TestFile test_file;
fputs(test_data.c_str(), test_file.stdio());
auto file = zxdump::internal::DumpFile::Open(test_file.RewoundFd(), false);
ASSERT_TRUE(file.is_ok()) << file.error_value();
EXPECT_EQ(file->size(), test_data.size());
EXPECT_EQ(file->size_bytes(), test_data.size());
auto bytes = file->ReadEphemeral({0, test_data.size()});
ASSERT_TRUE(bytes.is_ok()) << bytes.error_value();
std::string_view str{
reinterpret_cast<const char*>(bytes->data()),
bytes->size(),
};
EXPECT_EQ(str, test_data);
}
TEST(ZxdumpTests, DumpFilePipe) {
const std::string test_data = "test data";
int pipefd[2];
ASSERT_EQ(pipe(pipefd), 0) << strerror(errno);
fbl::unique_fd in(pipefd[0]);
{
FILE* outf = fdopen(pipefd[1], "w");
ASSERT_TRUE(outf) << strerror(errno);
fputs(test_data.c_str(), outf);
fclose(outf);
}
auto file = zxdump::internal::DumpFile::Open(std::move(in));
ASSERT_TRUE(file.is_ok()) << file.error_value();
EXPECT_EQ(file->size(), std::numeric_limits<size_t>::max());
EXPECT_EQ(file->size_bytes(), std::numeric_limits<size_t>::max());
// Even though it's not seekable, we can re-read the last-read chunk.
for (int i = 0; i < 100; ++i) {
auto bytes = file->ReadEphemeral({0, test_data.size()});
ASSERT_TRUE(bytes.is_ok()) << bytes.error_value();
std::string_view str{
reinterpret_cast<const char*>(bytes->data()),
bytes->size(),
};
EXPECT_EQ(str, test_data);
}
}
TEST(ZxdumpTests, DumpFileZstd) {
constexpr std::string_view kTestData = "test data";
// Write a compressed file with the zstd tool.
zxdump::testing::TestToolProcess zstd;
ASSERT_NO_FATAL_FAILURE(zstd.Init());
zxdump::testing::TestToolProcess::File& zstd_file =
zstd.MakeFile("dump-file-zstd", zxdump::testing::TestToolProcess::File::kZstdSuffix);
std::vector<std::string> args({"-q"s, "-o"s, zstd_file.name()});
ASSERT_NO_FATAL_FAILURE(zstd.Start("zstd"s, args));
ASSERT_NO_FATAL_FAILURE(zstd.SendStdin(std::string(kTestData)));
int exit_status;
ASSERT_NO_FATAL_FAILURE(zstd.Finish(exit_status));
EXPECT_EQ(exit_status, EXIT_SUCCESS);
auto file = zxdump::internal::DumpFile::Open(zstd_file.OpenOutput());
ASSERT_TRUE(file.is_ok()) << zstd.FilePathForRunner(zstd_file) << ": " << file.error_value();
auto header = file->ReadEphemeral({0, zxdump::internal::kHeaderProbeSize});
ASSERT_TRUE(header.is_ok()) << header.error_value();
ASSERT_FALSE(header->empty());
ASSERT_TRUE(zxdump::internal::DumpFile::IsCompressed(*header));
auto decompressed = file->Decompress({0, file->size()}, *header);
ASSERT_TRUE(decompressed.is_ok()) << decompressed.error_value();
// The reported size is not really meaningful, since it's streaming input.
// But it's guaranteed to be nonzero.
EXPECT_GT(decompressed->size(), 0u);
EXPECT_GT(decompressed->size_bytes(), 0u);
auto bytes = decompressed->ReadEphemeral({0, kTestData.size()});
ASSERT_TRUE(bytes.is_ok()) << bytes.error_value();
std::string_view str{
reinterpret_cast<const char*>(bytes->data()),
bytes->size(),
};
EXPECT_EQ(str, kTestData);
}
} // namespace