// Copyright 2019 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 <blobfs/format.h>
#include <blobfs/mkfs.h>
#include <block-client/cpp/fake-device.h>
#include <zxtest/zxtest.h>

#include "blobfs.h"

namespace blobfs {
namespace {

using block_client::FakeBlockDevice;
using block_client::FakeFVMBlockDevice;

zx_status_t CheckMountability(std::unique_ptr<BlockDevice> device) {
  MountOptions options = {};
  options.writability = Writability::ReadOnlyFilesystem;
  options.metrics = false;
  options.journal = true;
  std::unique_ptr<Blobfs> blobfs = nullptr;
  return Blobfs::Create(nullptr, std::move(device), &options, zx::resource(), &blobfs);
}

// Formatting filesystems should fail on devices that cannot be written.
TEST(FormatFilesystemTest, CannotFormatReadOnlyDevice) {
  auto device = std::make_unique<FakeBlockDevice>(1 << 20, 512);
  device->SetInfoFlags(fuchsia_hardware_block_FLAG_READONLY);
  ASSERT_EQ(ZX_ERR_ACCESS_DENIED, FormatFilesystem(device.get()));
}

// Formatting filesystems should fail on devices that don't contain any blocks.
TEST(FormatFilesystemTest, CannotFormatEmptyDevice) {
  auto device = std::make_unique<FakeBlockDevice>(0, 0);
  ASSERT_EQ(ZX_ERR_NO_SPACE, FormatFilesystem(device.get()));
}

// Formatting filesystems should fail on devices that aren't empty, but are
// still too small to contain a filesystem.
TEST(FormatFilesystemTest, CannotFormatSmallDevice) {
  auto device = std::make_unique<FakeBlockDevice>(1, 512);
  ASSERT_EQ(ZX_ERR_NO_SPACE, FormatFilesystem(device.get()));
}

// Formatting filesystems should fail on devices which have a block size that
// does not cleanly divide the blobfs block size.
TEST(FormatFilesystemTest, CannotFormatDeviceWithNonDivisorBlockSize) {
  const uint64_t kBlockCount = 1 << 20;
  uint64_t kBlockSize = 511;
  EXPECT_NE(kBlobfsBlockSize % kBlockSize, 0, "Expected non-divisor block size");
  auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
  ASSERT_EQ(ZX_ERR_IO_INVALID, FormatFilesystem(device.get()));
}

// Calculates the smallest number of blobfs blocks to generate a valid blobfs format.
constexpr uint64_t MinimumFilesystemBlocks() {
  const uint64_t kSuperBlockBlocks = 1;
  const uint64_t kInodeBlocks = sizeof(Inode) * kBlobfsDefaultInodeCount / kBlobfsBlockSize;
  const uint64_t kJournalBlocks = kMinimumJournalBlocks;
  const uint64_t kDataBlocks = kMinimumDataBlocks;
  const uint64_t kBlockMapBlocks = fbl::round_up(kDataBlocks, kBlobfsBlockBits) / kBlobfsBlockBits;

  return kSuperBlockBlocks + kInodeBlocks + kJournalBlocks + kDataBlocks + kBlockMapBlocks;
}

// Blobfs can be formatted on the smallest possible device.
TEST(FormatFilesystemTest, FormatNonFVMSmallestDevice) {
  const uint32_t kBlockSize = 512;
  const uint64_t kDiskBlockRatio = kBlobfsBlockSize / kBlockSize;
  const uint64_t kBlockCount = kDiskBlockRatio * MinimumFilesystemBlocks();

  // Smallest possible device.
  {
    auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
    ASSERT_OK(FormatFilesystem(device.get()));
    ASSERT_OK(CheckMountability(std::move(device)));
  }

  // One block smaller than the smallest possible device.
  {
    auto device = std::make_unique<FakeBlockDevice>(kBlockCount - 1, kBlockSize);
    ASSERT_EQ(ZX_ERR_NO_SPACE, FormatFilesystem(device.get()));
  }
}

// Calculates the smallest number of blobfs slices to generate a valid blobfs format.
uint64_t MinimumFilesystemSlices(uint64_t kSliceSize) {
  uint64_t kBlocksPerSlice = kSliceSize / kBlobfsBlockSize;
  auto BlocksToSlices = [kBlocksPerSlice](uint64_t blocks) {
    return fbl::round_up(blocks, kBlocksPerSlice) / kBlocksPerSlice;
  };

  const uint64_t kSuperBlockSlices = BlocksToSlices(1);
  const uint64_t kInodeSlices = 1;
  const uint64_t kJournalSlices = BlocksToSlices(kDefaultJournalBlocks);
  const uint64_t kDataSlices = BlocksToSlices(kMinimumDataBlocks);
  const uint64_t kBlockMapSlices = BlocksToSlices(BlocksRequiredForBits(kMinimumDataBlocks));

  return kSuperBlockSlices + kInodeSlices + kJournalSlices + kDataSlices + kBlockMapSlices;
}

TEST(FormatFilesystemTest, FormatFVMSmallestDevice) {
  const uint32_t kBlockSize = 512;
  const uint64_t kSliceSize = kBlobfsBlockSize * 8;
  const uint64_t kSliceCount = MinimumFilesystemSlices(kSliceSize);
  const uint64_t kDiskBlockRatio = kBlobfsBlockSize / kBlockSize;
  const uint64_t kBlockCount = kDiskBlockRatio * MinimumFilesystemBlocks();

  // Smallest possible device.
  {
    auto device =
        std::make_unique<FakeFVMBlockDevice>(kBlockCount, kBlockSize, kSliceSize, kSliceCount);
    ASSERT_OK(FormatFilesystem(device.get()));
    ASSERT_OK(CheckMountability(std::move(device)));
  }

  // One slice smaller than the smallest possible device.
  {
    auto device =
        std::make_unique<FakeFVMBlockDevice>(kBlockCount, kBlockSize, kSliceSize, kSliceCount - 1);
    ASSERT_EQ(ZX_ERR_NO_SPACE, FormatFilesystem(device.get()));
  }
}

// Blobfs can be formatted on slightly larger devices as well.
TEST(FormatFilesystemTest, FormatNonFVMDevice) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = 512;
  auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
  ASSERT_OK(FormatFilesystem(device.get()));
  ASSERT_OK(CheckMountability(std::move(device)));
}

TEST(FormatFilesystemTest, FormatFVMDevice) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = 512;
  const uint64_t kSliceSize = kBlobfsBlockSize * 8;
  const uint64_t kSliceCount = 1028;
  auto device =
      std::make_unique<FakeFVMBlockDevice>(kBlockCount, kBlockSize, kSliceSize, kSliceCount);
  ASSERT_OK(FormatFilesystem(device.get()));
  ASSERT_OK(CheckMountability(std::move(device)));
}

