// Copyright 2017 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 <assert.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <threads.h>
#include <utime.h>

#include <blobfs/format.h>
#include <blobfs/lz4.h>
#include <digest/digest.h>
#include <digest/merkle-tree.h>
#include <fbl/alloc_checker.h>
#include <fbl/atomic.h>
#include <fbl/auto_call.h>
#include <fbl/auto_lock.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/unique_fd.h>
#include <fbl/unique_ptr.h>
#include <fs-management/fvm.h>
#include <fs-management/mount.h>
#include <fs-management/ramdisk.h>
#include <fuchsia/io/c/fidl.h>
#include <fvm/fvm.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/fdio/io.h>
#include <lib/fzl/fdio.h>
#include <lib/memfs/memfs.h>
#include <unittest/unittest.h>
#include <zircon/device/device.h>
#include <zircon/device/ramdisk.h>
#include <zircon/device/vfs.h>
#include <zircon/syscalls.h>

#include "blobfs-test.h"

#define TMPFS_PATH "/blobfs-tmp"
#define MOUNT_PATH "/blobfs-tmp/zircon-blobfs-test"

namespace {
using digest::Digest;
using digest::MerkleTree;

// Indicates whether we should enable ramdisk failure tests for the current test run.
static bool gEnableRamdiskFailure = false;

// The maximum number of failure loops that should be tested. If set to 0, all of them will be run.
static uint64_t gRamdiskFailureLoops = 0;

// Information about the real disk which must be constructed at runtime, but which persists
// between tests.
static bool gUseRealDisk = false;
struct real_disk_info {
    uint64_t blk_size;
    uint64_t blk_count;
    char disk_path[PATH_MAX];
} gRealDiskInfo;

static bool gEnableOutput = true;

static_assert(fbl::is_pod<real_disk_info>::value, "Global variables should contain exclusively POD"
                                                  "data");

#define RUN_TEST_WRAPPER(test_size, test_name, test_type) \
    RUN_TEST_##test_size((TestWrapper<test_name, test_type>))

#define RUN_TEST_NORMAL(test_size, test_name) \
    RUN_TEST_WRAPPER(test_size, test_name, FsTestType::kNormal)

#define RUN_TEST_FVM(test_size, test_name) \
    RUN_TEST_WRAPPER(test_size, test_name, FsTestType::kFvm)

#define RUN_TESTS(test_size, test_name) \
    RUN_TEST_NORMAL(test_size, test_name) \
    RUN_TEST_FVM(test_size, test_name)

#define RUN_TESTS_SILENT(test_size, test_name) \
    gEnableOutput = false; \
    RUN_TESTS(test_size, test_name) \
    gEnableOutput = true;

// Defines a Blobfs test function which can be passed to the TestWrapper.
typedef bool (*TestFunction)(BlobfsTest* blobfsTest);

// Function which takes in print parameters and does nothing.
static void silent_printf(const char* line, int len, void* arg) {}

// A test wrapper which runs a Blobfs test. If the -f command line argument is used, the test will
// then be run the specified number of additional times, purposely causing the underlying ramdisk
// to fail at certain points.
template <TestFunction TestFunc, FsTestType TestType>
bool TestWrapper(void) {
    BEGIN_TEST;

    // Make sure that we are not testing ramdisk failures with a real disk.
    ASSERT_FALSE(gUseRealDisk && gEnableRamdiskFailure);

    BlobfsTest blobfsTest(TestType);
    blobfsTest.SetStdio(gEnableOutput);
    ASSERT_TRUE(blobfsTest.Init(), "Mounting Blobfs");

    if (gEnableRamdiskFailure) {
        // Sleep and re-wake the ramdisk to ensure that transaction counts have been reset.
        ASSERT_TRUE(blobfsTest.ToggleSleep());
        ASSERT_TRUE(blobfsTest.ToggleSleep());
    }

    // Run the test. This should pass.
    ASSERT_TRUE(TestFunc(&blobfsTest));

    // Get the total number of transactions required for this test.
    uint64_t block_count = 0;
    uint64_t interval = 1;
    uint64_t total = 0;

    if (gEnableRamdiskFailure) {
        // Based on the number of total blocks written and the user provided count of tests,
        // calculate the block interval to test with ramdisk failures.
        ASSERT_TRUE(blobfsTest.GetRamdiskCount(&block_count));

        if (gRamdiskFailureLoops && gRamdiskFailureLoops < block_count) {
            interval = block_count / gRamdiskFailureLoops;
        }
    }

    ASSERT_TRUE(blobfsTest.Teardown(), "Unmounting Blobfs");
    blobfsTest.SetStdio(false);

    // Run the test again, setting the ramdisk to fail after each |interval| blocks.
    for (uint64_t i = 1; i <= block_count; i += interval) {
        if (gRamdiskFailureLoops && total >= gRamdiskFailureLoops) {
            break;
        }

        printf("Running ramdisk failure test %" PRIu64 " / %" PRIu64
               " (block %" PRIu64 " / %" PRIu64 ")\n", total,
               gRamdiskFailureLoops ? gRamdiskFailureLoops : block_count, i, block_count);

        ASSERT_TRUE(blobfsTest.Reset());
        ASSERT_TRUE(blobfsTest.Init(), "Mounting Blobfs");
        ASSERT_TRUE(blobfsTest.ToggleSleep(i));

        // The following test run may fail, but since we don't care, silence any test output.
        unittest_set_output_function(silent_printf, nullptr);

        // We do not care whether the test itself fails or not - regardless, fsck should pass
        // (even if the most recent file system state has not been preserved).
        TestFunc(&blobfsTest);
        current_test_info->all_ok = true;

        ASSERT_TRUE(blobfsTest.ToggleSleep());

        // Restore the default output function.
        unittest_restore_output_function();

        // Forcibly unmount and remount the blobfs partition. With journaling enabled, any
        // inconsistencies should be resolved.
        ASSERT_TRUE(blobfsTest.ForceRemount());

        // The fsck check during Teardown should verify that journal replay was successful.
        ASSERT_TRUE(blobfsTest.Teardown(), "Unmounting Blobfs");

        total += 1;
    }

    END_TEST;
}

#define FVM_DRIVER_LIB "/boot/driver/fvm.so"
#define STRLEN(s) sizeof(s) / sizeof((s)[0])

// FVM slice size used for tests
constexpr size_t kTestFvmSliceSize = blobfs::kBlobfsBlockSize; // 8kb
// Minimum blobfs size required by CreateUmountRemountLargeMultithreaded test
constexpr size_t kBytesNormalMinimum = 5 * (1 << 20); // 5mb
// Minimum blobfs size required by ResizePartition test
constexpr size_t kSliceBytesFvmMinimum = 507 * kTestFvmSliceSize;
constexpr size_t kTotalBytesFvmMinimum = fvm::MetadataSize(kSliceBytesFvmMinimum,
                                         kTestFvmSliceSize) * 2 + kSliceBytesFvmMinimum; // ~8.5mb

constexpr uint8_t kTestUniqueGUID[] = {
    0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
constexpr uint8_t kTestPartGUID[] = {
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
};

constexpr size_t kBlocksPerSlice = kTestFvmSliceSize / blobfs::kBlobfsBlockSize;

const fsck_options_t test_fsck_options = {
    .verbose = false,
    .never_modify = true,
    .always_modify = false,
    .force = true,
};

BlobfsTest::~BlobfsTest() {
    switch (state_) {
    case FsTestState::kMinimal:
    case FsTestState::kRunning:
    case FsTestState::kError:
        EXPECT_EQ(Teardown(), 0);
        break;
    default:
        break;
    }
}

bool BlobfsTest::Init(FsTestState state) {
    BEGIN_HELPER;
    ASSERT_EQ(state_, FsTestState::kInit);
    auto error = fbl::MakeAutoCall([this](){ state_ = FsTestState::kError; });

    ASSERT_TRUE(mkdir(MOUNT_PATH, 0755) == 0 || errno == EEXIST,
                "Could not create mount point for test filesystems");

    if (gUseRealDisk) {
        strncpy(ramdisk_path_, gRealDiskInfo.disk_path, PATH_MAX);
        blk_size_ = gRealDiskInfo.blk_size;
        blk_count_ = gRealDiskInfo.blk_count;
    } else {
        ASSERT_EQ(create_ramdisk(blk_size_, blk_count_, ramdisk_path_), 0,
                  "Blobfs: Could not create ramdisk");
    }

    if (type_ == FsTestType::kFvm) {
        ASSERT_EQ(kTestFvmSliceSize % blobfs::kBlobfsBlockSize, 0);

        fbl::unique_fd fd(open(ramdisk_path_, O_RDWR));
        ASSERT_TRUE(fd, "[FAILED]: Could not open test disk");
        ASSERT_EQ(fvm_init(fd.get(), kTestFvmSliceSize), ZX_OK,
                  "[FAILED]: Could not format disk with FVM");
        ASSERT_GE(ioctl_device_bind(fd.get(), FVM_DRIVER_LIB, STRLEN(FVM_DRIVER_LIB)), 0,
                  "[FAILED]: Could not bind disk to FVM driver");

        snprintf(fvm_path_, sizeof(fvm_path_), "%s/fvm", ramdisk_path_);
        ASSERT_EQ(wait_for_device(fvm_path_, ZX_SEC(3)), ZX_OK,
                  "[FAILED]: FVM driver never appeared");
        fd.reset();

        // Open "fvm" driver.
        fbl::unique_fd fvm_fd(open(fvm_path_, O_RDWR));
        ASSERT_GE(fvm_fd.get(), 0, "[FAILED]: Could not open FVM driver");

        // Restore the "fvm_disk_path" to the ramdisk, so it can
        // be destroyed when the test completes.
        fvm_path_[strlen(fvm_path_) - strlen("/fvm")] = 0;

        alloc_req_t request;
        memset(&request, 0, sizeof(request));
        request.slice_count = 1;
        strcpy(request.name, "fs-test-partition");
        memcpy(request.type, kTestPartGUID, sizeof(request.type));
        memcpy(request.guid, kTestUniqueGUID, sizeof(request.guid));

        fd.reset(fvm_allocate_partition(fvm_fd.get(), &request));
        ASSERT_TRUE(fd, "[FAILED]: Could not allocate FVM partition");
        fvm_fd.reset();
        fd.reset(open_partition(kTestUniqueGUID, kTestPartGUID, 0, ramdisk_path_));
        ASSERT_TRUE(fd, "[FAILED]: Could not locate FVM partition");
        fd.reset();
    }

    if (state != FsTestState::kMinimal) {
        ASSERT_EQ(state, FsTestState::kRunning);
        ASSERT_EQ(mkfs(ramdisk_path_, DISK_FORMAT_BLOBFS, launch_stdio_sync, &default_mkfs_options),
                  ZX_OK);
        ASSERT_TRUE(Mount());
    }

    error.cancel();
    state_ = state;
    END_HELPER;
}

bool BlobfsTest::Remount() {
    BEGIN_HELPER;
    ASSERT_EQ(state_, FsTestState::kRunning);
    auto error = fbl::MakeAutoCall([this](){ state_ = FsTestState::kError; });
    ASSERT_EQ(umount(MOUNT_PATH), ZX_OK, "Failed to unmount blobfs");
    ASSERT_EQ(fsck(ramdisk_path_, DISK_FORMAT_BLOBFS, &test_fsck_options,
                   launch_stdio_sync), ZX_OK, "Filesystem fsck failed");
    ASSERT_TRUE(Mount(), "Failed to mount blobfs");
    error.cancel();
    END_HELPER;
}

bool BlobfsTest::ForceRemount() {
    BEGIN_HELPER;
    // Attempt to unmount, but do not check the result.
    // It is possible that the partition has already been unmounted.
    umount(MOUNT_PATH);
    ASSERT_TRUE(Mount());
    // In the event of success, set state to kRunning, regardless of whether the state was kMinimal
    // before. Since the partition is now mounted, we will need to umount/fsck on Teardown.
    state_ = FsTestState::kRunning;
    END_HELPER;
}

bool BlobfsTest::Teardown() {
    BEGIN_HELPER;
    ASSERT_NE(state_, FsTestState::kComplete);
    auto error = fbl::MakeAutoCall([this](){ state_ = FsTestState::kError; });

    if (state_ == FsTestState::kRunning) {
        ASSERT_EQ(state_, FsTestState::kRunning);
        ASSERT_TRUE(CheckInfo(MOUNT_PATH));
        ASSERT_EQ(umount(MOUNT_PATH), ZX_OK, "Failed to unmount filesystem");
        ASSERT_EQ(fsck(ramdisk_path_, DISK_FORMAT_BLOBFS, &test_fsck_options, launch_stdio_sync),
                  ZX_OK, "Filesystem fsck failed");
    }

    if (gUseRealDisk) {
        if (type_ == FsTestType::kFvm) {
            ASSERT_EQ(fvm_destroy(fvm_path_), ZX_OK);
        }
    } else {
        if (type_ == FsTestType::kFvm) {
            ASSERT_EQ(destroy_ramdisk(fvm_path_), 0);
        } else {
            ASSERT_EQ(destroy_ramdisk(ramdisk_path_), 0);
        }
    }

    error.cancel();
    state_ = FsTestState::kComplete;
    END_HELPER;
}

bool BlobfsTest::GetDevicePath(char* path, size_t len) const {
    BEGIN_HELPER;
    if (type_ == FsTestType::kFvm) {
        strlcpy(path, fvm_path_, len);
        strlcat(path, "/fvm", len);
        while (true) {
            DIR* dir = opendir(path);
            ASSERT_NONNULL(dir, "Unable to open FVM dir");

            struct dirent* dir_entry;
            bool updated = false;
            while ((dir_entry = readdir(dir)) != NULL) {
                if (strcmp(dir_entry->d_name, ".") == 0) {
                    continue;
                }

                updated = true;
                strlcat(path, "/", len);
                strlcat(path, dir_entry->d_name, len);
            }

            closedir(dir);

            if (!updated) {
                break;
            }
        }
    } else {
        strlcpy(path, ramdisk_path_, len);
    }
    END_HELPER;
}

bool BlobfsTest::ToggleSleep(uint64_t blk_count) {
    BEGIN_HELPER;

    if (asleep_) {
        // If the ramdisk is asleep, wake it up.
        if (type_ == FsTestType::kNormal) {
            ASSERT_EQ(wake_ramdisk(ramdisk_path_), 0);
        } else {
            ASSERT_EQ(wake_ramdisk(fvm_path_), 0);
        }
    } else {
        // If the ramdisk is active, put it to sleep after the specified block count.
        if (type_ == FsTestType::kNormal) {
            ASSERT_EQ(sleep_ramdisk(ramdisk_path_, blk_count), 0);
        } else {
            ASSERT_EQ(sleep_ramdisk(fvm_path_, blk_count), 0);
        }
    }

    asleep_ = !asleep_;
    END_HELPER;
}

bool BlobfsTest::GetRamdiskCount(uint64_t* blk_count) const {
    BEGIN_HELPER;
    ramdisk_blk_counts_t counts;

    switch (type_) {
    case FsTestType::kNormal:
        ASSERT_EQ(get_ramdisk_blocks(ramdisk_path_, &counts), 0);
        break;
    case FsTestType::kFvm:
        ASSERT_EQ(get_ramdisk_blocks(fvm_path_, &counts), 0);
        break;
    default:
        ASSERT_TRUE(false);
    }

    *blk_count = counts.received;
    END_HELPER;
}

bool BlobfsTest::CheckInfo(const char* mount_path) {
    fbl::unique_fd fd(open(mount_path, O_RDONLY | O_DIRECTORY));
    ASSERT_TRUE(fd);

    zx_status_t status;
    fuchsia_io_FilesystemInfo info;
    fzl::FdioCaller caller(fbl::move(fd));
    ASSERT_EQ(fuchsia_io_DirectoryAdminQueryFilesystem(caller.borrow_channel(), &status, &info),
              ZX_OK);
    ASSERT_EQ(status, ZX_OK);
    const char* kFsName = "blobfs";
    const char* name = reinterpret_cast<const char*>(info.name);
    ASSERT_EQ(strncmp(name, kFsName, strlen(kFsName)), 0, "Unexpected filesystem mounted");
    ASSERT_LE(info.used_nodes, info.total_nodes, "Used nodes greater than free nodes");
    ASSERT_LE(info.used_bytes, info.total_bytes, "Used bytes greater than free bytes");
    ASSERT_EQ(close(caller.release().release()), 0);
    return true;
}

bool BlobfsTest::Mount() {
    BEGIN_HELPER;
    int flags = read_only_ ? O_RDONLY : O_RDWR;

    fbl::unique_fd fd(open(ramdisk_path_, flags));
    ASSERT_TRUE(fd.get(), "Could not open ramdisk");

    mount_options_t options;
    memcpy(&options, &default_mount_options, sizeof(options));

    if (read_only_) {
        options.readonly = true;
    }

    auto launch = stdio_ ? launch_stdio_async : launch_silent_async;

    // fd consumed by mount. By default, mount waits until the filesystem is
    // ready to accept commands.
    ASSERT_EQ(mount(fd.get(), MOUNT_PATH, DISK_FORMAT_BLOBFS, &options, launch), ZX_OK,
              "Could not mount blobfs");

    END_HELPER;
}

// Helper functions for testing:

// Helper for streaming operations (such as read, write) which may need to be
// repeated multiple times.
template <typename T, typename U>
static int StreamAll(T func, int fd, U* buf, size_t max) {
    size_t n = 0;
    while (n != max) {
        ssize_t d = func(fd, &buf[n], max - n);
        if (d < 0) {
            return -1;
        }
        n += d;
    }
    return 0;
}

static bool VerifyContents(int fd, const char* data, size_t size_data) {
    // Verify the contents of the Blob
    fbl::AllocChecker ac;
    fbl::unique_ptr<char[]> buf(new (&ac) char[size_data]);
    EXPECT_EQ(ac.check(), true);
    ASSERT_EQ(lseek(fd, 0, SEEK_SET), 0);
    ASSERT_EQ(StreamAll(read, fd, &buf[0], size_data), 0, "Failed to read data");
    ASSERT_EQ(memcmp(buf.get(), data, size_data), 0, "Read data, but it was bad");
    return true;
}

// An in-memory representation of a blob.
typedef struct blob_info {
    char path[PATH_MAX];
    fbl::unique_ptr<char[]> merkle;
    size_t size_merkle;
    fbl::unique_ptr<char[]> data;
    size_t size_data;
} blob_info_t;

// Creates an open blob with the provided Merkle tree + Data, and
// reads to verify the data.
static bool MakeBlob(blob_info_t* info, fbl::unique_fd* out_fd) {
    fbl::unique_fd fd(open(info->path, O_CREAT | O_RDWR));
    ASSERT_TRUE(fd, "Failed to create blob");
    ASSERT_EQ(ftruncate(fd.get(), info->size_data), 0);
    ASSERT_EQ(StreamAll(write, fd.get(), info->data.get(), info->size_data), 0,
              "Failed to write Data");
    ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
    out_fd->reset(fd.release());
    return true;
}

static bool MakeBlobUnverified(blob_info_t* info, fbl::unique_fd* out_fd) {
    fbl::unique_fd fd(open(info->path, O_CREAT | O_RDWR));
    ASSERT_TRUE(fd, "Failed to create blob");
    ASSERT_EQ(ftruncate(fd.get(), info->size_data), 0);
    ASSERT_EQ(StreamAll(write, fd.get(), info->data.get(), info->size_data), 0,
              "Failed to write Data");
    out_fd->reset(fd.release());
    return true;
}

static bool VerifyCompromised(int fd, const char* data, size_t size_data) {
    // Verify the contents of the Blob
    fbl::AllocChecker ac;
    fbl::unique_ptr<char[]> buf(new (&ac) char[size_data]);
    EXPECT_EQ(ac.check(), true);

    ASSERT_EQ(lseek(fd, 0, SEEK_SET), 0);
    ASSERT_EQ(StreamAll(read, fd, &buf[0], size_data), -1, "Expected reading to fail");
    return true;
}

// Creates a blob with the provided Merkle tree + Data, and
// reads to verify the data.
static bool MakeBlobCompromised(blob_info_t* info) {
    fbl::unique_fd fd(open(info->path, O_CREAT | O_RDWR));
    ASSERT_TRUE(fd, "Failed to create blob");
    ASSERT_EQ(ftruncate(fd.get(), info->size_data), 0);

    // If we're writing a blob with invalid sizes, it's possible that writing will fail.
    StreamAll(write, fd.get(), info->data.get(), info->size_data);

    ASSERT_TRUE(VerifyCompromised(fd.get(), info->data.get(), info->size_data));
    ASSERT_EQ(close(fd.release()), 0);
    return true;
}

static bool uint8_to_hex_str(const uint8_t* data, char* hex_str) {
    for (size_t i = 0; i < 32; i++) {
        ASSERT_EQ(sprintf(hex_str + (i * 2), "%02x", data[i]), 2,
                  "Error converting name to string");
    }
    hex_str[64] = 0;
    return true;
}

static void RandomFill(char* data, size_t length) {
    static unsigned int seed = static_cast<unsigned int>(zx_ticks_get());
    // TODO(US-286): Make this easier to reproduce with reliably generated prng.
    unittest_printf("RandomFill of %zu bytes with seed: %u\n", length, seed);
    for (size_t i = 0; i < length; i++) {
        data[i] = (char)rand_r(&seed);
    }
}

using BlobSrcFunction = void (*)(char* data, size_t length);

// Creates, writes, reads (to verify) and operates on a blob.
// Returns the result of the post-processing 'func' (true == success).
static bool GenerateBlob(BlobSrcFunction sourceCb, size_t size_data,
                         fbl::unique_ptr<blob_info_t>* out) {
    BEGIN_HELPER;
    fbl::AllocChecker ac;
    fbl::unique_ptr<blob_info_t> info(new (&ac) blob_info_t);
    EXPECT_EQ(ac.check(), true);
    info->data.reset(new (&ac) char[size_data]);
    EXPECT_EQ(ac.check(), true);
    sourceCb(info->data.get(), size_data);
    info->size_data = size_data;

    // Generate the Merkle Tree
    info->size_merkle = MerkleTree::GetTreeLength(size_data);
    if (info->size_merkle == 0) {
        info->merkle = nullptr;
    } else {
        info->merkle.reset(new (&ac) char[info->size_merkle]);
        ASSERT_EQ(ac.check(), true);
    }
    Digest digest;
    ASSERT_EQ(MerkleTree::Create(&info->data[0], info->size_data, &info->merkle[0],
                                 info->size_merkle, &digest),
              ZX_OK, "Couldn't create Merkle Tree");
    strcpy(info->path, MOUNT_PATH "/");
    size_t prefix_len = strlen(info->path);
    digest.ToString(info->path + prefix_len, sizeof(info->path) - prefix_len);

    // Sanity-check the merkle tree
    ASSERT_EQ(MerkleTree::Verify(&info->data[0], info->size_data, &info->merkle[0],
                                 info->size_merkle, 0, info->size_data, digest),
              ZX_OK, "Failed to validate Merkle Tree");

    *out = fbl::move(info);
    END_HELPER;
}

static bool GenerateRandomBlob(size_t size_data, fbl::unique_ptr<blob_info_t>* out) {
    BEGIN_HELPER;
    ASSERT_TRUE(GenerateBlob(RandomFill, size_data, out));
    END_HELPER;
}

bool QueryInfo(size_t expected_nodes, size_t expected_bytes) {
    fbl::unique_fd fd(open(MOUNT_PATH, O_RDONLY | O_DIRECTORY));
    ASSERT_TRUE(fd);

    zx_status_t status;
    fuchsia_io_FilesystemInfo info;
    fzl::FdioCaller caller(fbl::move(fd));
    ASSERT_EQ(fuchsia_io_DirectoryAdminQueryFilesystem(caller.borrow_channel(), &status, &info),
              ZX_OK);
    ASSERT_EQ(status, ZX_OK);
    const char* kFsName = "blobfs";
    const char* name = reinterpret_cast<const char*>(info.name);
    ASSERT_EQ(close(caller.release().release()), 0);
    ASSERT_EQ(strncmp(name, kFsName, strlen(kFsName)), 0, "Unexpected filesystem mounted");
    ASSERT_EQ(info.block_size, blobfs::kBlobfsBlockSize);
    ASSERT_EQ(info.max_filename_size, Digest::kLength * 2);
    ASSERT_EQ(info.fs_type, VFS_TYPE_BLOBFS);
    ASSERT_NE(info.fs_id, 0);

    // Check that used_bytes are within a reasonable range
    ASSERT_GE(info.used_bytes, expected_bytes);
    ASSERT_LE(info.used_bytes, info.total_bytes);

    // Check that total_bytes are a multiple of slice_size
    ASSERT_GE(info.total_bytes, kTestFvmSliceSize);
    ASSERT_EQ(info.total_bytes % kTestFvmSliceSize, 0);
    ASSERT_EQ(info.total_nodes, kTestFvmSliceSize / blobfs::kBlobfsInodeSize);
    ASSERT_EQ(info.used_nodes, expected_nodes);
    return true;
}

}  // namespace

// Actual tests:
static bool TestBasic(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    for (size_t i = 10; i < 16; i++) {
        fbl::unique_ptr<blob_info_t> info;
        ASSERT_TRUE(GenerateRandomBlob(1 << i, &info));

        fbl::unique_fd fd;
        ASSERT_TRUE(MakeBlob(info.get(), &fd));
        ASSERT_EQ(close(fd.release()), 0);

        // We can re-open and verify the Blob as read-only
        fd.reset(open(info->path, O_RDONLY));
        ASSERT_TRUE(fd, "Failed to-reopen blob");
        ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
        ASSERT_EQ(close(fd.release()), 0);

        // We cannot re-open the blob as writable
        fd.reset(open(info->path, O_RDWR | O_CREAT));
        ASSERT_FALSE(fd, "Shouldn't be able to re-create blob that exists");
        fd.reset(open(info->path, O_RDWR));
        ASSERT_FALSE(fd, "Shouldn't be able to re-open blob as writable");
        fd.reset(open(info->path, O_WRONLY));
        ASSERT_FALSE(fd, "Shouldn't be able to re-open blob as writable");

        ASSERT_EQ(unlink(info->path), 0);
    }
    END_HELPER;
}

static bool TestNullBlob(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    fbl::unique_ptr<blob_info_t> info;
    ASSERT_TRUE(GenerateRandomBlob(0, &info));

    fbl::unique_fd fd(open(info->path, O_CREAT | O_EXCL | O_RDWR));
    ASSERT_TRUE(fd);
    ASSERT_EQ(ftruncate(fd.get(), 0), 0);
    char buf[1];
    ASSERT_EQ(read(fd.get(), &buf[0], 1), 0, "Null Blob should reach EOF immediately");
    ASSERT_EQ(close(fd.release()), 0);

    fd.reset(open(info->path, O_CREAT | O_EXCL | O_RDWR));
    ASSERT_FALSE(fd, "Null Blob should already exist");
    fd.reset(open(info->path, O_CREAT | O_RDWR));
    ASSERT_FALSE(fd, "Null Blob should not be openable as writable");

    fd.reset(open(info->path, O_RDONLY));
    ASSERT_TRUE(fd);
    ASSERT_EQ(close(fd.release()), 0);
    ASSERT_EQ(unlink(info->path), 0, "Null Blob should be unlinkable");

    END_HELPER;
}

static bool TestCompressibleBlob(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    for (size_t i = 10; i < 22; i++) {
        fbl::unique_ptr<blob_info_t> info;

        // Create blobs which are trivially compressible.
        ASSERT_TRUE(GenerateBlob([](char* data, size_t length) {
            size_t i = 0;
            while (i < length) {
                size_t j = (rand() % (length - i)) + 1;
                memset(data, (char) j, j);
                data += j;
                i += j;
            }
        }, 1 << i, &info));

        fbl::unique_fd fd;
        ASSERT_TRUE(MakeBlob(info.get(), &fd));
        ASSERT_EQ(close(fd.release()), 0);

        // We can re-open and verify the Blob as read-only
        fd.reset(open(info->path, O_RDONLY));
        ASSERT_TRUE(fd, "Failed to-reopen blob");
        ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
        ASSERT_EQ(close(fd.release()), 0);

        // We cannot re-open the blob as writable
        fd.reset(open(info->path, O_RDWR | O_CREAT));
        ASSERT_FALSE(fd, "Shouldn't be able to re-create blob that exists");
        fd.reset(open(info->path, O_RDWR));
        ASSERT_FALSE(fd, "Shouldn't be able to re-open blob as writable");
        fd.reset(open(info->path, O_WRONLY));
        ASSERT_FALSE(fd, "Shouldn't be able to re-open blob as writable");

        // Force decompression by remounting, re-accessing blob.
        ASSERT_TRUE(blobfsTest->Remount());
        fd.reset(open(info->path, O_RDONLY));
        ASSERT_TRUE(fd, "Failed to-reopen blob");
        ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
        ASSERT_EQ(close(fd.release()), 0);

        ASSERT_EQ(unlink(info->path), 0);
    }

    END_HELPER;
}

static bool TestMmap(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    for (size_t i = 10; i < 16; i++) {
        fbl::unique_ptr<blob_info_t> info;
        ASSERT_TRUE(GenerateRandomBlob(1 << i, &info));

        fbl::unique_fd fd;
        ASSERT_TRUE(MakeBlob(info.get(), &fd));
        ASSERT_EQ(close(fd.release()), 0);
        fd.reset(open(info->path, O_RDONLY));
        ASSERT_TRUE(fd, "Failed to-reopen blob");

        void* addr = mmap(NULL, info->size_data, PROT_READ, MAP_PRIVATE,
                          fd.get(), 0);
        ASSERT_NE(addr, MAP_FAILED, "Could not mmap blob");
        ASSERT_EQ(memcmp(addr, info->data.get(), info->size_data), 0, "Mmap data invalid");
        ASSERT_EQ(munmap(addr, info->size_data), 0, "Could not unmap blob");
        ASSERT_EQ(close(fd.release()), 0);
        ASSERT_EQ(unlink(info->path), 0);
    }
    END_HELPER;
}

static bool TestMmapUseAfterClose(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    for (size_t i = 10; i < 16; i++) {
        fbl::unique_ptr<blob_info_t> info;
        ASSERT_TRUE(GenerateRandomBlob(1 << i, &info));

        fbl::unique_fd fd;
        ASSERT_TRUE(MakeBlob(info.get(), &fd));
        ASSERT_EQ(close(fd.release()), 0);
        fd.reset(open(info->path, O_RDONLY));
        ASSERT_TRUE(fd, "Failed to-reopen blob");

        void* addr = mmap(NULL, info->size_data, PROT_READ, MAP_PRIVATE, fd.get(), 0);
        ASSERT_NE(addr, MAP_FAILED, "Could not mmap blob");
        ASSERT_EQ(close(fd.release()), 0);

        // We should be able to access the mapped data while the file is closed.
        ASSERT_EQ(memcmp(addr, info->data.get(), info->size_data), 0, "Mmap data invalid");

        // We should be able to re-open and remap the file.
        //
        // Although this isn't being tested explicitly (we lack a mechanism to
        // check that the second mapping uses the same underlying pages as the
        // first) the memory usage should avoid duplication in the second
        // mapping.
        fd.reset(open(info->path, O_RDONLY));
        void* addr2 = mmap(NULL, info->size_data, PROT_READ, MAP_PRIVATE, fd.get(), 0);
        ASSERT_NE(addr2, MAP_FAILED, "Could not mmap blob");
        ASSERT_EQ(close(fd.release()), 0);
        ASSERT_EQ(memcmp(addr2, info->data.get(), info->size_data), 0, "Mmap data invalid");

        ASSERT_EQ(munmap(addr, info->size_data), 0, "Could not unmap blob");
        ASSERT_EQ(munmap(addr2, info->size_data), 0, "Could not unmap blob");

        ASSERT_EQ(unlink(info->path), 0);
    }
    END_HELPER;
}

static bool TestReaddir(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    constexpr size_t kMaxEntries = 50;
    constexpr size_t kBlobSize = 1 << 10;

    fbl::AllocChecker ac;
    fbl::Array<fbl::unique_ptr<blob_info_t>>
        info(new (&ac) fbl::unique_ptr<blob_info_t>[kMaxEntries](), kMaxEntries);
    ASSERT_TRUE(ac.check());

    // Try to readdir on an empty directory
    DIR* dir = opendir(MOUNT_PATH);
    ASSERT_NONNULL(dir);
    auto cleanup = fbl::MakeAutoCall([dir](){ closedir(dir); });
    ASSERT_NULL(readdir(dir), "Expected blobfs to start empty");

    // Fill a directory with entries
    for (size_t i = 0; i < kMaxEntries; i++) {
        ASSERT_TRUE(GenerateRandomBlob(kBlobSize, &info[i]));
        fbl::unique_fd fd;
        ASSERT_TRUE(MakeBlob(info[i].get(), &fd));
        ASSERT_EQ(close(fd.release()), 0);
        fd.reset(open(info[i]->path, O_RDONLY));
        ASSERT_TRUE(fd, "Failed to-reopen blob");
        ASSERT_TRUE(VerifyContents(fd.get(), info[i]->data.get(), info[i]->size_data));
        ASSERT_EQ(close(fd.release()), 0);
    }

    // Check that we see the expected number of entries
    size_t entries_seen = 0;
    struct dirent* de;
    while ((de = readdir(dir)) != nullptr) {
        entries_seen++;
    }
    ASSERT_EQ(entries_seen, kMaxEntries);
    entries_seen = 0;
    rewinddir(dir);

    // Readdir on a directory which contains entries, removing them as we go
    // along.
    while ((de = readdir(dir)) != nullptr) {
        for (size_t i = 0; i < kMaxEntries; i++) {
            if ((info[i]->size_data != 0) &&
                strcmp(strrchr(info[i]->path, '/') + 1, de->d_name) == 0) {
                ASSERT_EQ(unlink(info[i]->path), 0);
                // It's a bit hacky, but we set 'size_data' to zero
                // to identify the entry has been unlinked.
                info[i]->size_data = 0;
                goto found;
            }
        }
        ASSERT_TRUE(false, "Blobfs Readdir found an unexpected entry");
    found:
        entries_seen++;
    }
    ASSERT_EQ(entries_seen, kMaxEntries);

    ASSERT_NULL(readdir(dir), "Expected blobfs to end empty");
    cleanup.cancel();
    ASSERT_EQ(closedir(dir), 0);
    END_HELPER;
}

static bool TestDiskTooSmall(BlobfsTest* blobfsTest) {
    BEGIN_TEST;

    if (gUseRealDisk) {
        fprintf(stderr, "Ramdisk required; skipping test\n");
        return true;
    }

    uint64_t minimum_size = 0;
    if (blobfsTest->GetType() == FsTestType::kFvm) {
        size_t blocks_per_slice = kTestFvmSliceSize / blobfs::kBlobfsBlockSize;

        // Calculate slices required for data blocks based on minimum requirement and slice size.
        uint64_t required_data_slices = fbl::round_up(blobfs::kMinimumDataBlocks, blocks_per_slice)
                                        / blocks_per_slice;
        // Require an additional 1 slice each for super, inode, and block bitmaps.
        uint64_t blobfs_size = (required_data_slices + 3) * kTestFvmSliceSize;
        minimum_size = blobfs_size;
        uint64_t metadata_size = fvm::MetadataSize(blobfs_size, kTestFvmSliceSize);

        // Re-calculate minimum size until the metadata size stops growing.
        while (minimum_size - blobfs_size != metadata_size * 2) {
            minimum_size = blobfs_size + metadata_size * 2;
            metadata_size = fvm::MetadataSize(minimum_size, kTestFvmSliceSize);
        }

        ASSERT_EQ(minimum_size - blobfs_size,
                  fvm::MetadataSize(minimum_size, kTestFvmSliceSize) * 2);
    } else {
        blobfs::Superblock info;
        info.inode_count = blobfs::kBlobfsDefaultInodeCount;
        info.block_count = blobfs::kMinimumDataBlocks;
        info.flags = 0;

        minimum_size = (blobfs::DataBlocks(info) + blobfs::DataStartBlock(info)) *
                       blobfs::kBlobfsBlockSize;
    }

    // Teardown the initial test configuration and reset the test state.
    ASSERT_TRUE(blobfsTest->Teardown());
    ASSERT_TRUE(blobfsTest->Reset());

    // Create disk with minimum possible size, make sure init passes.
    ASSERT_GE(minimum_size, blobfsTest->GetBlockSize());
    uint64_t disk_blocks = minimum_size / blobfsTest->GetBlockSize();
    ASSERT_TRUE(blobfsTest->SetBlockCount(disk_blocks));
    ASSERT_TRUE(blobfsTest->Init());
    ASSERT_TRUE(blobfsTest->Teardown());

    // Reset the disk size and test state.
    ASSERT_TRUE(blobfsTest->Reset());
    ASSERT_TRUE(blobfsTest->SetBlockCount(disk_blocks - 1));

    // Create disk with smaller than minimum size, make sure mkfs fails.
    ASSERT_TRUE(blobfsTest->Init(FsTestState::kMinimal));

    char device_path[PATH_MAX];
    ASSERT_TRUE(blobfsTest->GetDevicePath(device_path, PATH_MAX));
    ASSERT_NE(mkfs(device_path, DISK_FORMAT_BLOBFS, launch_stdio_sync, &default_mkfs_options),
              ZX_OK);

    // Reset the ramdisk counts so we don't attempt to run ramdisk failure tests. There isn't
    // really a point with this test since we are testing blobfs creation, which doesn't generate
    // any journal entries.
    ASSERT_TRUE(blobfsTest->ToggleSleep());
    ASSERT_TRUE(blobfsTest->ToggleSleep());
    END_TEST;
}


static bool TestQueryInfo(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    ASSERT_EQ(blobfsTest->GetType(), FsTestType::kFvm);

    size_t total_bytes = 0;
    ASSERT_TRUE(QueryInfo(0, 0));
    for (size_t i = 10; i < 16; i++) {
        fbl::unique_ptr<blob_info_t> info;
        ASSERT_TRUE(GenerateRandomBlob(1 << i, &info));

        fbl::unique_fd fd;
        ASSERT_TRUE(MakeBlob(info.get(), &fd));
        ASSERT_EQ(close(fd.release()), 0);
        total_bytes += fbl::round_up(info->size_merkle + info->size_data,
                       blobfs::kBlobfsBlockSize);
    }

    ASSERT_TRUE(QueryInfo(6, total_bytes));
    END_HELPER;
}

static bool UseAfterUnlink(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    for (size_t i = 0; i < 16; i++) {
        fbl::unique_ptr<blob_info_t> info;
        ASSERT_TRUE(GenerateRandomBlob(1 << i, &info));

        fbl::unique_fd fd;
        ASSERT_TRUE(MakeBlob(info.get(), &fd));

        // We should be able to unlink the blob
        ASSERT_EQ(unlink(info->path), 0, "Failed to unlink");

        // We should still be able to read the blob after unlinking
        ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));

