blob: f7fc06095e0e5ff883cccd34dab46937e995e036 [file]
// Copyright 2026 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <lib/linux-initramfs/initramfs.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
namespace {
using namespace std::literals;
using ::testing::ElementsAre;
using ::testing::Pair;
constexpr std::string_view kTestImage =
"070701"sv // magic
"0CE447C8000041ED0002086000015F53000000026AB79FC9"sv
"00000000"sv // filesize
"000000FD000000010000000000000000"sv
"00000005"sv // namesize
"00000000"sv
"dir1\0\0"sv
"070701"sv // magic
"0CE447CA000081A40002086000015F53000000016AB79FC9"sv
"0000000E"sv // filesize
"000000FD000000010000000000000000"sv
"0000000B"sv // namesize
"00000000"sv
"dir1/file1\0\0\0\0"sv
"Hello, world!\n\0\0"sv
"070701"sv // magic
"0CE447C9000041ED0002086000015F53000000026AB79FD2"sv
"000000000"sv // filesize
"00000FD000000010000000000000000"sv
"00000005"sv // namesize
"00000000"sv
"dir2\0\0"sv
"070701"sv // magic
"0CE447CB000081A40002086000015F53000000016AB79FD2"sv
"0000000C"sv // filesize
"000000FD000000010000000000000000"sv
"0000000B"sv // namesize
"00000000"sv
"dir2/file2\0\0\0\0"sv
"Lorem ipsum\n"sv
"070701"sv // magic
"000000000000000000000000000000000000000100000000"sv
"00000000"sv // filesize
"00000000000000000000000000000000"sv
"0000000B"sv // namesize
"00000000"sv
"TRAILER!!!\0\0\0\0"sv;
static_assert(kTestImage.size() == 632);
constexpr std::string_view kTestImage2 =
"070701"sv // magic
"0CCA5C0D000081A40002086000015F53000000016ABB04CC"sv
"0000000D"sv // filesize
"000000FD000000010000000000000000"sv
"00000006"sv // namesize
"00000000file3\0"sv
"Hello again!\n\0\0\0"sv
"070701"sv // magic
"0CCA5C12000081A40002086000015F53000000016ABB04EA"sv
"0000000F"sv // filesize
"000000FD000000010000000000000000"sv
"00000006"sv // namesize
"00000000file4\0dolor sit amet\n\0"sv
"070701"sv // magic
"070701"sv // magic
"000000000000000000000000000000000000000100000000"sv
"00000000"sv // filesize
"00000000000000000000000000000000"sv
"0000000B"sv // namesize
"00000000"sv
"TRAILER!!!\0\0\0\0"sv;
TEST(InitramfsTests, Empty) {
linux_initramfs::Initramfs ctor; // Default constructed.
EXPECT_TRUE(ctor.empty());
linux_initramfs::Initramfs empty{std::span<std::byte>()};
EXPECT_TRUE(empty.empty());
ctor = empty;
EXPECT_TRUE(empty.empty());
}
TEST(InitramfsTests, Truncated) {
constexpr std::string_view kTrunacted = "0707010000000000";
linux_initramfs::Initramfs truncated(kTrunacted);
EXPECT_TRUE(truncated.empty());
}
TEST(InitramfsTests, Invalid) {
const std::string bogus(200, 'x');
linux_initramfs::Initramfs invalid(std::string_view{bogus});
EXPECT_TRUE(invalid.empty());
}
TEST(InitramfsTests, InvalidWithCorrectMagic) {
std::string bogus_with_magic = "070701";
bogus_with_magic.resize(200, 'x');
linux_initramfs::Initramfs magic_bogon(std::string_view{bogus_with_magic});
EXPECT_TRUE(magic_bogon.empty());
}
TEST(InitramfsTests, Iterate) {
constexpr auto as_str = [](const linux_initramfs::Member& member) {
return std::string_view{reinterpret_cast<const char*>(member.contents.data()),
member.contents.size_bytes()};
};
linux_initramfs::Initramfs fs{kTestImage};
EXPECT_FALSE(fs.empty());
std::vector members{std::from_range, fs};
ASSERT_EQ(members.size(), 4u);
EXPECT_EQ(members[0].size_bytes(), 116u);
EXPECT_EQ(members[0].name, "dir1");
EXPECT_EQ(members[0].contents.size_bytes(), 0u);
EXPECT_EQ(members[1].size_bytes(), 140u);
EXPECT_EQ(members[1].name, "dir1/file1");
EXPECT_EQ(as_str(members[1]), "Hello, world!\n");
EXPECT_EQ(members[2].name, "dir2");
EXPECT_EQ(members[2].size_bytes(), 116u);
EXPECT_EQ(members[2].contents.size_bytes(), 0u);
EXPECT_EQ(members[3].size_bytes(), 136u);
EXPECT_EQ(members[3].name, "dir2/file2");
EXPECT_EQ(as_str(members[3]), "Lorem ipsum\n");
}
TEST(InitramfsTests, Concatenate) {
std::string image(kTestImage);
static_assert(kTestImage.size() % 4 == 0);
image += kTestImage2;
linux_initramfs::Initramfs fs{image};
constexpr auto as_pair = [](const linux_initramfs::Member& member) {
return std::pair<std::string_view, std::string_view>{
member.name,
{
reinterpret_cast<const char*>(member.contents.data()),
member.contents.size(),
},
};
};
std::vector<std::pair<std::string_view, std::string_view>> members{
std::from_range, std::views::transform(fs, as_pair)};
EXPECT_THAT(members, ::testing::ElementsAre( //
Pair("dir1"sv, ""sv), //
Pair("dir1/file1"sv, "Hello, world!\n"sv), //
Pair("dir2"sv, ""sv), //
Pair("dir2/file2"sv, "Lorem ipsum\n"sv), //
Pair("file3"sv, "Hello again!\n"sv), //
Pair("file4"sv, "dolor sit amet\n"sv)));
}
} // namespace