blob: 3bc360f5c247e322fe10018887909289d076fae8 [file] [log] [blame]
// Copyright 2020 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/fdio/spawn.h>
#include <lib/zx/process.h>
#include <zircon/device/block.h>
#include <fbl/unique_fd.h>
#include <fs-management/format.h>
#include <fs-management/launch.h>
#include <fs-management/mount.h>
#include <gtest/gtest.h>
#include "src/lib/isolated_devmgr/v2_component/ram_disk.h"
namespace factoryfs {
namespace {
TEST(FactoryFs, ExportedFilesystemIsMountable) {
constexpr int kDeviceBlockSize = 4096;
constexpr int kBlockCount = 1024;
auto ram_disk_or = isolated_devmgr::RamDisk::Create(kDeviceBlockSize, kBlockCount);
ASSERT_TRUE(ram_disk_or.is_ok()) << ram_disk_or.status_string();
char factoryfs_c_str[] = "/tmp/factoryfs.XXXXXX";
ASSERT_NE(mkdtemp(factoryfs_c_str), nullptr);
const std::string factoryfs(factoryfs_c_str);
const std::string hello = factoryfs + "/hello";
const std::string foo = factoryfs + "/foo";
const std::string bar = factoryfs + "/foo/bar";
fbl::unique_fd fd(open(hello.c_str(), O_CREAT | O_RDWR, 0777));
ASSERT_TRUE(fd) << errno;
ASSERT_EQ(write(fd.get(), "world", 5), 5);
ASSERT_EQ(mkdir(foo.c_str(), 0777), 0);
fd.reset(open(bar.c_str(), O_CREAT | O_RDWR, 0777));
ASSERT_TRUE(fd);
ASSERT_EQ(write(fd.get(), "bar", 3), 3);
fd.reset();
std::string ram_disk_path = ram_disk_or.value().path();
const char *argv[] = {"/pkg/bin/export_ffs", factoryfs.c_str(), ram_disk_path.c_str(), nullptr};
zx::process process;
zx_status_t status = fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, argv[0], argv,
process.reset_and_get_address());
ASSERT_EQ(status, ZX_OK);
status = process.wait_one(ZX_PROCESS_TERMINATED, zx::time::infinite(), nullptr);
ASSERT_EQ(status, ZX_OK);
// Clean up.
EXPECT_EQ(unlink(hello.c_str()), 0) << errno;
EXPECT_EQ(unlink(bar.c_str()), 0) << errno;
EXPECT_EQ(rmdir(foo.c_str()), 0) << errno;
// Now try and mount Factoryfs.
ASSERT_EQ(ramdisk_set_flags(ram_disk_or.value().client(), BLOCK_FLAG_READONLY), ZX_OK);
fd.reset(open(ram_disk_path.c_str(), O_RDONLY));
ASSERT_TRUE(fd) << errno;
mount_options_t options = default_mount_options;
options.register_fs = false;
status =
mount(fd.release(), factoryfs_c_str, DISK_FORMAT_FACTORYFS, &options, launch_stdio_async);
EXPECT_EQ(status, ZX_OK);
// And check contents of factoryfs.
fd.reset(open(hello.c_str(), O_RDONLY));
ASSERT_TRUE(fd) << errno;
char buf[11];
EXPECT_EQ(read(fd.get(), buf, sizeof(buf)), 5);
EXPECT_EQ(memcmp(buf, "world", 5), 0);
fd.reset(open(bar.c_str(), O_RDONLY));
ASSERT_TRUE(fd) << errno;
EXPECT_EQ(read(fd.get(), buf, sizeof(buf)), 3) << errno;
EXPECT_EQ(memcmp(buf, "bar", 3), 0);
}
} // namespace
} // namespace factoryfs