        // After closing the fd, however, we should not be able to re-open the blob
        ASSERT_EQ(close(fd.release()), 0);
        ASSERT_LT(open(info->path, O_RDONLY), 0, "Expected blob to be deleted");
    }
    END_HELPER;
}

static bool WriteAfterRead(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    for (size_t i = 0; i < 16; i++) {
        fbl::unique_ptr<blob_info_t> info;
        ASSERT_TRUE(GenerateRandomBlob(1 << i, &info));

        fbl::unique_fd fd;
        ASSERT_TRUE(MakeBlob(info.get(), &fd));

        // After blob generation, writes should be rejected
        ASSERT_LT(write(fd.get(), info->data.get(), 1), 0,
                  "After being written, the blob should refuse writes");

        off_t seek_pos = (rand() % info->size_data);
        ASSERT_EQ(lseek(fd.get(), seek_pos, SEEK_SET), seek_pos);
        ASSERT_LT(write(fd.get(), info->data.get(), 1), 0,
                  "After being written, the blob should refuse writes");
        ASSERT_LT(ftruncate(fd.get(), rand() % info->size_data), 0,
                  "The blob should always refuse to be truncated");

        // We should be able to unlink the blob
        ASSERT_EQ(close(fd.release()), 0);
        ASSERT_EQ(unlink(info->path), 0, "Failed to unlink");
    }
    END_HELPER;
}