// Blobfs can be formatted on devices that have "trailing device block(s)" that
// cannot be fully addressed by blobfs blocks.
TEST(FormatFilesystemTest, FormatNonFVMDeviceWithTrailingDiskBlock) {
  const uint64_t kBlockCount = (1 << 20) + 1;
  const uint32_t kBlockSize = 512;
  auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
  ASSERT_OK(FormatFilesystem(device.get()));
  ASSERT_OK(CheckMountability(std::move(device)));
}

TEST(FormatFilesystemTest, FormatFVMDeviceWithTrailingDiskBlock) {
  const uint64_t kBlockCount = (1 << 20) + 1;
  const uint32_t kBlockSize = 512;
  const uint64_t kSliceSize = kBlobfsBlockSize * 8;
  const uint64_t kSliceCount = 1028;
  auto device =
      std::make_unique<FakeFVMBlockDevice>(kBlockCount, kBlockSize, kSliceSize, kSliceCount);
  ASSERT_OK(FormatFilesystem(device.get()));
  ASSERT_OK(CheckMountability(std::move(device)));
}

// Blobfs can be formatted on devices that have block sizes up to and including
// the blobfs block size itself.
TEST(FormatFilesystemTest, FormatNonFVMDeviceWithLargestBlockSize) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = kBlobfsBlockSize;
  auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
  ASSERT_OK(FormatFilesystem(device.get()));
  ASSERT_OK(CheckMountability(std::move(device)));
}

TEST(FormatFilesystemTest, FormatFVMDeviceWithLargestBlockSize) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = kBlobfsBlockSize;
  const uint64_t kSliceSize = kBlobfsBlockSize * 8;
  const uint64_t kSliceCount = 1028;
  auto device =
      std::make_unique<FakeFVMBlockDevice>(kBlockCount, kBlockSize, kSliceSize, kSliceCount);
  ASSERT_OK(FormatFilesystem(device.get()));
  ASSERT_OK(CheckMountability(std::move(device)));
}

// Blobfs cannot be formatted on devices that have block sizes larger than the
// blobfs block size itself.
TEST(FormatFilesystemTest, FormatNonFVMDeviceWithTooLargeBlockSize) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = kBlobfsBlockSize * 2;
  auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
  ASSERT_EQ(ZX_ERR_IO_INVALID, FormatFilesystem(device.get()));
  ASSERT_EQ(ZX_ERR_IO, CheckMountability(std::move(device)));
}

TEST(FormatFilesystemTest, FormatFVMDeviceWithTooLargeBlockSize) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = kBlobfsBlockSize * 2;
  const uint64_t kSliceSize = kBlobfsBlockSize * 8;
  const uint64_t kSliceCount = 1028;
  auto device =
      std::make_unique<FakeFVMBlockDevice>(kBlockCount, kBlockSize, kSliceSize, kSliceCount);
  ASSERT_EQ(ZX_ERR_IO_INVALID, FormatFilesystem(device.get()));
  ASSERT_EQ(ZX_ERR_IO, CheckMountability(std::move(device)));
}

