// Copyright 2018 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 <fcntl.h>
#include <stdio.h>

#include <blobfs/common.h>
#include <fbl/auto_call.h>
#include <fbl/function.h>
#include <fbl/string.h>
#include <fbl/unique_fd.h>
#include <fs-test-utils/fixture.h>
#include <fuchsia/hardware/block/c/fidl.h>
#include <lib/fzl/fdio.h>
#include <ramdevice-client/ramdisk.h>
#include <unittest/unittest.h>
#include <zircon/device/block.h>
#include <zircon/syscalls.h>

namespace fs_test_utils {
namespace {

zx_status_t GetBlockDeviceInfo(const fbl::String& block_device_path,
                               fuchsia_hardware_block_BlockInfo* blk_info) {
    fbl::unique_fd fd(open(block_device_path.c_str(), O_RDONLY));
    fzl::FdioCaller disk_caller(std::move(fd));
    zx_status_t status;
    zx_status_t io_status = fuchsia_hardware_block_BlockGetInfo(disk_caller.borrow_channel(),
                                                                &status, blk_info);
    if (io_status != ZX_OK) {
        return io_status;
    }
    if (status != ZX_OK) {
        return status;
    }
    return ZX_OK;
}

bool IsValidBlockDeviceOnlyTrue() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    options.block_device_path = "some_block_device";
    ASSERT_TRUE(options.IsValid(&err_str), err_str.c_str());
    ASSERT_TRUE(err_str.empty());
    END_TEST;
}

bool IsValidUseRamdiskTrue() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    options.use_ramdisk = true;
    options.ramdisk_block_size = 512;
    options.ramdisk_block_count = 1;
    ASSERT_TRUE(options.IsValid(&err_str), err_str.c_str());
    ASSERT_TRUE(err_str.empty());
    END_TEST;
}

bool IsValidUseFvmTrue() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    fbl::String err_str;
    options.use_fvm = true;
    options.fvm_slice_size = kFvmBlockSize;
    ASSERT_TRUE(options.IsValid(&err_str), err_str.c_str());
    ASSERT_TRUE(err_str.empty());
    END_TEST;
}

bool IsValidEmptyIsFalse() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

bool IsValidDefaultIsTrue() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    fbl::String err_str;
    ASSERT_TRUE(options.IsValid(&err_str));
    ASSERT_TRUE(err_str.empty());
    END_TEST;
}

bool IsValidBlockAndRamdiskSetIsFalse() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    options.block_device_path = "some_block_device";
    options.use_ramdisk = true;
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

bool IsValidRamdiskBlockCountIsZeroFalse() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    options.use_ramdisk = true;
    options.ramdisk_block_count = 0;
    options.ramdisk_block_size = 512;
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

bool IsValidRamdiskBlockSizeIsZeroFalse() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    options.use_ramdisk = true;
    options.ramdisk_block_count = 10;
    options.ramdisk_block_size = 0;
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

bool IsValidFvmSlizeSizeIsZeroFalse() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    fbl::String err_str;
    options.use_fvm = true;
    options.fvm_slice_size = 0;
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

bool IsValidFvmSlizeSizeIsNotMultipleOfFvmBlockSizeFalse() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    fbl::String err_str;
    options.use_fvm = true;
    options.fvm_slice_size = kFvmBlockSize + 3;
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

bool IsValidNoBlockDeviceFalse() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    options.block_device_path = "";
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

BEGIN_TEST_CASE(FixtureOptionsTests);
RUN_TEST(IsValidBlockDeviceOnlyTrue);
RUN_TEST(IsValidUseRamdiskTrue);
RUN_TEST(IsValidUseFvmTrue);
RUN_TEST(IsValidDefaultIsTrue);
RUN_TEST(IsValidEmptyIsFalse);
RUN_TEST(IsValidNoBlockDeviceFalse);
RUN_TEST(IsValidBlockAndRamdiskSetIsFalse);
RUN_TEST(IsValidRamdiskBlockCountIsZeroFalse);
RUN_TEST(IsValidRamdiskBlockSizeIsZeroFalse);
RUN_TEST(IsValidFvmSlizeSizeIsZeroFalse);
RUN_TEST(IsValidFvmSlizeSizeIsNotMultipleOfFvmBlockSizeFalse);
END_TEST_CASE(FixtureOptionsTests)

bool RamdiskSetupAndCleanup() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    Fixture fixture(options);
    fixture.SetUpTestCase();
    ASSERT_TRUE(!fixture.block_device_path().empty());
    fuchsia_hardware_block_BlockInfo ramdisk_info;
    ASSERT_EQ(GetBlockDeviceInfo(fixture.block_device_path(), &ramdisk_info), ZX_OK);
    ASSERT_EQ(ramdisk_info.block_count, options.ramdisk_block_count);
    ASSERT_EQ(ramdisk_info.block_size, options.ramdisk_block_size);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    fbl::unique_fd ramdisk_fd(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_FALSE(ramdisk_fd);
    END_TEST;
}