bool WriteAfterUnlink(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    fbl::unique_ptr<blob_info_t> info;
    size_t size = 1 << 20;
    ASSERT_TRUE(GenerateRandomBlob(size, &info));

    // Partially write out first blob.
    fbl::unique_fd fd(open(info->path, O_CREAT | O_RDWR));
    ASSERT_TRUE(fd, "Failed to create blob");
    ASSERT_EQ(ftruncate(fd.get(), size), 0);
    ASSERT_EQ(StreamAll(write, fd.get(), info->data.get(), size / 2), 0, "Failed to write Data");
    ASSERT_EQ(unlink(info->path), 0);
    ASSERT_EQ(StreamAll(write, fd.get(), info->data.get() + size / 2, size - (size / 2)), 0, "Failed to write Data");
    ASSERT_EQ(close(fd.release()), 0);
    ASSERT_LT(open(info->path, O_RDONLY), 0);
    END_HELPER;
}

static bool ReadTooLarge(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    for (size_t i = 0; i < 16; i++) {
        fbl::unique_ptr<blob_info_t> info;
        ASSERT_TRUE(GenerateRandomBlob(1 << i, &info));

        fbl::unique_fd fd;
        ASSERT_TRUE(MakeBlob(info.get(), &fd));

        // Verify the contents of the Blob
        fbl::AllocChecker ac;
        fbl::unique_ptr<char[]> buf(new (&ac) char[info->size_data]);
        EXPECT_EQ(ac.check(), true);

        // Try read beyond end of blob
        off_t end_off = info->size_data;
        ASSERT_EQ(lseek(fd.get(), end_off, SEEK_SET), end_off);
        ASSERT_EQ(read(fd.get(), &buf[0], 1), 0, "Expected empty read beyond end of file");

        // Try some reads which straddle the end of the blob
        for (ssize_t j = 1; j < static_cast<ssize_t>(info->size_data); j *= 2) {
            end_off = info->size_data - j;
            ASSERT_EQ(lseek(fd.get(), end_off, SEEK_SET), end_off);
            ASSERT_EQ(read(fd.get(), &buf[0], j * 2), j, "Expected to only read one byte at end of file");
            ASSERT_EQ(memcmp(buf.get(), &info->data[info->size_data - j], j),
                      0, "Read data, but it was bad");
        }

        // We should be able to unlink the blob
        ASSERT_EQ(close(fd.release()), 0);
        ASSERT_EQ(unlink(info->path), 0, "Failed to unlink");
    }
    END_HELPER;
}

