blob: 8057ddf094b7db4eb0d1ac4ebb173eef5a186f82 [file]
// Copyright 2021 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.
#ifndef ZIRCON_SYSTEM_ULIB_ZBITL_TEST_BOOTFS_TESTS_H_
#define ZIRCON_SYSTEM_ULIB_ZBITL_TEST_BOOTFS_TESTS_H_
#include <lib/zbitl/items/bootfs.h>
#include <lib/zbitl/view.h>
#include <iterator>
#include <fbl/unique_fd.h>
#include <gtest/gtest.h>
#include "array-tests.h"
#include "fd-tests.h"
#include "src/lib/files/scoped_temp_dir.h"
#include "tests.h"
template <typename TestTraits>
void TestBootfsIteration() {
using namespace std::string_view_literals;
using Storage = typename TestTraits::storage_type;
files::ScopedTempDir dir;
fbl::unique_fd fd;
size_t size = 0;
ASSERT_NO_FATAL_FAILURE(OpenTestDataZbi(TestDataZbiType::kBootfs, dir.path(), &fd, &size));
// Read the ZBI containing the BOOTFS into memory.
typename FblByteArrayTestTraits::Context zbi_context;
ASSERT_NO_FATAL_FAILURE(FblByteArrayTestTraits::Create(std::move(fd), size, &zbi_context));
zbitl::View view(zbi_context.TakeStorage());
auto it = view.begin();
ASSERT_EQ(std::next(it), view.end()) << "expected a single BOOTFS item";
ASSERT_EQ(uint32_t{ZBI_TYPE_STORAGE_BOOTFS}, it->header->type);
// Ultimately we want to create an object of storage_type containing the
// BOOTFS - and the preferred choice of test traits for creating storage
// objects with prescribed contents is to use a fbl::unique_fd. Accordingly,
// we decompress the BOOTFS into this form.
const uint32_t bootfs_size = zbitl::UncompressedLength(*it->header);
typename FdTestTraits::Context decompressed_context;
ASSERT_NO_FATAL_FAILURE(FdTestTraits::Create(bootfs_size, &decompressed_context));
fbl::unique_fd bootfs_fd = decompressed_context.TakeStorage();
{
auto result = view.CopyStorageItem(bootfs_fd, it);
ASSERT_FALSE(result.is_error()) << ViewCopyErrorString(result.error_value());
}
typename TestTraits::Context bootfs_context;
ASSERT_NO_FATAL_FAILURE(TestTraits::Create(std::move(bootfs_fd), bootfs_size, &bootfs_context));
zbitl::BootfsView<Storage> bootfs;
{
auto result = zbitl::BootfsView<Storage>::Create(bootfs_context.TakeStorage());
ASSERT_FALSE(result.is_error()) << BootfsErrorString(result.error_value());
bootfs = std::move(result.value());
}
auto test_find = [&bootfs](auto expected_it, std::string_view filename,
std::string_view dirname = {}) {
auto match = bootfs.find(filename, dirname);
auto result = bootfs.take_error();
ASSERT_FALSE(result.is_error()) << BootfsErrorString(result.error_value());
EXPECT_EQ(expected_it, match);
};
uint32_t idx = 0;
for (auto it = bootfs.begin(); it != bootfs.end(); ++it) {
Bytes contents;
ASSERT_NO_FATAL_FAILURE(TestTraits::Read(bootfs.storage(), it->data, it->size, &contents));
switch (idx) {
case 0:
EXPECT_EQ(it->name, "A.txt"sv);
EXPECT_EQ(contents,
"Four score and seven years ago our fathers brought forth on this "
"continent, a new nation, conceived in Liberty, and dedicated to the "
"proposition that all men are created equal.");
break;
case 1:
EXPECT_EQ(it->name, "nested/B.txt"sv);
ASSERT_NO_FATAL_FAILURE(test_find(it, /*filename=*/"B.txt", /*dirname=*/"nested"));
EXPECT_EQ(contents,
"Now we are engaged in a great civil war, testing whether that nation, "
"or any nation so conceived and so dedicated, can long endure.");
break;
case 2:
EXPECT_EQ(it->name, "nested/again/C.txt"sv);
ASSERT_NO_FATAL_FAILURE(test_find(it, /*filename=*/"again/C.txt", /*dirname=*/"nested"));
ASSERT_NO_FATAL_FAILURE(test_find(it, /*filename=*/"C.txt", /*dirname=*/"nested/again"));
EXPECT_EQ(contents, "We are met on a great battle-field of that war.");
break;
default:
__UNREACHABLE;
}
ASSERT_NO_FATAL_FAILURE(test_find(it, it->name, /*dirname=*/{}));
ASSERT_NO_FATAL_FAILURE(test_find(it, it->name, /*dirname=*/""));
++idx;
}
EXPECT_EQ(3u, idx) << "we expect three files in the BOOTFS";
{
auto result = view.take_error();
EXPECT_FALSE(result.is_error()) << ViewErrorString(result.error_value());
}
{
auto result = bootfs.take_error();
EXPECT_FALSE(result.is_error()) << BootfsErrorString(result.error_value());
}
}
#endif // ZIRCON_SYSTEM_ULIB_ZBITL_TEST_BOOTFS_TESTS_H_