// Validates that a formatted filesystem, mounted as writable, is converted
// to read-only on a device that is not writable.
TEST(FormatFilesystemTest, FormatDeviceNoJournalAutoConvertReadonly) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = kBlobfsBlockSize;
  auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
  ASSERT_OK(FormatFilesystem(device.get()));
  device->SetInfoFlags(fuchsia_hardware_block_FLAG_READONLY);

  MountOptions mount_options = {};
  mount_options.writability = Writability::Writable;
  mount_options.metrics = false;
  mount_options.journal = false;
  std::unique_ptr<Blobfs> fs = nullptr;
  ASSERT_OK(Blobfs::Create(nullptr, std::move(device), &mount_options, zx::resource(), &fs));
  ASSERT_EQ(Writability::ReadOnlyDisk, fs->writability());
}

// Validates that a formatted filesystem mounted as writable with a journal cannot be mounted on a
// read-only device. This "auto-conversion" is disabled because journal replay is necessary
// to guarantee filesystem correctness, which involves writeback.
TEST(FormatFilesystemTest, FormatDeviceWithJournalCannotAutoConvertReadonly) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = kBlobfsBlockSize;
  auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
  ASSERT_OK(FormatFilesystem(device.get()));
  device->SetInfoFlags(fuchsia_hardware_block_FLAG_READONLY);

  MountOptions options = {};
  options.writability = Writability::Writable;
  options.metrics = false;
  options.journal = true;
  std::unique_ptr<Blobfs> blobfs = nullptr;
  ASSERT_EQ(ZX_ERR_ACCESS_DENIED,
            Blobfs::Create(nullptr, std::move(device), &options, zx::resource(), &blobfs));
}

// After formatting a filesystem with block size valid block size N, mounting on
// a device with an invalid block size should fail.
TEST(FormatFilesystemTest, CreateBlobfsFailureOnUnalignedBlockSize) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = 512;
  auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
  ASSERT_OK(FormatFilesystem(device.get()));
  device->SetBlockSize(kBlockSize + 1);
  ASSERT_EQ(ZX_ERR_IO, CheckMountability(std::move(device)));
}

// After formatting a filesystem with block size valid block count N, mounting
// on a device less M blocks (for M < N) should fail.
TEST(FormatFilesystemTest, CreateBlobfsFailureWithLessBlocks) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = 512;
  auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
  ASSERT_OK(FormatFilesystem(device.get()));
  device->SetBlockCount(kBlockCount - 1);
  ASSERT_EQ(ZX_ERR_BAD_STATE, CheckMountability(std::move(device)));
}

// After formatting a filesystem with block size valid block count N, mounting
// on a device less M blocks (for M > N) should succeed.
TEST(FormatFilesystemTest, CreateBlobfsSuccessWithMoreBlocks) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = 512;
  auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
  ASSERT_OK(FormatFilesystem(device.get()));
  device->SetBlockCount(kBlockCount + 1);
  ASSERT_OK(CheckMountability(std::move(device)));
}

// Blobfs cannot be formatted on an FVM with a slice size smaller than a block size.
TEST(FormatFilesystemTest, FormatFVMDeviceWithTooSmallSliceSize) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = kBlobfsBlockSize;
  const uint64_t kSliceSize = kBlobfsBlockSize / 2;
  const uint64_t kSliceCount = 1028;
  auto device =
      std::make_unique<FakeFVMBlockDevice>(kBlockCount, kBlockSize, kSliceSize, kSliceCount);
  ASSERT_EQ(ZX_ERR_IO_INVALID, FormatFilesystem(device.get()));
  ASSERT_EQ(ZX_ERR_INVALID_ARGS, CheckMountability(std::move(device)));
}

// Blobfs can be formatted on an FVM with a slice slice equal to a block size.
TEST(FormatFilesystemTest, FormatFVMDeviceWithSmallestSliceSize) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = kBlobfsBlockSize;
  const uint64_t kSliceSize = kBlobfsBlockSize;
  const uint64_t kSliceCount = 1028;
  auto device =
      std::make_unique<FakeFVMBlockDevice>(kBlockCount, kBlockSize, kSliceSize, kSliceCount);
  ASSERT_OK(FormatFilesystem(device.get()));
  ASSERT_OK(CheckMountability(std::move(device)));
}

// Blobfs cannot be formatted on an FVM with a slice size that does not divide
// the blobfs block size.
TEST(FormatFilesystemTest, FormatFVMDeviceWithNonDivisibleSliceSize) {
  const uint64_t kBlockCount = 1 << 20;
  const uint32_t kBlockSize = kBlobfsBlockSize;
  const uint64_t kSliceSize = kBlobfsBlockSize * 8 + 1;
  const uint64_t kSliceCount = 1028;
  auto device =
      std::make_unique<FakeFVMBlockDevice>(kBlockCount, kBlockSize, kSliceSize, kSliceCount);
  ASSERT_EQ(ZX_ERR_IO_INVALID, FormatFilesystem(device.get()));
  ASSERT_EQ(ZX_ERR_INVALID_ARGS, CheckMountability(std::move(device)));
}

}  // namespace
}  // namespace blobfs