static bool BadAllocation(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    ASSERT_LT(open(MOUNT_PATH "/00112233445566778899AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVV",
                   O_CREAT | O_RDWR),
              0, "Only acceptable pathnames are hex");
    ASSERT_LT(open(MOUNT_PATH "/00112233445566778899AABBCCDDEEFF", O_CREAT | O_RDWR), 0,
              "Only acceptable pathnames are 32 hex-encoded bytes");

    fbl::unique_ptr<blob_info_t> info;
    ASSERT_TRUE(GenerateRandomBlob(1 << 15, &info));

    fbl::unique_fd fd(open(info->path, O_CREAT | O_RDWR));
    ASSERT_TRUE(fd, "Failed to create blob");
    ASSERT_EQ(ftruncate(fd.get(), 0), -1, "Blob without data doesn't match null blob");
    // This is the size of the entire disk; we won't have room.
    ASSERT_EQ(ftruncate(fd.get(), blobfsTest->GetDiskSize()), -1, "Huge blob");

    // Okay, finally, a valid blob!
    ASSERT_EQ(ftruncate(fd.get(), info->size_data), 0, "Failed to allocate blob");

    // Write nothing, but close the blob. Since the write was incomplete,
    // it will be inaccessible.
    ASSERT_EQ(close(fd.release()), 0);
    ASSERT_LT(open(info->path, O_RDWR), 0, "Cannot access partial blob");
    ASSERT_LT(open(info->path, O_RDONLY), 0, "Cannot access partial blob");

    // And once more -- let's write everything but the last byte of a blob's data.
    fd.reset(open(info->path, O_CREAT | O_RDWR));
    ASSERT_TRUE(fd, "Failed to create blob");
    ASSERT_EQ(ftruncate(fd.get(), info->size_data), 0, "Failed to allocate blob");
    ASSERT_EQ(StreamAll(write, fd.get(), info->data.get(), info->size_data - 1), 0,
              "Failed to write data");
    ASSERT_EQ(close(fd.release()), 0);
    ASSERT_LT(open(info->path, O_RDWR), 0, "Cannot access partial blob");
    END_HELPER;
}

static bool CorruptedBlob(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;

    fbl::unique_ptr<blob_info_t> info;
    for (size_t i = 1; i < 18; i++) {
        ASSERT_TRUE(GenerateRandomBlob(1 << i, &info));
        info->size_data -= (rand() % info->size_data) + 1;
        if (info->size_data == 0) {
            info->size_data = 1;
        }
        ASSERT_TRUE(MakeBlobCompromised(info.get()));
    }

    for (size_t i = 0; i < 18; i++) {
        ASSERT_TRUE(GenerateRandomBlob(1 << i, &info));
        // Flip a random bit of the data
        size_t rand_index = rand() % info->size_data;
        char old_val = info->data.get()[rand_index];
        while ((info->data.get()[rand_index] = static_cast<char>(rand())) == old_val) {
        }
        ASSERT_TRUE(MakeBlobCompromised(info.get()));
    }

    END_HELPER;
}

static bool CorruptedDigest(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;

    fbl::unique_ptr<blob_info_t> info;
    for (size_t i = 1; i < 18; i++) {
        ASSERT_TRUE(GenerateRandomBlob(1 << i, &info));

        char hexdigits[17] = "0123456789abcdef";
        size_t idx = strlen(info->path) - 1 - (rand() % (2 * Digest::kLength));
        char newchar = hexdigits[rand() % 16];
        while (info->path[idx] == newchar) {
            newchar = hexdigits[rand() % 16];
        }
        info->path[idx] = newchar;
        ASSERT_TRUE(MakeBlobCompromised(info.get()));
    }

    for (size_t i = 0; i < 18; i++) {
        ASSERT_TRUE(GenerateRandomBlob(1 << i, &info));
        // Flip a random bit of the data
        size_t rand_index = rand() % info->size_data;
        char old_val = info->data.get()[rand_index];
        while ((info->data.get()[rand_index] = static_cast<char>(rand())) == old_val) {
        }
        ASSERT_TRUE(MakeBlobCompromised(info.get()));
    }

    END_HELPER;
}

static bool EdgeAllocation(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;

    // Powers of two...
    for (size_t i = 1; i < 16; i++) {
        // -1, 0, +1 offsets...
        for (size_t j = -1; j < 2; j++) {
            fbl::unique_ptr<blob_info_t> info;
            ASSERT_TRUE(GenerateRandomBlob((1 << i) + j, &info));
            fbl::unique_fd fd;
            ASSERT_TRUE(MakeBlob(info.get(), &fd));
            ASSERT_EQ(unlink(info->path), 0);
            ASSERT_EQ(close(fd.release()), 0);
        }
    }
    END_HELPER;
}

static bool UmountWithOpenFile(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    fbl::unique_ptr<blob_info_t> info;
    ASSERT_TRUE(GenerateRandomBlob(1 << 16, &info));
    fbl::unique_fd fd;
    ASSERT_TRUE(MakeBlob(info.get(), &fd));

    // Intentionally don't close the file descriptor: Unmount anyway.
    ASSERT_TRUE(blobfsTest->Remount());
    // Just closing our local handle; the connection should be disconnected.
    ASSERT_EQ(close(fd.release()), -1);
    ASSERT_EQ(errno, EPIPE);

    fd.reset(open(info->path, O_RDONLY));
    ASSERT_TRUE(fd, "Failed to open blob");
    ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
    ASSERT_EQ(close(fd.release()), 0, "Could not close blob");

    ASSERT_EQ(unlink(info->path), 0);
    END_HELPER;
}