bool DiskIsFormattedCorrectlyNoFvm() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    // Check device format.
    fbl::unique_fd blk_fd(open(fixture.GetFsBlockDevice().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    disk_format_t actual = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual, DISK_FORMAT_MINFS);
    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    // Verify nothing is mounted anymore.
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_ERR_NOT_FOUND);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool DiskAndFvmAreFormattedCorrectly() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.use_fvm = true;
    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    // Check device format.
    fbl::unique_fd blk_fd(open(fixture.GetFsBlockDevice().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    disk_format_t actual = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual, DISK_FORMAT_MINFS);

    fbl::unique_fd fvm_blk_fd(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(fvm_blk_fd);
    disk_format_t fvm_actual = detect_disk_format(fvm_blk_fd.get());
    ASSERT_EQ(fvm_actual, DISK_FORMAT_FVM);

    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    // Verify nothing is mounted anymore.
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_ERR_NOT_FOUND);

    ASSERT_TRUE(fvm_blk_fd);
    fvm_actual = detect_disk_format(fvm_blk_fd.get());
    ASSERT_EQ(fvm_actual, DISK_FORMAT_UNKNOWN);

    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool UseBlockDeviceIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.use_ramdisk = false;

    // Create a Ramdisk which will be passed as the 'block_device'.
    ramdisk_client_t* ramdisk = nullptr;
    ASSERT_EQ(ramdisk_create(options.ramdisk_block_size,
                             options.ramdisk_block_count, &ramdisk),
              ZX_OK);
    options.block_device_path = ramdisk_get_path(ramdisk);

    auto clean_up = fbl::MakeAutoCall([&ramdisk]() {
        ramdisk_destroy(ramdisk);
    });

    mkfs_options_t mkfs_options = default_mkfs_options;
    ASSERT_EQ(mkfs(options.block_device_path.c_str(), DISK_FORMAT_BLOBFS,
                   launch_stdio_sync, &mkfs_options),
              ZX_OK);

    Fixture fixture(options);

    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    EXPECT_TRUE(options.block_device_path == fixture.block_device_path());
    EXPECT_TRUE(options.block_device_path == fixture.GetFsBlockDevice());
    fbl::unique_fd blk_fd(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    disk_format_t actual_format = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_BLOBFS);

    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    blk_fd.reset(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    actual_format = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_MINFS);

    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    blk_fd.reset(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    actual_format = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_MINFS);

    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool UseBlockDeviceWithFvmIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.use_ramdisk = false;
    options.use_fvm = true;

    // Create a Ramdisk which will be passed as the 'block_device'.
    ramdisk_client_t* ramdisk = nullptr;
    ASSERT_EQ(ramdisk_create(options.ramdisk_block_size,
                             options.ramdisk_block_count, &ramdisk),
              ZX_OK);
    options.block_device_path = ramdisk_get_path(ramdisk);

    auto clean_up = fbl::MakeAutoCall([&ramdisk]() {
        ramdisk_destroy(ramdisk);
    });

    mkfs_options_t mkfs_options = default_mkfs_options;
    ASSERT_EQ(mkfs(options.block_device_path.c_str(), DISK_FORMAT_BLOBFS,
                   launch_stdio_sync, &mkfs_options),
              ZX_OK);

    Fixture fixture(options);

    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    EXPECT_TRUE(options.block_device_path == fixture.block_device_path());
    EXPECT_TRUE(fixture.GetFsBlockDevice().empty());
    fbl::unique_fd blk_fd(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    disk_format_t actual_format = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_BLOBFS);

    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    blk_fd.reset(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    actual_format = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_FVM);

    blk_fd.reset(open(fixture.GetFsBlockDevice().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    actual_format = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_MINFS);

    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    blk_fd.reset(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    actual_format = detect_disk_format(blk_fd.get());
    // Destroying the FVM should leave this in unknown format.
    ASSERT_EQ(actual_format, DISK_FORMAT_UNKNOWN);

    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool SkipFormatIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.use_ramdisk = false;
    options.fs_format = false;

    // Create a Ramdisk which will be passed as the 'block_device'.
    ramdisk_client_t* ramdisk = nullptr;
    ASSERT_EQ(ramdisk_create(options.ramdisk_block_size,
                             options.ramdisk_block_count, &ramdisk),
              ZX_OK);
    options.block_device_path = ramdisk_get_path(ramdisk);

    auto clean_up = fbl::MakeAutoCall([&ramdisk]() {
        ramdisk_destroy(ramdisk);
    });

    mkfs_options_t mkfs_options = default_mkfs_options;
    ASSERT_EQ(mkfs(options.block_device_path.c_str(), DISK_FORMAT_BLOBFS,
                   launch_stdio_sync, &mkfs_options),
              ZX_OK);

    Fixture fixture(options);

    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    EXPECT_TRUE(options.block_device_path == fixture.block_device_path());
    EXPECT_TRUE(options.block_device_path == fixture.GetFsBlockDevice());
    fbl::unique_fd block_fd(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(block_fd);
    disk_format_t actual_format = detect_disk_format(block_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_BLOBFS);

    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    block_fd.reset(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(block_fd);
    actual_format = detect_disk_format(block_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_BLOBFS);

    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    block_fd.reset(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(block_fd);
    actual_format = detect_disk_format(block_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_BLOBFS);

    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool SkipMountIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.fs_mount = false;

    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);

    // Verify nothing is mounted anymore.
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_ERR_NOT_FOUND);
    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool MountIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.fs_mount = false;

    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_ERR_NOT_FOUND);
    ASSERT_EQ(fixture.Mount(), ZX_OK);
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_OK);

    // Since we need to try to umount to verify if the device is mounted,
    // the fixture still sees the device as mounted, so it will try to umount
    // and fail with not found, which is ok.
    ASSERT_EQ(fixture.TearDown(), ZX_ERR_NOT_FOUND);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool UmountIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.fs_mount = true;

    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    ASSERT_EQ(fixture.Umount(), ZX_OK);
    // Verify nothing is mounted anymore.
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_ERR_NOT_FOUND);
    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool RemountIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.fs_mount = true;

    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    ASSERT_EQ(fixture.Remount(), ZX_OK);
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_OK);
    // Teardown will return this error because we manually umount the underlying
    ASSERT_EQ(fixture.TearDown(), ZX_ERR_NOT_FOUND);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool FsckIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    options.fs_mount = false;

    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    // running fsck on a freshly formatted disk should never fail.
    ASSERT_EQ(fixture.Fsck(), ZX_OK);
    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);

    END_TEST;
}