static bool UmountWithMappedFile(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    fbl::unique_ptr<blob_info_t> info;
    ASSERT_TRUE(GenerateRandomBlob(1 << 16, &info));
    fbl::unique_fd fd;
    ASSERT_TRUE(MakeBlob(info.get(), &fd));

    void* addr = mmap(nullptr, info->size_data, PROT_READ, MAP_SHARED, fd.get(), 0);
    ASSERT_NONNULL(addr);
    ASSERT_EQ(close(fd.release()), 0);

    // Intentionally don't unmap the file descriptor: Unmount anyway.
    ASSERT_TRUE(blobfsTest->Remount());
    // Just closing our local handle; the connection should be disconnected.
    ASSERT_EQ(munmap(addr, info->size_data), 0);

    fd.reset(open(info->path, O_RDONLY));
    ASSERT_GE(fd.get(), 0, "Failed to open blob");
    ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
    ASSERT_EQ(close(fd.release()), 0, "Could not close blob");

    ASSERT_EQ(unlink(info->path), 0);
    END_HELPER;
}

static bool UmountWithOpenMappedFile(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    fbl::unique_ptr<blob_info_t> info;
    ASSERT_TRUE(GenerateRandomBlob(1 << 16, &info));
    fbl::unique_fd fd;
    ASSERT_TRUE(MakeBlob(info.get(), &fd));

    void* addr = mmap(nullptr, info->size_data, PROT_READ, MAP_SHARED, fd.get(), 0);
    ASSERT_NONNULL(addr);

    // Intentionally don't close the file descriptor: Unmount anyway.
    ASSERT_TRUE(blobfsTest->Remount());
    // Just closing our local handle; the connection should be disconnected.
    ASSERT_EQ(munmap(addr, info->size_data), 0);
    ASSERT_EQ(close(fd.release()), -1);
    ASSERT_EQ(errno, EPIPE);

    fd.reset(open(info->path, O_RDONLY));
    ASSERT_GE(fd.get(), 0, "Failed to open blob");
    ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
    ASSERT_EQ(close(fd.release()), 0, "Could not close blob");

    ASSERT_EQ(unlink(info->path), 0);
    END_HELPER;
}

static bool CreateUmountRemountSmall(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    for (size_t i = 10; i < 16; i++) {
        fbl::unique_ptr<blob_info_t> info;
        ASSERT_TRUE(GenerateRandomBlob(1 << i, &info));

        fbl::unique_fd fd;
        ASSERT_TRUE(MakeBlob(info.get(), &fd));
        // Close fd, unmount filesystem
        ASSERT_EQ(close(fd.release()), 0);

        ASSERT_TRUE(blobfsTest->Remount(), "Could not re-mount blobfs");

        fd.reset(open(info->path, O_RDONLY));
        ASSERT_TRUE(fd, "Failed to open blob");

        ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
        ASSERT_EQ(close(fd.release()), 0, "Could not close blob");
        ASSERT_EQ(unlink(info->path), 0);
    }

    END_HELPER;
}

static bool check_not_readable(int fd) {
    BEGIN_HELPER;
    struct pollfd fds;
    fds.fd = fd;
    fds.events = POLLIN;
    ASSERT_EQ(poll(&fds, 1, 10), 0, "Failed to wait for readable blob");

    char buf[1];
    ASSERT_EQ(lseek(fd, 0, SEEK_SET), 0);
    ASSERT_LT(read(fd, buf, sizeof(buf)), 0, "Blob should not be readable yet");
    END_HELPER;
}

static bool check_readable(int fd) {
    BEGIN_HELPER;
    struct pollfd fds;
    fds.fd = fd;
    fds.events = POLLIN;
    ASSERT_EQ(poll(&fds, 1, 10), 1, "Failed to wait for readable blob");
    ASSERT_EQ(fds.revents, POLLIN);

    char buf[1];
    ASSERT_EQ(lseek(fd, 0, SEEK_SET), 0);
    ASSERT_EQ(read(fd, buf, sizeof(buf)), sizeof(buf));
    END_HELPER;
}

static bool EarlyRead(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    // Check that we cannot read from the Blob until it has been fully written
    fbl::unique_ptr<blob_info_t> info;

    ASSERT_TRUE(GenerateRandomBlob(1 << 17, &info));
    fbl::unique_fd fd(open(info->path, O_CREAT | O_EXCL | O_RDWR));
    ASSERT_TRUE(fd, "Failed to create blob");

    ASSERT_LT(open(info->path, O_CREAT | O_EXCL | O_RDWR), 0,
              "Should not be able to exclusively create twice");

    // This second fd should also not be readable
    fbl::unique_fd fd2(open(info->path, O_CREAT | O_RDWR));
    ASSERT_TRUE(fd2, "Failed to create blob");

    ASSERT_TRUE(check_not_readable(fd.get()), "Should not be readable after open");
    ASSERT_TRUE(check_not_readable(fd2.get()), "Should not be readable after open");
    ASSERT_EQ(ftruncate(fd.get(), info->size_data), 0);
    ASSERT_TRUE(check_not_readable(fd.get()), "Should not be readable after alloc");
    ASSERT_TRUE(check_not_readable(fd2.get()), "Should not be readable after alloc");
    ASSERT_EQ(StreamAll(write, fd.get(), info->data.get(), info->size_data), 0,
              "Failed to write Data");

    // Okay, NOW we can read.
    // Double check that attempting to read early didn't cause problems...
    ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
    ASSERT_TRUE(VerifyContents(fd2.get(), info->data.get(), info->size_data));

    // Cool, everything is readable. What if we try accessing the blob status now?
    EXPECT_TRUE(check_readable(fd.get()));

    ASSERT_EQ(close(fd.release()), 0);
    ASSERT_EQ(close(fd2.release()), 0);
    ASSERT_EQ(unlink(info->path), 0);
    END_HELPER;
}

static bool wait_readable(int fd) {
    BEGIN_HELPER;
    struct pollfd fds;
    fds.fd = fd;
    fds.events = POLLIN;
    ASSERT_EQ(poll(&fds, 1, 10000), 1, "Failed to wait for readable blob");
    ASSERT_EQ(fds.revents, POLLIN);
    END_HELPER;
}

// Check that we cannot read from the Blob until it has been fully written
static bool WaitForRead(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    fbl::unique_ptr<blob_info_t> info;

    ASSERT_TRUE(GenerateRandomBlob(1 << 17, &info));
    fbl::unique_fd fd(open(info->path, O_CREAT | O_EXCL | O_RDWR));
    ASSERT_TRUE(fd, "Failed to create blob");

    ASSERT_LT(open(info->path, O_CREAT | O_EXCL | O_RDWR), 0,
              "Should not be able to exclusively create twice");

    // Launch a background thread to wait for fd to become readable
    auto wait_until_readable = [](void* arg) {
        fbl::unique_fd fd(*static_cast<int*>(arg));
        if (!wait_readable(fd.get())) {
            return -1;
        }

        if (!check_readable(fd.get())) {
            return -1;
        }

        if (close(fd.release()) != 0) {
            return -1;
        }

        return 0;
    };

    int dupfd = dup(fd.get());
    thrd_t waiter_thread;
    thrd_create(&waiter_thread, wait_until_readable, &dupfd);

    ASSERT_TRUE(check_not_readable(fd.get()), "Should not be readable after open");
    ASSERT_EQ(ftruncate(fd.get(), info->size_data), 0);
    ASSERT_TRUE(check_not_readable(fd.get()), "Should not be readable after alloc");
    ASSERT_EQ(StreamAll(write, fd.get(), info->data.get(), info->size_data), 0,
              "Failed to write Data");

    // Cool, everything is readable. What if we try accessing the blob status now?
    EXPECT_TRUE(check_readable(fd.get()));

    // Our background thread should have also completed successfully...
    int result;
    ASSERT_EQ(thrd_join(waiter_thread, &result), 0, "thrd_join failed");
    ASSERT_EQ(result, 0, "Unexpected result from background thread");

    // Double check that attempting to read early didn't cause problems...
    ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
    ASSERT_EQ(close(fd.release()), 0);
    ASSERT_EQ(unlink(info->path), 0);
    END_HELPER;
}

// Check that seeks during writing are ignored
static bool WriteSeekIgnored(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    fbl::unique_ptr<blob_info_t> info;
    ASSERT_TRUE(GenerateRandomBlob(1 << 17, &info));
    fbl::unique_fd fd(open(info->path, O_CREAT | O_RDWR));
    ASSERT_TRUE(fd, "Failed to create blob");
    ASSERT_EQ(ftruncate(fd.get(), info->size_data), 0);

    size_t n = 0;
    while (n != info->size_data) {
        off_t seek_pos = (rand() % info->size_data);
        ASSERT_EQ(lseek(fd.get(), seek_pos, SEEK_SET), seek_pos);
        ssize_t d = write(fd.get(), info->data.get(), info->size_data - n);
        ASSERT_GT(d, 0, "Data Write error");
        n += d;
    }

    // Double check that attempting to seek early didn't cause problems...
    ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
    ASSERT_EQ(close(fd.release()), 0);
    ASSERT_EQ(unlink(info->path), 0);
    END_HELPER;
}

// Try unlinking at a variety of times
static bool UnlinkTiming(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    // Unlink, close fd, re-open fd as new file
    auto full_unlink_reopen = [](fbl::unique_fd& fd, const char* path) {
        BEGIN_HELPER;
        ASSERT_EQ(unlink(path), 0);
        ASSERT_EQ(close(fd.release()), 0);
        fd.reset(open(path, O_CREAT | O_RDWR | O_EXCL));
        ASSERT_TRUE(fd, "Failed to recreate blob");
        END_HELPER;
    };

    fbl::unique_ptr<blob_info_t> info;
    ASSERT_TRUE(GenerateRandomBlob(1 << 17, &info));

    fbl::unique_fd fd(open(info->path, O_CREAT | O_RDWR));
    ASSERT_TRUE(fd, "Failed to create blob");

    // Unlink after first open
    ASSERT_TRUE(full_unlink_reopen(fd, info->path));

    // Unlink after init
    ASSERT_EQ(ftruncate(fd.get(), info->size_data), 0);
    ASSERT_TRUE(full_unlink_reopen(fd, info->path));

    // Unlink after first write
    ASSERT_EQ(ftruncate(fd.get(), info->size_data), 0);
    ASSERT_EQ(StreamAll(write, fd.get(), info->data.get(), info->size_data), 0,
              "Failed to write Data");
    ASSERT_TRUE(full_unlink_reopen(fd, info->path));
    ASSERT_EQ(unlink(info->path), 0);
    ASSERT_EQ(close(fd.release()), 0);
    END_HELPER;
}

// Attempt using invalid operations
static bool InvalidOps(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    // First off, make a valid blob
    fbl::unique_ptr<blob_info_t> info;
    ASSERT_TRUE(GenerateRandomBlob(1 << 12, &info));
    fbl::unique_fd fd;
    ASSERT_TRUE(MakeBlob(info.get(), &fd));
    ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));

    // Neat. Now, let's try some unsupported operations
    ASSERT_LT(rename(info->path, info->path), 0);
    ASSERT_LT(truncate(info->path, 0), 0);
    ASSERT_LT(utime(info->path, nullptr), 0);

    // Test that a blob fd cannot unmount the entire blobfs.
    zx_status_t status;
    fzl::FdioCaller caller(fbl::move(fd));
    ASSERT_EQ(fuchsia_io_DirectoryAdminUnmount(caller.borrow_channel(), &status), ZX_OK);
    ASSERT_EQ(status, ZX_ERR_ACCESS_DENIED);
    fd.reset(caller.release().release());

    // Access the file once more, after these operations
    ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
    ASSERT_EQ(unlink(info->path), 0);
    ASSERT_EQ(close(fd.release()), 0);
    END_HELPER;
}

// Attempt operations on the root directory
static bool RootDirectory(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    fbl::unique_fd dirfd(open(MOUNT_PATH "/.", O_RDONLY));
    ASSERT_TRUE(dirfd, "Cannot open root directory");

    fbl::unique_ptr<blob_info_t> info;
    ASSERT_TRUE(GenerateRandomBlob(1 << 12, &info));

    // Test ioctls which should ONLY operate on Blobs
    ASSERT_LT(ftruncate(dirfd.get(), info->size_data), 0);

    char buf[8];
    ASSERT_LT(write(dirfd.get(), buf, 8), 0, "Should not write to directory");
    ASSERT_LT(read(dirfd.get(), buf, 8), 0, "Should not read from directory");

    // Should NOT be able to unlink root dir
    ASSERT_EQ(close(dirfd.release()), 0);
    ASSERT_LT(unlink(info->path), 0);
    END_HELPER;
}

bool TestPartialWrite(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    fbl::unique_ptr<blob_info_t> info_complete;
    fbl::unique_ptr<blob_info_t> info_partial;
    size_t size = 1 << 20;
    ASSERT_TRUE(GenerateRandomBlob(size, &info_complete));
    ASSERT_TRUE(GenerateRandomBlob(size, &info_partial));

    // Partially write out first blob.
    fbl::unique_fd fd_partial(open(info_partial->path, O_CREAT | O_RDWR));
    ASSERT_TRUE(fd_partial, "Failed to create blob");
    ASSERT_EQ(ftruncate(fd_partial.get(), size), 0);
    ASSERT_EQ(StreamAll(write, fd_partial.get(), info_partial->data.get(), size / 2), 0,
              "Failed to write Data");

    // Completely write out second blob.
    fbl::unique_fd fd_complete;
    ASSERT_TRUE(MakeBlob(info_complete.get(), &fd_complete));

    ASSERT_EQ(close(fd_complete.release()), 0);
    ASSERT_EQ(close(fd_partial.release()), 0);
    END_HELPER;
}

bool TestPartialWriteSleepRamdisk(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    if (gUseRealDisk) {
        fprintf(stderr, "Ramdisk required; skipping test\n");
        return true;
    }

    fbl::unique_ptr<blob_info_t> info_complete;
    fbl::unique_ptr<blob_info_t> info_partial;
    size_t size = 1 << 20;
    ASSERT_TRUE(GenerateRandomBlob(size, &info_complete));
    ASSERT_TRUE(GenerateRandomBlob(size, &info_partial));

    // Partially write out first blob.
    fbl::unique_fd fd_partial(open(info_partial->path, O_CREAT | O_RDWR));
    ASSERT_TRUE(fd_partial, "Failed to create blob");
    ASSERT_EQ(ftruncate(fd_partial.get(), size), 0);
    ASSERT_EQ(StreamAll(write, fd_partial.get(), info_partial->data.get(), size / 2), 0,
              "Failed to write Data");

    // Completely write out second blob.
    fbl::unique_fd fd_complete;
    ASSERT_TRUE(MakeBlob(info_complete.get(), &fd_complete));

    ASSERT_EQ(syncfs(fd_complete.get()), 0);
    ASSERT_TRUE(blobfsTest->ToggleSleep());

    ASSERT_EQ(close(fd_complete.release()), 0);
    ASSERT_EQ(close(fd_partial.release()), 0);

    fd_complete.reset(open(info_complete->path, O_RDONLY));
    ASSERT_TRUE(fd_complete, "Failed to re-open blob");

    ASSERT_EQ(syncfs(fd_complete.get()), 0);
    ASSERT_TRUE(blobfsTest->ToggleSleep());

    ASSERT_TRUE(VerifyContents(fd_complete.get(), info_complete->data.get(), size));

    fd_partial.reset(open(info_partial->path, O_RDONLY));
    ASSERT_FALSE(fd_partial, "Should not be able to open invalid blob");
    ASSERT_EQ(close(fd_complete.release()), 0);
    END_HELPER;
}

enum TestState {
    empty,
    configured,
    readable,
};

typedef struct blob_state : public fbl::DoublyLinkedListable<fbl::unique_ptr<blob_state>> {
    blob_state(fbl::unique_ptr<blob_info_t> i)
        : info(fbl::move(i)), state(empty), writes_remaining(1) {
            bytes_remaining = info->size_data;
        }

    fbl::unique_ptr<blob_info_t> info;
    TestState state;
    fbl::unique_fd fd;
    size_t writes_remaining;
    size_t bytes_remaining;
} blob_state_t;

typedef struct blob_list {
    fbl::Mutex list_lock;
    fbl::DoublyLinkedList<fbl::unique_ptr<blob_state>> list;
    uint32_t blob_count = 0;
} blob_list_t;

// Make sure we do not exceed maximum fd count
static_assert(FDIO_MAX_FD >= 256, "");
constexpr uint32_t max_blobs = FDIO_MAX_FD - 32;

// Generate and open a new blob
bool blob_create_helper(blob_list_t* bl, unsigned* seed) {
    fbl::unique_ptr<blob_info_t> info;
    ASSERT_TRUE(GenerateRandomBlob(1 + (rand_r(seed) % (1 << 16)), &info));

    fbl::AllocChecker ac;
    fbl::unique_ptr<blob_state_t> state(new (&ac) blob_state(fbl::move(info)));
    ASSERT_EQ(ac.check(), true);

    {
        fbl::AutoLock al(&bl->list_lock);

        if (bl->blob_count >= max_blobs) {
            return true;
        }
        fbl::unique_fd fd(open(state->info->path, O_CREAT | O_RDWR));
        ASSERT_TRUE(fd, "Failed to create blob");
        state->fd.reset(fd.release());

        bl->list.push_front(fbl::move(state));
        bl->blob_count++;
    }
    return true;
}

// Allocate space for an open, empty blob
bool blob_config_helper(blob_list_t* bl) {
    fbl::unique_ptr<blob_state> state;
    {
        fbl::AutoLock al(&bl->list_lock);
        state = bl->list.pop_back();
    }

    if (state == nullptr) {
        return true;
    } else if (state->state == empty) {
        ASSERT_EQ(ftruncate(state->fd.get(), state->info->size_data), 0);
        state->state = configured;
    }
    {
        fbl::AutoLock al(&bl->list_lock);
        bl->list.push_front(fbl::move(state));
    }
    return true;
}

// Write the data for an open, partially written blob
bool blob_write_data_helper(blob_list_t* bl) {
    fbl::unique_ptr<blob_state> state;
    {
        fbl::AutoLock al(&bl->list_lock);
        state = bl->list.pop_back();
    }
    if (state == nullptr) {
        return true;
    } else if (state->state == configured) {
        size_t bytes_write = state->bytes_remaining / state->writes_remaining;
        size_t bytes_offset = state->info->size_data - state->bytes_remaining;
        ASSERT_EQ(StreamAll(write, state->fd.get(), state->info->data.get() + bytes_offset,
                            bytes_write), 0, "Failed to write Data");

        state->writes_remaining--;
        state->bytes_remaining -= bytes_write;
        if (state->writes_remaining == 0 && state->bytes_remaining == 0) {
            state->state = readable;
        }
    }
    {
        fbl::AutoLock al(&bl->list_lock);
        bl->list.push_front(fbl::move(state));
    }
    return true;
}

// Read the blob's data
bool blob_read_data_helper(blob_list_t* bl) {
    fbl::unique_ptr<blob_state> state;
    {
        fbl::AutoLock al(&bl->list_lock);
        state = bl->list.pop_back();
    }
    if (state == nullptr) {
        return true;
    } else if (state->state == readable) {
        ASSERT_TRUE(VerifyContents(state->fd.get(), state->info->data.get(),
                                   state->info->size_data));
    }
    {
        fbl::AutoLock al(&bl->list_lock);
        bl->list.push_front(fbl::move(state));
    }
    return true;
}

// Unlink the blob
bool blob_unlink_helper(blob_list_t* bl) {
    fbl::unique_ptr<blob_state> state;
    {
        fbl::AutoLock al(&bl->list_lock);
        state = bl->list.pop_back();
    }
    if (state == nullptr) {
        return true;
    }
    ASSERT_EQ(unlink(state->info->path), 0, "Could not unlink blob");
    ASSERT_EQ(close(state->fd.release()), 0, "Could not close blob");
    {
        fbl::AutoLock al(&bl->list_lock);
        bl->blob_count--;
    }
    return true;
}

bool blob_reopen_helper(blob_list_t* bl) {
    fbl::unique_ptr<blob_state> state;
    {
        fbl::AutoLock al(&bl->list_lock);
        state = bl->list.pop_back();
    }
    if (state == nullptr) {
        return true;
    } else if (state->state == readable) {
        ASSERT_EQ(close(state->fd.release()), 0, "Could not close blob");
        fbl::unique_fd fd(open(state->info->path, O_RDONLY));
        ASSERT_TRUE(fd, "Failed to reopen blob");
        state->fd.reset(fd.release());
    }
    {
        fbl::AutoLock al(&bl->list_lock);
        bl->list.push_front(fbl::move(state));
    }
    return true;
}

bool TestAlternateWrite(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    size_t num_blobs = 1;
    size_t num_writes = 100;
    unsigned int seed = static_cast<unsigned int>(zx_ticks_get());
    blob_list_t bl;

    for (size_t i = 0; i < num_blobs; i++) {
        ASSERT_TRUE(blob_create_helper(&bl, &seed));
        bl.list.front().writes_remaining = num_writes;
    }

    for (size_t i = 0; i < num_blobs; i++) {
        ASSERT_TRUE(blob_config_helper(&bl));
    }

    for (size_t i = 0; i < num_writes; i++) {
        for (size_t j = 0; j < num_blobs; j++) {
            ASSERT_TRUE(blob_write_data_helper(&bl));
        }
    }

    for (size_t i = 0; i < num_blobs; i++) {
        ASSERT_TRUE(blob_reopen_helper(&bl));
    }

    for (auto& state : bl.list) {
        ASSERT_TRUE(check_readable(state.fd.get()));
    }

    for (size_t i = 0; i < num_blobs; i++) {
        ASSERT_TRUE(blob_read_data_helper(&bl));
    }

    for (auto& state : bl.list) {
        ASSERT_EQ(close(state.fd.release()), 0);
    }
    END_HELPER;
}

static bool TestHugeBlobRandom(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    fbl::unique_ptr<blob_info_t> info;

    // This blob is extremely large, and will remain large
    // on disk. It is not easily compressible.
    ASSERT_TRUE(GenerateRandomBlob(2 * blobfs::WriteBufferSize(), &info));

    fbl::unique_fd fd;
    ASSERT_TRUE(MakeBlob(info.get(), &fd));
    ASSERT_EQ(close(fd.release()), 0);

    // We can re-open and verify the Blob as read-only
    fd.reset(open(info->path, O_RDONLY));
    ASSERT_TRUE(fd, "Failed to-reopen blob");
    ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
    ASSERT_EQ(close(fd.release()), 0);

    // We cannot re-open the blob as writable
    fd.reset(open(info->path, O_RDWR | O_CREAT));
    ASSERT_FALSE(fd, "Shouldn't be able to re-create blob that exists");
    fd.reset(open(info->path, O_RDWR));
    ASSERT_FALSE(fd, "Shouldn't be able to re-open blob as writable");
    fd.reset(open(info->path, O_WRONLY));
    ASSERT_FALSE(fd, "Shouldn't be able to re-open blob as writable");

    // Force decompression by remounting, re-accessing blob.
    ASSERT_TRUE(blobfsTest->Remount());
    fd.reset(open(info->path, O_RDONLY));
    ASSERT_TRUE(fd, "Failed to-reopen blob");
    ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
    ASSERT_EQ(close(fd.release()), 0);

    ASSERT_EQ(unlink(info->path), 0);
    END_HELPER;
}

static bool TestHugeBlobCompressible(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    fbl::unique_ptr<blob_info_t> info;

    // This blob is extremely large, and will remain large
    // on disk, even though is very compressible.
    ASSERT_TRUE(GenerateBlob([](char* data, size_t length) {
        RandomFill(data, length / 2);
        data = reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(data) + length / 2);
        memset(data, 'a', length / 2);
    }, 2 * blobfs::WriteBufferSize(), &info));

    fbl::unique_fd fd;
    ASSERT_TRUE(MakeBlob(info.get(), &fd));
    ASSERT_EQ(close(fd.release()), 0);

    // We can re-open and verify the Blob as read-only
    fd.reset(open(info->path, O_RDONLY));
    ASSERT_TRUE(fd, "Failed to-reopen blob");
    ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
    ASSERT_EQ(close(fd.release()), 0);

    // We cannot re-open the blob as writable
    fd.reset(open(info->path, O_RDWR | O_CREAT));
    ASSERT_FALSE(fd, "Shouldn't be able to re-create blob that exists");
    fd.reset(open(info->path, O_RDWR));
    ASSERT_FALSE(fd, "Shouldn't be able to re-open blob as writable");
    fd.reset(open(info->path, O_WRONLY));
    ASSERT_FALSE(fd, "Shouldn't be able to re-open blob as writable");

    // Force decompression by remounting, re-accessing blob.
    ASSERT_TRUE(blobfsTest->Remount());
    fd.reset(open(info->path, O_RDONLY));
    ASSERT_TRUE(fd, "Failed to-reopen blob");
    ASSERT_TRUE(VerifyContents(fd.get(), info->data.get(), info->size_data));
    ASSERT_EQ(close(fd.release()), 0);

    ASSERT_EQ(unlink(info->path), 0);
    END_HELPER;
}