bool FsckFails() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    options.fs_mount = false;

    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    // corrupt the disk!
    // right now we don't have a way to manipulate the internals of the
    // filesystem to get it into a corrupt state, so we take advantage of the
    // fact that we know where things are on disk and can just muck with them
    // directly. we just set a giant array to all 1 and squash the node map.
    uint8_t data[8192];
    memset(data, 0xffffffff, 8192);
    int dev = open(fixture.GetFsBlockDevice().c_str(), O_RDWR);
    if (dev < 0) {
        LOG_ERROR(0, "failed to open device\n");
    }
    ASSERT_EQ(blobfs::writeblk(dev, 1, data), ZX_OK);
    int r3 = close(dev);
    if (r3 < 0) {
        LOG_ERROR(0, "failed to close\n");
    }
    sync();
    // fsck should fail...the filesystem is obviously corrupt!
    ASSERT_EQ(fixture.Fsck(), ZX_ERR_BAD_STATE);
    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);

    END_TEST;
}

bool FsckMounted() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);

    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    ASSERT_EQ(fixture.Fsck(), ZX_ERR_BAD_STATE);
    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);

    END_TEST;
}

bool FsckUnformatted() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    options.fs_format = false;
    options.fs_mount = false;

    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    ASSERT_EQ(fixture.Fsck(), ZX_ERR_BAD_STATE);
    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);

    END_TEST;
}

bool FsckNoBlockDevice() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    options.use_ramdisk = false;
    options.fs_format = false;
    options.fs_mount = false;

    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    ASSERT_EQ(fixture.Fsck(), ZX_ERR_BAD_STATE);
    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);

    END_TEST;
}

BEGIN_TEST_CASE(FixtureTest);
RUN_TEST(RamdiskSetupAndCleanup);
RUN_TEST(DiskIsFormattedCorrectlyNoFvm);
RUN_TEST(DiskAndFvmAreFormattedCorrectly);
RUN_TEST(UseBlockDeviceIsOk);
RUN_TEST(UseBlockDeviceWithFvmIsOk);
RUN_TEST(SkipFormatIsOk);
RUN_TEST(SkipMountIsOk);
RUN_TEST(MountIsOk);
RUN_TEST(UmountIsOk);
RUN_TEST(RemountIsOk);
RUN_TEST(FsckIsOk);
RUN_TEST(FsckFails);
RUN_TEST(FsckMounted);
RUN_TEST(FsckUnformatted);
RUN_TEST(FsckNoBlockDevice);
END_TEST_CASE(FixtureTest)

} // namespace
} // namespace fs_test_utils