static bool CreateUmountRemountLarge(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    blob_list_t bl;
    // TODO(smklein): Here, and elsewhere in this file, remove this source
    // of randomness to make the unit test deterministic -- fuzzing should
    // be the tool responsible for introducing randomness into the system.
    unsigned int seed = static_cast<unsigned int>(zx_ticks_get());
    unittest_printf("unmount_remount test using seed: %u\n", seed);

    // Do some operations...
    size_t num_ops = 5000;
    for (size_t i = 0; i < num_ops; ++i) {
        switch (rand_r(&seed) % 6) {
        case 0:
            ASSERT_TRUE(blob_create_helper(&bl, &seed));
            break;
        case 1:
            ASSERT_TRUE(blob_config_helper(&bl));
            break;
        case 2:
            ASSERT_TRUE(blob_write_data_helper(&bl));
            break;
        case 3:
            ASSERT_TRUE(blob_read_data_helper(&bl));
            break;
        case 4:
            ASSERT_TRUE(blob_reopen_helper(&bl));
            break;
        case 5:
            ASSERT_TRUE(blob_unlink_helper(&bl));
            break;
        }
    }

    // Close all currently opened nodes (REGARDLESS of their state)
    for (auto& state : bl.list) {
        ASSERT_EQ(close(state.fd.release()), 0);
    }

    // Unmount, remount
    ASSERT_TRUE(blobfsTest->Remount(), "Could not re-mount blobfs");

    for (auto& state : bl.list) {
        if (state.state == readable) {
            // If a blob was readable before being unmounted, it should still exist.
            fbl::unique_fd fd(open(state.info->path, O_RDONLY));
            ASSERT_TRUE(fd, "Failed to create blob");
            ASSERT_TRUE(VerifyContents(fd.get(), state.info->data.get(),
                                       state.info->size_data));
            ASSERT_EQ(unlink(state.info->path), 0);
            ASSERT_EQ(close(fd.release()), 0);
        } else {
            // ... otherwise, the blob should have been deleted.
            ASSERT_LT(open(state.info->path, O_RDONLY), 0);
        }
    }

    END_HELPER;
}

int unmount_remount_thread(void* arg) {
    blob_list_t* bl = static_cast<blob_list_t*>(arg);
    unsigned int seed = static_cast<unsigned int>(zx_ticks_get());
    unittest_printf("unmount_remount thread using seed: %u\n", seed);

    // Do some operations...
    size_t num_ops = 1000;
    for (size_t i = 0; i < num_ops; ++i) {
        switch (rand_r(&seed) % 6) {
        case 0:
            ASSERT_TRUE(blob_create_helper(bl, &seed));
            break;
        case 1:
            ASSERT_TRUE(blob_config_helper(bl));
            break;
        case 2:
            ASSERT_TRUE(blob_write_data_helper(bl));
            break;
        case 3:
            ASSERT_TRUE(blob_read_data_helper(bl));
            break;
        case 4:
            ASSERT_TRUE(blob_reopen_helper(bl));
            break;
        case 5:
            ASSERT_TRUE(blob_unlink_helper(bl));
            break;
        }
    }

    return 0;
}

static bool CreateUmountRemountLargeMultithreaded(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    blob_list_t bl;

    size_t num_threads = 10;
    fbl::AllocChecker ac;
    fbl::Array<thrd_t> threads(new (&ac) thrd_t[num_threads](), num_threads);
    ASSERT_TRUE(ac.check());

    // Launch all threads
    for (size_t i = 0; i < num_threads; i++) {
        ASSERT_EQ(thrd_create(&threads[i], unmount_remount_thread, &bl),
                  thrd_success);
    }

    // Wait for all threads to complete
    for (size_t i = 0; i < num_threads; i++) {
        int res;
        ASSERT_EQ(thrd_join(threads[i], &res), thrd_success);
        ASSERT_EQ(res, 0);
    }

    // Close all currently opened nodes (REGARDLESS of their state)
    for (auto& state : bl.list) {
        ASSERT_EQ(close(state.fd.release()), 0);
    }

    // Unmount, remount
    ASSERT_TRUE(blobfsTest->Remount(), "Could not re-mount blobfs");

    for (auto& state : bl.list) {
        if (state.state == readable) {
            // If a blob was readable before being unmounted, it should still exist.
            fbl::unique_fd fd(open(state.info->path, O_RDONLY));
            ASSERT_TRUE(fd, "Failed to create blob");
            ASSERT_TRUE(VerifyContents(fd.get(), state.info->data.get(),
                                       state.info->size_data));
            ASSERT_EQ(unlink(state.info->path), 0);
            ASSERT_EQ(close(fd.release()), 0);
        } else {
            // ... otherwise, the blob should have been deleted.
            ASSERT_LT(open(state.info->path, O_RDONLY), 0);
        }
    }

    END_HELPER;
}

static bool NoSpace(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    fbl::unique_ptr<blob_info_t> last_info = nullptr;

    // Keep generating blobs until we run out of space
    size_t count = 0;
    while (true) {
        fbl::unique_ptr<blob_info_t> info;
        ASSERT_TRUE(GenerateRandomBlob(1 << 17, &info));

        fbl::unique_fd fd(open(info->path, O_CREAT | O_RDWR));
        ASSERT_TRUE(fd, "Failed to create blob");
        int r = ftruncate(fd.get(), info->size_data);
        if (r < 0) {
            ASSERT_EQ(errno, ENOSPC, "Blobfs expected to run out of space");
            // We ran out of space, as expected. Can we allocate if we
            // unlink a previously allocated blob of the desired size?
            ASSERT_EQ(unlink(last_info->path), 0, "Unlinking old blob");
            ASSERT_EQ(ftruncate(fd.get(), info->size_data), 0, "Re-init after unlink");

            // Yay! allocated successfully.
            ASSERT_EQ(close(fd.release()), 0);
            break;
        }
        ASSERT_EQ(StreamAll(write, fd.get(), info->data.get(), info->size_data), 0,
                  "Failed to write Data");
        ASSERT_EQ(close(fd.release()), 0);
        last_info = fbl::move(info);

        if (++count % 50 == 0) {
            printf("Allocated %lu blobs\n", count);
        }
    }

    END_HELPER;
}

static bool QueryDevicePath(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    fbl::unique_fd dirfd(open(MOUNT_PATH "/.", O_RDONLY | O_ADMIN));
    ASSERT_TRUE(dirfd, "Cannot open root directory");

    char device_buffer[1024];
    char* device_path = static_cast<char*>(device_buffer);
    zx_status_t status;
    size_t path_len;
    fzl::FdioCaller caller(fbl::move(dirfd));
    ASSERT_EQ(fuchsia_io_DirectoryAdminGetDevicePath(caller.borrow_channel(), &status,
                                                     device_path, sizeof(device_buffer),
                                                     &path_len), ZX_OK);
    dirfd = caller.release();
    ASSERT_EQ(status, ZX_OK);
    ASSERT_GT(path_len, 0, "Device path not found");

    char actual_path[PATH_MAX];
    ASSERT_TRUE(blobfsTest->GetDevicePath(actual_path, PATH_MAX));
    ASSERT_EQ(strncmp(actual_path, device_path, path_len), 0, "Unexpected device path");
    ASSERT_EQ(close(dirfd.release()), 0);

    dirfd.reset(open(MOUNT_PATH "/.", O_RDONLY));
    ASSERT_TRUE(dirfd, "Cannot open root directory");
    caller.reset(fbl::move(dirfd));
    ASSERT_EQ(fuchsia_io_DirectoryAdminGetDevicePath(caller.borrow_channel(), &status,
                                                     device_path, sizeof(device_buffer),
                                                     &path_len), ZX_OK);
    dirfd = caller.release();
    ASSERT_EQ(status, ZX_ERR_ACCESS_DENIED);
    ASSERT_EQ(path_len, 0);
    ASSERT_EQ(close(dirfd.release()), 0);
    END_HELPER;
}

static bool TestReadOnly(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    // Mount the filesystem as read-write.
    // We can create new blobs.
    fbl::unique_ptr<blob_info_t> info;
    ASSERT_TRUE(GenerateRandomBlob(1 << 10, &info));
    fbl::unique_fd blob_fd;
    ASSERT_TRUE(MakeBlob(info.get(), &blob_fd));
    ASSERT_TRUE(VerifyContents(blob_fd.get(), info->data.get(), info->size_data));
    ASSERT_EQ(close(blob_fd.release()), 0);

    blobfsTest->SetReadOnly(true);
    ASSERT_TRUE(blobfsTest->Remount());

    // We can read old blobs
    blob_fd.reset(open(info->path, O_RDONLY));
    ASSERT_GE(blob_fd.get(), 0);
    ASSERT_TRUE(VerifyContents(blob_fd.get(), info->data.get(), info->size_data));
    ASSERT_EQ(close(blob_fd.release()), 0);

    // We cannot create new blobs
    ASSERT_TRUE(GenerateRandomBlob(1 << 10, &info));
    ASSERT_LT(open(info->path, O_CREAT | O_RDWR), 0);
    END_HELPER;
}

// This tests growing both additional inodes and blocks
static bool ResizePartition(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    ASSERT_EQ(blobfsTest->GetType(), FsTestType::kFvm);

    // Create 1000 blobs. Test slices are small enough that this will require both inodes and
    // blocks to be added
    for (size_t d = 0; d < 1000; d++) {
        if (d % 100 == 0) {
            printf("Creating blob: %lu\n", d);
        }

        fbl::unique_ptr<blob_info_t> info;
        ASSERT_TRUE(GenerateRandomBlob(64, &info));

        fbl::unique_fd fd;
        ASSERT_TRUE(MakeBlob(info.get(), &fd));
        ASSERT_EQ(close(fd.release()), 0);
    }

    printf("Remounting blobfs\n");
    // Remount partition
    ASSERT_TRUE(blobfsTest->Remount(), "Could not re-mount blobfs");

    DIR* dir = opendir(MOUNT_PATH);
    ASSERT_NONNULL(dir);
    unsigned entries_deleted = 0;
    char path[PATH_MAX];
    struct dirent* de;

    // Unlink all blobs
    while ((de = readdir(dir)) != nullptr) {
        if (entries_deleted % 100 == 0) {
            printf("Unlinking blob: %u\n", entries_deleted);
        }
        strcpy(path, MOUNT_PATH "/");
        strcat(path, de->d_name);
        ASSERT_EQ(unlink(path), 0);
        entries_deleted++;
    }

    printf("Completing test\n");
    ASSERT_EQ(closedir(dir), 0);
    ASSERT_EQ(entries_deleted, 1000);
    END_HELPER;
}

static bool CorruptAtMount(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    ASSERT_EQ(blobfsTest->GetType(), FsTestType::kFvm);
    ASSERT_TRUE(blobfsTest->Teardown());
    ASSERT_TRUE(blobfsTest->Reset());
    ASSERT_TRUE(blobfsTest->Init(FsTestState::kMinimal), "Mounting Blobfs");

    char device_path[PATH_MAX];
    ASSERT_TRUE(blobfsTest->GetDevicePath(device_path, PATH_MAX));
    ASSERT_EQ(mkfs(device_path, DISK_FORMAT_BLOBFS, launch_stdio_sync, &default_mkfs_options),
              ZX_OK);

    fbl::unique_fd fd(blobfsTest->GetFd());
    ASSERT_TRUE(fd, "Could not open ramdisk");

    // Manually shrink slice so FVM will differ from Blobfs.
    extend_request_t extend_request;
    extend_request.offset = blobfs::kFVMNodeMapStart / kBlocksPerSlice;
    extend_request.length = 1;
    ASSERT_EQ(ioctl_block_fvm_shrink(fd.get(), &extend_request), 0);

    // Verify that shrink was successful.
    query_request_t query_request;
    query_request.count = 1;
    query_request.vslice_start[0] = extend_request.offset;
    query_response_t query_response;
    ASSERT_EQ(ioctl_block_fvm_vslice_query(fd.get(), &query_request, &query_response),
              sizeof(query_response_t));
    ASSERT_EQ(query_request.count, query_response.count);
    ASSERT_FALSE(query_response.vslice_range[0].allocated);
    ASSERT_EQ(query_response.vslice_range[0].count,
              (blobfs::kFVMDataStart - blobfs::kFVMNodeMapStart) / kBlocksPerSlice);

    // Attempt to mount the VPart. This should fail since slices are missing.
    ASSERT_NE(mount(fd.release(), MOUNT_PATH, DISK_FORMAT_BLOBFS, &default_mount_options,
                    launch_stdio_async), ZX_OK);

    fd.reset(blobfsTest->GetFd());
    ASSERT_TRUE(fd, "Could not open ramdisk");

    // Manually grow slice count to twice what it was initially.
    extend_request.length = 2;
    ASSERT_EQ(ioctl_block_fvm_extend(fd.get(), &extend_request), 0);

    // Verify that extend was successful.
    ASSERT_EQ(ioctl_block_fvm_vslice_query(fd.get(), &query_request, &query_response),
              sizeof(query_response_t));
    ASSERT_EQ(query_request.count, query_response.count);
    ASSERT_TRUE(query_response.vslice_range[0].allocated);
    ASSERT_EQ(query_response.vslice_range[0].count, 2);

    // Attempt to mount the VPart. This should succeed.
    ASSERT_EQ(mount(fd.release(), MOUNT_PATH, DISK_FORMAT_BLOBFS, &default_mount_options,
                    launch_stdio_async), ZX_OK);

    ASSERT_EQ(umount(MOUNT_PATH), ZX_OK);
    fd.reset(blobfsTest->GetFd());
    ASSERT_TRUE(fd, "Could not open ramdisk");

    // Verify that mount automatically removed extra slice.
    ASSERT_EQ(ioctl_block_fvm_vslice_query(fd.get(), &query_request, &query_response),
              sizeof(query_response_t));
    ASSERT_EQ(query_request.count, query_response.count);
    ASSERT_TRUE(query_response.vslice_range[0].allocated);
    ASSERT_EQ(query_response.vslice_range[0].count, 1);

    END_HELPER;
}

typedef struct reopen_data {
    char path[PATH_MAX];
    fbl::atomic_bool complete;
} reopen_data_t;

int reopen_thread(void* arg) {
    reopen_data_t* dat = static_cast<reopen_data_t*>(arg);
    unsigned attempts = 0;
    while (!atomic_load(&dat->complete)) {
        fbl::unique_fd fd(open(dat->path, O_RDONLY));
        ASSERT_TRUE(fd);
        ASSERT_EQ(close(fd.release()), 0);
        attempts++;
    }

    printf("Reopened %u times\n", attempts);
    return 0;
}

// The purpose of this test is to repro the case where a blob is being retrieved from the blob hash
// at the same time it is being destructed, causing an invalid vnode to be returned. This can only
// occur when the client is opening a new fd to the blob at the same time it is being destructed
// after all writes to disk have completed.
// This test works best if a sleep is added at the beginning of fbl_recycle in VnodeBlob.
static bool CreateWriteReopen(BlobfsTest* blobfsTest) {
    BEGIN_HELPER;
    size_t num_ops = 10;

    fbl::unique_ptr<blob_info_t> anchor_info;
    ASSERT_TRUE(GenerateRandomBlob(1 << 10, &anchor_info));

    fbl::unique_ptr<blob_info_t> info;
    ASSERT_TRUE(GenerateRandomBlob(10 * (1 << 20), &info));
    reopen_data_t dat;
    strcpy(dat.path, info->path);

    for (size_t i = 0; i < num_ops; i++) {
        printf("Running op %lu... ", i);
        fbl::unique_fd fd;
        fbl::unique_fd anchor_fd;
        atomic_store(&dat.complete, false);

        // Write both blobs to disk (without verification, so we can start reopening the blob asap)
        ASSERT_TRUE(MakeBlobUnverified(info.get(), &fd));
        ASSERT_TRUE(MakeBlobUnverified(anchor_info.get(), &anchor_fd));
        ASSERT_EQ(close(fd.release()), 0);

        thrd_t thread;
        ASSERT_EQ(thrd_create(&thread, reopen_thread, &dat), thrd_success);

        // Sleep while the thread continually opens and closes the blob
        usleep(1000000);
        ASSERT_EQ(syncfs(anchor_fd.get()), 0);
        atomic_store(&dat.complete, true);

        int res;
        ASSERT_EQ(thrd_join(thread, &res), thrd_success);
        ASSERT_EQ(res, 0);

        ASSERT_EQ(close(anchor_fd.release()), 0);
        ASSERT_EQ(unlink(info->path), 0);
        ASSERT_EQ(unlink(anchor_info->path), 0);
    }

    END_HELPER;
}

// Ensure Compressor returns an error if we try to compress more data than the buffer can hold.
static bool TestCompressorBufferTooSmall(void) {
    BEGIN_TEST;
    blobfs::Compressor c;

    // Pretend we're going to compress only one byte of data.
    const size_t buf_size = c.BufferMax(1);
    fbl::AllocChecker ac;
    fbl::unique_ptr<char[]> buf(new (&ac) char[buf_size]);
    EXPECT_EQ(ac.check(), true);
    ASSERT_EQ(c.Initialize(buf.get(), buf_size), ZX_OK);

    // Create data that is just too big to fit within this buffer size.
    size_t data_size = 0;
    while (c.BufferMax(++data_size) <= buf_size) {}
    ASSERT_GT(data_size, 0);

    unsigned int seed = 0;
    fbl::unique_ptr<char[]> data(new (&ac) char[data_size]);
    EXPECT_EQ(ac.check(), true);

    for (size_t i = 0; i < data_size; i++) {
        data[i] = static_cast<char>(rand_r(&seed));
    }

    ASSERT_EQ(c.Update(&data, data_size), ZX_ERR_IO_DATA_INTEGRITY);
    END_TEST;
}

BEGIN_TEST_CASE(blobfs_tests)
RUN_TESTS(MEDIUM, TestBasic)
RUN_TESTS(MEDIUM, TestNullBlob)
RUN_TESTS(MEDIUM, TestCompressibleBlob)
RUN_TESTS(MEDIUM, TestMmap)
RUN_TESTS(MEDIUM, TestMmapUseAfterClose)
RUN_TESTS(MEDIUM, TestReaddir)
RUN_TESTS(MEDIUM, TestDiskTooSmall)
RUN_TEST_FVM(MEDIUM, TestQueryInfo)
RUN_TESTS(MEDIUM, UseAfterUnlink)
RUN_TESTS(MEDIUM, WriteAfterRead)
RUN_TESTS(MEDIUM, WriteAfterUnlink)
RUN_TESTS(MEDIUM, ReadTooLarge)
RUN_TESTS(MEDIUM, BadAllocation)
RUN_TESTS_SILENT(MEDIUM, CorruptedBlob)
RUN_TESTS_SILENT(MEDIUM, CorruptedDigest)
RUN_TESTS(MEDIUM, EdgeAllocation)
RUN_TESTS(MEDIUM, UmountWithOpenFile)
RUN_TESTS(MEDIUM, UmountWithMappedFile)
RUN_TESTS(MEDIUM, UmountWithOpenMappedFile)
RUN_TESTS(MEDIUM, CreateUmountRemountSmall)
RUN_TESTS(MEDIUM, EarlyRead)
RUN_TESTS(MEDIUM, WaitForRead)
RUN_TESTS(MEDIUM, WriteSeekIgnored)
RUN_TESTS(MEDIUM, UnlinkTiming)
RUN_TESTS(MEDIUM, InvalidOps)
RUN_TESTS(MEDIUM, RootDirectory)
RUN_TESTS(MEDIUM, TestPartialWrite)
RUN_TESTS(MEDIUM, TestPartialWriteSleepRamdisk)
RUN_TESTS(MEDIUM, TestAlternateWrite)
RUN_TESTS(LARGE, TestHugeBlobRandom)
RUN_TESTS(LARGE, TestHugeBlobCompressible)
RUN_TESTS(LARGE, CreateUmountRemountLarge)
RUN_TESTS(LARGE, CreateUmountRemountLargeMultithreaded)
RUN_TESTS(LARGE, NoSpace)
RUN_TESTS(MEDIUM, QueryDevicePath)
RUN_TESTS(MEDIUM, TestReadOnly)
RUN_TEST_FVM(MEDIUM, ResizePartition)
RUN_TEST_FVM(MEDIUM, CorruptAtMount)
RUN_TESTS(LARGE, CreateWriteReopen)
RUN_TEST(TestCompressorBufferTooSmall);
END_TEST_CASE(blobfs_tests)

static void print_test_help(FILE* f) {
    fprintf(f,
            "  -d <blkdev>\n"
            "      Use block device <blkdev> instead of a ramdisk\n"
            "  -f <count>\n"
            "      For each test, run the test <count> additional times,\n"
            "        intentionally causing the underlying device driver to\n"
            "        'sleep' after a certain number of block writes.\n"
            "      After each additional test, the blobfs partition will be\n"
            "        remounted and checked for consistency via fsck.\n"
            "      If <count> is 0, the maximum number of tests are run.\n"
            "      This option is only valid when using a ramdisk.\n"
            "\n");
}

int main(int argc, char** argv) {
    unittest_register_test_help_printer(print_test_help);

    int i = 1;
    while (i < argc) {
        if (!strcmp(argv[i], "-d") && (i + 1 < argc)) {
            fbl::unique_fd fd(open(argv[i + 1], O_RDWR));
            if (!fd) {
                fprintf(stderr, "[fs] Could not open block device\n");
                return -1;
            } else if (ioctl_device_get_topo_path(fd.get(), gRealDiskInfo.disk_path, PATH_MAX)
                       < 0) {
                fprintf(stderr, "[fs] Could not acquire topological path of block device\n");
                return -1;
            }

            // If we previously tried running tests on this disk, it may
            // have created an FVM and failed. (Try to) clean up from previous state
            // before re-running.
            fvm_destroy(gRealDiskInfo.disk_path);

            block_info_t block_info;
            ssize_t rc = ioctl_block_get_info(fd.get(), &block_info);

            if (rc < 0 || rc != sizeof(block_info)) {
                fprintf(stderr, "[fs] Could not query block device info\n");
                return -1;
            }

            gUseRealDisk = true;
            gRealDiskInfo.blk_size = block_info.block_size;
            gRealDiskInfo.blk_count = block_info.block_count;

            size_t disk_size = gRealDiskInfo.blk_size * gRealDiskInfo.blk_count;
            if (disk_size < kBytesNormalMinimum) {
                fprintf(stderr, "Error: Insufficient disk space for tests");
                return -1;
            } else if (disk_size < kTotalBytesFvmMinimum) {
                fprintf(stderr, "Error: Insufficient disk space for FVM tests");
                return -1;
            }
            i += 2;
        } else if (!strcmp(argv[i], "-f") && (i + 1 < argc)) {
            gEnableRamdiskFailure = true;
            gRamdiskFailureLoops = atoi(argv[i + 1]);
            i += 2;
        } else {
            // Ignore options we don't recognize. See ulib/unittest/README.md.
            break;
        }
    }

    if (gUseRealDisk && gEnableRamdiskFailure) {
        fprintf(stderr, "Error: Ramdisk failure not allowed for real disk\n");
        return -1;
    }

    // Initialize tmpfs.
    async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
    if (loop.StartThread() != ZX_OK) {
        fprintf(stderr, "Error: Cannot initialize local tmpfs loop\n");
        return -1;
    }
    if (memfs_install_at(loop.dispatcher(), TMPFS_PATH) != ZX_OK) {
        fprintf(stderr, "Error: Cannot install local tmpfs\n");
        return -1;
    }

    return unittest_run_all_tests(argc, argv) ? 0 : -1;
}
