// 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 <fuchsia/device/llcpp/fidl.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/fdio/watcher.h>
#include <zircon/assert.h>
#include <zircon/device/block.h>
#include <zircon/hw/gpt.h>

#include <string_view>

#include <fbl/string_printf.h>
#include <gtest/gtest.h>
#include <ramdevice-client/ramdisk.h>

#include "block-device-interface.h"
#include "block-device-manager.h"
#include "block-watcher-test-data.h"
#include "encrypted-volume-interface.h"
#include "mock-block-device.h"
#include "src/lib/files/glob.h"
#include "src/lib/isolated_devmgr/v2_component/ram_disk.h"
#include "src/storage/fshost/fshost_integration_test.h"

namespace devmgr {
namespace {

Config::Options TestOptions() { return Config::DefaultOptions(); }
Config::Options FactoryOptions() {
  auto options = TestOptions();
  options.insert({Config::kFactory, {}});
  return options;
}
Config::Options DurableOptions() {
  auto options = TestOptions();
  options.insert({Config::kDurable, {}});
  return options;
}

// Tests adding a device which has an unknown format.
TEST(AddDeviceTestCase, AddUnknownDevice) {
  MockBlockDevice device;
  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  EXPECT_EQ(ZX_ERR_NOT_SUPPORTED, manager.AddDevice(device));
}

// Tests adding a device which is smaller than the expected header size
TEST(AddDeviceTestCase, AddSmallDevice) {
  class SmallDevice : public MockBlockDevice {
   public:
    zx_status_t GetInfo(fuchsia_hardware_block_BlockInfo* out_info) const override {
      fuchsia_hardware_block_BlockInfo info = {};
      info.flags = 0;
      info.block_size = 512;
      info.block_count = 1;
      *out_info = info;
      return ZX_OK;
    }
  };
  SmallDevice device;
  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  EXPECT_EQ(ZX_ERR_NOT_SUPPORTED, manager.AddDevice(device));
}

// Tests adding a device with a GPT format.
TEST(AddDeviceTestCase, AddGPTDevice) {
  MockBlockDevice device(MockBlockDevice::GptOptions());
  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(device.attached());
}

// Tests adding a device with an FVM format.
TEST(AddDeviceTestCase, AddFVMDevice) {
  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice device(MockBlockDevice::FvmOptions());
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(device.attached());
}

// Tests adding a device with an MBR format.
TEST(AddDeviceTestCase, AddMBRDevice) {
  auto options = TestOptions();
  options[Config::kMbr] = std::string();
  Config config(options);
  BlockDeviceManager manager(&config);
  MockBlockDevice device(MockBlockDevice::Options{
      .content_format = DISK_FORMAT_MBR,
      .driver_path = kMBRDriverPath,
  });
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(device.attached());
}

TEST(AddDeviceTestCase, AddBlockVerityDevice) {
  Config config(FactoryOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice gpt_device(MockBlockDevice::GptOptions());
  EXPECT_EQ(manager.AddDevice(gpt_device), ZX_OK);
  MockBlockVerityDevice device(/*allow_authoring=*/true);
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(device.attached());
}

TEST(AddDeviceTestCase, NonFactoryBlockVerityDeviceNotAttached) {
  Config config(FactoryOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice gpt_device(MockBlockDevice::GptOptions());
  EXPECT_EQ(manager.AddDevice(gpt_device), ZX_OK);
  MockBlockDevice::Options options = MockBlockVerityDevice::VerityOptions();
  options.partition_name = "not-factory";
  MockBlockVerityDevice device(/*allow_authoring=*/true, options);
  EXPECT_EQ(manager.AddDevice(device), ZX_ERR_NOT_SUPPORTED);
  EXPECT_FALSE(device.attached());
}

// Tests adding a device with the block-verity disk format
TEST(AddDeviceTestCase, AddFormattedBlockVerityDevice) {
  Config config(FactoryOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice gpt_device(MockBlockDevice::GptOptions());
  EXPECT_EQ(manager.AddDevice(gpt_device), ZX_OK);
  MockSealedBlockVerityDevice device;
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(device.attached());
  EXPECT_TRUE(device.opened());
}

// Tests adding a device with block-verity format but no seal provided by
// bootloader
TEST(AddDeviceTestCase, AddFormattedBlockVerityDeviceWithoutSeal) {
  class BlockVerityDeviceWithNoSeal : public MockBlockVerityDevice {
   public:
    BlockVerityDeviceWithNoSeal() : MockBlockVerityDevice(/*allow_authoring=*/false) {}

    zx::status<std::string> VeritySeal() final {
      seal_read_ = true;
      return zx::error_status(ZX_ERR_NOT_FOUND);
    }
    zx_status_t OpenBlockVerityForVerifiedRead(std::string seal_hex) final {
      ADD_FAILURE() << "Should not call OpenBlockVerityForVerifiedRead";
      return ZX_OK;
    }
    bool seal_read() const { return seal_read_; }

   private:
    bool seal_read_ = false;
  };
  Config config(FactoryOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice gpt_device(MockBlockDevice::GptOptions());
  EXPECT_EQ(manager.AddDevice(gpt_device), ZX_OK);
  BlockVerityDeviceWithNoSeal device;
  EXPECT_EQ(ZX_ERR_NOT_FOUND, manager.AddDevice(device));
  EXPECT_TRUE(device.attached());
  EXPECT_TRUE(device.seal_read());
}

// Tests adding a device with block-verity format while in factory authoring mode
TEST(AddDeviceTestCase, AddFormattedBlockVerityDeviceInAuthoringMode) {
  class BlockVerityDeviceInAuthoringMode : public MockBlockVerityDevice {
   public:
    BlockVerityDeviceInAuthoringMode() : MockBlockVerityDevice(/*allow_authoring=*/true) {}

    zx::status<std::string> VeritySeal() final {
      ADD_FAILURE() << "Should not call VeritySeal";
      return zx::error_status(ZX_ERR_NOT_FOUND);
    }
    zx_status_t OpenBlockVerityForVerifiedRead(std::string seal_hex) final {
      ADD_FAILURE() << "Should not call OpenBlockVerityForVerifiedRead";
      return ZX_OK;
    }
  };
  Config config(FactoryOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice gpt_device(MockBlockDevice::GptOptions());
  EXPECT_EQ(manager.AddDevice(gpt_device), ZX_OK);
  BlockVerityDeviceInAuthoringMode device;
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(device.attached());
}

// Tests adding blobfs which does not not have a valid type GUID.
TEST(AddDeviceTestCase, AddNoGUIDBlobDevice) {
  class BlobDeviceWithInvalidTypeGuid : public MockBlobfsDevice {
   public:
    const fuchsia_hardware_block_partition_GUID& GetTypeGuid() const final {
      static fuchsia_hardware_block_partition_GUID guid = GUID_TEST_VALUE;
      return guid;
    }
  };

  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
  EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  BlobDeviceWithInvalidTypeGuid device;
  EXPECT_EQ(ZX_ERR_NOT_SUPPORTED, manager.AddDevice(device));
  EXPECT_FALSE(device.mounted());
}

// Tests adding blobfs with a valid type GUID, but invalid metadata.
TEST(AddDeviceTestCase, AddInvalidBlobDevice) {
  class BlobDeviceWithInvalidMetadata : public MockBlobfsDevice {
   public:
    zx_status_t CheckFilesystem() final {
      MockBlobfsDevice::CheckFilesystem();
      return ZX_ERR_BAD_STATE;
    }
  };
  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
  EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  BlobDeviceWithInvalidMetadata device;
  EXPECT_EQ(ZX_ERR_BAD_STATE, manager.AddDevice(device));
  EXPECT_TRUE(device.checked());
  EXPECT_FALSE(device.formatted());
  EXPECT_FALSE(device.mounted());
}

// Tests adding blobfs with a valid type GUID and valid metadata.
TEST(AddDeviceTestCase, AddValidBlobDevice) {
  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
  EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  MockBlobfsDevice device;
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(device.checked());
  EXPECT_FALSE(device.formatted());
  EXPECT_TRUE(device.mounted());
}

TEST(AddDeviceTestCase, NetbootingDoesNotMountBlobfs) {
  auto options = TestOptions();
  options[Config::kNetboot] = std::string();
  Config config(options);
  BlockDeviceManager manager(&config);
  MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
  EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  MockBlobfsDevice device;
  EXPECT_EQ(ZX_ERR_NOT_SUPPORTED, manager.AddDevice(device));
  EXPECT_FALSE(device.mounted());
}

// Tests adding minfs which does not not have a valid type GUID.
TEST(AddDeviceTestCase, AddNoGUIDMinfsDevice) {
  class MinfsDeviceWithInvalidGuid : public MockBlockDevice {
   public:
    using MockBlockDevice::MockBlockDevice;

    const fuchsia_hardware_block_partition_GUID& GetTypeGuid() const final {
      static fuchsia_hardware_block_partition_GUID guid = GUID_TEST_VALUE;
      return guid;
    }
  };
  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
  EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  MinfsDeviceWithInvalidGuid device(MockZxcryptDevice::ZxcryptOptions());
  EXPECT_EQ(ZX_ERR_NOT_SUPPORTED, manager.AddDevice(device));
  EXPECT_FALSE(device.attached());
}

// Tests adding minfs with a valid type GUID and invalid metadata. Observe that
// the filesystem reformats itself.
TEST(AddDeviceTestCase, AddInvalidMinfsDeviceWithFormatOnCorruptionEnabled) {
  class MinfsDeviceWithInvalidMetadata : public MockMinfsDevice {
   public:
    zx_status_t CheckFilesystem() final {
      MockMinfsDevice::CheckFilesystem();
      return ZX_ERR_BAD_STATE;
    }
  };
  auto options = TestOptions();
  Config config(options);
  EXPECT_TRUE(config.is_set(Config::kFormatMinfsOnCorruption));
  BlockDeviceManager manager(&config);
  MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
  EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  MockZxcryptDevice zxcrypt_device;
  EXPECT_EQ(manager.AddDevice(zxcrypt_device), ZX_OK);
  MinfsDeviceWithInvalidMetadata device;
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(device.checked());
  EXPECT_TRUE(device.formatted());
  EXPECT_TRUE(device.mounted());
}

// Tests adding minfs with a valid type GUID and invalid metadata. Observe that
// the filesystem does not reformats itself and adding device fails.
TEST(AddDeviceTestCase, AddInvalidMinfsDeviceWithFormatOnCorruptionDisabled) {
  class MinfsDeviceWithInvalidMetadata : public MockMinfsDevice {
   public:
    zx_status_t CheckFilesystem() final {
      MockMinfsDevice::CheckFilesystem();
      return ZX_ERR_BAD_STATE;
    }
  };
  auto options = TestOptions();
  EXPECT_EQ(options.erase(Config::kFormatMinfsOnCorruption), 1ul);
  Config config(options);
  EXPECT_FALSE(config.is_set(Config::kFormatMinfsOnCorruption));
  BlockDeviceManager manager(&config);
  MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
  EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  MockZxcryptDevice zxcrypt_device;
  EXPECT_EQ(manager.AddDevice(zxcrypt_device), ZX_OK);
  MinfsDeviceWithInvalidMetadata device;
  EXPECT_EQ(ZX_ERR_BAD_STATE, manager.AddDevice(device));
}

// Tests adding zxcrypt with a valid type GUID and invalid format. Observe that
// the partition reformats itself.
TEST(AddDeviceTestCase, FormatZxcryptDevice) {
  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
  EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  MockBlockDevice::Options options = MockZxcryptDevice::ZxcryptOptions();
  options.content_format = DISK_FORMAT_UNKNOWN;
  MockZxcryptDevice zxcrypt_device(options);
  EXPECT_EQ(manager.AddDevice(zxcrypt_device), ZX_OK);
  MockMinfsDevice device;
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(zxcrypt_device.formatted_zxcrypt());
  EXPECT_TRUE(device.formatted());
  EXPECT_TRUE(device.mounted());
}

// Tests adding zxcrypt with a valid type GUID and minfs format i.e. it's a minfs partition without
// zxcrypt. Observe that the partition reformats itself.
TEST(AddDeviceTestCase, FormatMinfsDeviceWithZxcrypt) {
  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
  EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  MockBlockDevice::Options options = MockZxcryptDevice::ZxcryptOptions();
  options.content_format = DISK_FORMAT_MINFS;
  MockZxcryptDevice zxcrypt_device(options);
  EXPECT_EQ(manager.AddDevice(zxcrypt_device), ZX_OK);
  MockMinfsDevice device;
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(zxcrypt_device.formatted_zxcrypt());
  EXPECT_TRUE(device.formatted());
  EXPECT_TRUE(device.mounted());
}

TEST(AddDeviceTestCase, MinfsWithNoZxcryptOptionMountsWithoutZxcrypt) {
  auto options = TestOptions();
  options[Config::kNoZxcrypt] = std::string();
  Config config(options);
  BlockDeviceManager manager(&config);
  MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
  EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  auto minfs_options = MockMinfsDevice::MinfsOptions();
  minfs_options.topological_path = MockBlockDevice::BaseTopologicalPath() + "/fvm/minfs-p-2/block";
  minfs_options.partition_name = "minfs";
  MockMinfsDevice device(minfs_options);
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(device.mounted());
}

TEST(AddDeviceTestCase, MinfsRamdiskMounts) {
  // The fvm-ramdisk option will check that the topological path actually has an expected ramdisk
  // prefix.
  auto manager_options = TestOptions();
  manager_options[Config::kFvmRamdisk] = std::string();
  Config config(manager_options);
  BlockDeviceManager manager(&config);
  auto options = MockBlockDevice::FvmOptions();
  constexpr std::string_view kBasePath = "/dev/misc/ramctl/mock_device/block";
  options.topological_path = kBasePath;
  MockBlockDevice fvm_device(options);
  EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  options = MockMinfsDevice::MinfsOptions();
  options.topological_path = std::string(kBasePath) + "/fvm/minfs-p-2/block";
  options.partition_name = "minfs";
  MockMinfsDevice device(options);
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(device.mounted());
}

TEST(AddDeviceTestCase, MinfsRamdiskDeviceNotRamdiskDoesNotMount) {
  auto options = TestOptions();
  options[Config::kFvmRamdisk] = std::string();
  options[Config::kAttachZxcryptToNonRamdisk] = std::string();
  Config config(options);
  BlockDeviceManager manager(&config);
  auto fvm_options = MockBlockDevice::FvmOptions();
  fvm_options.topological_path = "/dev/misc/ramctl/mock_device/block";
  MockBlockDevice ramdisk_fvm_device(fvm_options);
  EXPECT_EQ(manager.AddDevice(ramdisk_fvm_device), ZX_OK);
  MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
  EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  MockZxcryptDevice zxcrypt_device;
  EXPECT_EQ(manager.AddDevice(zxcrypt_device), ZX_OK);
  MockMinfsDevice device;
  EXPECT_EQ(manager.AddDevice(device), ZX_ERR_NOT_SUPPORTED);
  EXPECT_FALSE(device.mounted());
}

TEST(AddDeviceTestCase, MinfsRamdiskWithoutZxcryptAttachOption) {
  auto options = TestOptions();
  options[Config::kFvmRamdisk] = std::string();
  Config config(options);
  BlockDeviceManager manager(&config);
  MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
  EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  MockZxcryptDevice zxcrypt_device;
  EXPECT_EQ(manager.AddDevice(zxcrypt_device), ZX_ERR_NOT_SUPPORTED);
}

TEST(AddDeviceTestCase, MinfsWithAlternateNameMounts) {
  Config config(TestOptions());
  for (std::string name : {GUID_DATA_NAME, "data"}) {
    BlockDeviceManager manager(&config);
    MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
    EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
    MockZxcryptDevice zxcrypt_device;
    EXPECT_EQ(manager.AddDevice(zxcrypt_device), ZX_OK);
    auto minfs_options = MockMinfsDevice::MinfsOptions();
    minfs_options.partition_name = name;
    MockMinfsDevice device(minfs_options);
    EXPECT_EQ(manager.AddDevice(device), ZX_OK);
    EXPECT_TRUE(device.mounted());
  }
}

// Durable partition tests
// Tests adding minfs on durable partition with a valid type GUID and valid metadata.
TEST(AddDeviceTestCase, AddValidDurableDevice) {
  class DurableZxcryptDevice : public MockZxcryptDevice {
   public:
    DurableZxcryptDevice()
        : MockZxcryptDevice(Options{
              .content_format = DISK_FORMAT_ZXCRYPT,
              .driver_path = kZxcryptDriverPath,
              .topological_path =
                  MockBlockDevice::BaseTopologicalPath() + "/" GPT_DURABLE_NAME "-004/block",
              .partition_name = GPT_DURABLE_NAME,
          }) {}

    const fuchsia_hardware_block_partition_GUID& GetTypeGuid() const final {
      static fuchsia_hardware_block_partition_GUID guid = GPT_DURABLE_TYPE_GUID;
      return guid;
    }
  };
  class DurableDevice : public MockBlockDevice {
   public:
    using MockBlockDevice::MockBlockDevice;

    const fuchsia_hardware_block_partition_GUID& GetTypeGuid() const final {
      static fuchsia_hardware_block_partition_GUID guid = GPT_DURABLE_TYPE_GUID;
      return guid;
    }
    zx_status_t CheckFilesystem() final {
      checked_ = true;
      return ZX_OK;
    }
    zx_status_t FormatFilesystem() final {
      formatted_ = true;
      return ZX_OK;
    }
    zx_status_t MountFilesystem() final {
      mounted_ = true;
      return ZX_OK;
    }

    bool checked() const { return checked_; }
    bool formatted() const { return formatted_; }
    bool mounted() const { return mounted_; }

   private:
    bool checked_ = false;
    bool formatted_ = false;
    bool mounted_ = false;
  };
  Config config(DurableOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice gpt_device(MockBlockDevice::GptOptions());
  EXPECT_EQ(manager.AddDevice(gpt_device), ZX_OK);
  DurableZxcryptDevice zxcrypt_device;
  EXPECT_EQ(manager.AddDevice(zxcrypt_device), ZX_OK);
  DurableDevice device(MockBlockDevice::DurableOptions());
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(device.checked());
  EXPECT_FALSE(device.formatted());
  EXPECT_TRUE(device.mounted());
}

// Tests adding a boot partition device with unknown format can be added with
// the correct driver.
TEST(AddDeviceTestCase, AddUnknownFormatBootPartitionDevice) {
  class BootPartDevice : public MockBlockDevice {
   public:
    BootPartDevice()
        : MockBlockDevice(Options{
              .driver_path = kBootpartDriverPath,
          }) {}
    zx_status_t GetInfo(fuchsia_hardware_block_BlockInfo* out_info) const override {
      fuchsia_hardware_block_BlockInfo info = {};
      info.flags = BLOCK_FLAG_BOOTPART;
      info.block_size = 512;
      info.block_count = 1024;
      *out_info = info;
      return ZX_OK;
    }
  };
  BootPartDevice device;
  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(device.attached());
}

TEST(AddDeviceTestCase, AddPermanentlyMiskeyedZxcryptVolume) {
  class ZxcryptVolume : public devmgr::EncryptedVolumeInterface {
   public:
    zx_status_t Unseal() final {
      // Simulate a device where we've lost the key -- can't unlock until we
      // format the device with a new key, but can afterwards.
      if (formatted) {
        postformat_unseal_attempt_count++;
        return ZX_OK;
      } else {
        preformat_unseal_attempt_count++;
        return ZX_ERR_ACCESS_DENIED;
      }
    }
    zx_status_t Format() final {
      formatted = true;
      return ZX_OK;
    }

    int preformat_unseal_attempt_count = 0;
    int postformat_unseal_attempt_count = 0;
    bool formatted = false;
  };
  ZxcryptVolume volume;
  EXPECT_EQ(volume.EnsureUnsealedAndFormatIfNeeded(), ZX_OK);
  EXPECT_TRUE(volume.preformat_unseal_attempt_count > 1);
  EXPECT_TRUE(volume.formatted);
  EXPECT_EQ(volume.postformat_unseal_attempt_count, 1);
}

TEST(AddDeviceTestCase, AddTransientlyMiskeyedZxcryptVolume) {
  class ZxcryptVolume : public devmgr::EncryptedVolumeInterface {
   public:
    zx_status_t Unseal() final {
      // Simulate a transient error -- fail the first time we try to unseal the
      // volume, but succeed on a retry or any subsequent attempt.
      unseal_attempt_count++;
      if (unseal_attempt_count > 1) {
        return ZX_OK;
      } else {
        return ZX_ERR_ACCESS_DENIED;
      }
    }

    zx_status_t Format() final {
      // We expect this to never be called.
      formatted = true;
      return ZX_OK;
    }

    int unseal_attempt_count = 0;
    bool formatted = false;
  };
  ZxcryptVolume volume;
  EXPECT_EQ(volume.EnsureUnsealedAndFormatIfNeeded(), ZX_OK);
  EXPECT_FALSE(volume.formatted);
  EXPECT_EQ(volume.unseal_attempt_count, 2);
}

TEST(AddDeviceTestCase, AddFailingZxcryptVolumeShouldNotFormat) {
  class ZxcryptVolume : public devmgr::EncryptedVolumeInterface {
   public:
    zx_status_t Unseal() final {
      // Errors that are not ZX_ERR_ACCESS_DENIED should not trigger
      // formatting.
      return ZX_ERR_INTERNAL;
    }
    zx_status_t Format() final {
      // Expect this to not be called.
      formatted = true;
      return ZX_OK;
    }

    bool formatted = false;
  };
  ZxcryptVolume volume;
  EXPECT_EQ(ZX_ERR_INTERNAL, volume.EnsureUnsealedAndFormatIfNeeded());
  EXPECT_FALSE(volume.formatted);
}

// Tests adding factoryfs with valid factoryfs magic, as a verified child of a
// block-verity device, but with invalid metadata.
TEST(AddDeviceTestCase, AddInvalidFactoryfsDevice) {
  class FactoryfsWithInvalidMetadata : public MockFactoryfsDevice {
    zx_status_t CheckFilesystem() override {
      MockFactoryfsDevice::CheckFilesystem();
      return ZX_ERR_BAD_STATE;
    }
  };
  Config config(FactoryOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice gpt_device(MockBlockDevice::GptOptions());
  EXPECT_EQ(manager.AddDevice(gpt_device), ZX_OK);
  MockSealedBlockVerityDevice verity_device;
  EXPECT_EQ(manager.AddDevice(verity_device), ZX_OK);
  FactoryfsWithInvalidMetadata device;
  EXPECT_EQ(ZX_ERR_BAD_STATE, manager.AddDevice(device));
  EXPECT_TRUE(device.checked());
  EXPECT_FALSE(device.formatted());
  EXPECT_FALSE(device.mounted());
}

// Tests adding factoryfs with valid fasctoryfs magic, as a verified child of a
// block-verity device, and valid metadata.
TEST(AddDeviceTestCase, AddValidFactoryfsDevice) {
  Config config(FactoryOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice gpt_device(MockBlockDevice::GptOptions());
  EXPECT_EQ(manager.AddDevice(gpt_device), ZX_OK);
  MockSealedBlockVerityDevice verity_device;
  EXPECT_EQ(manager.AddDevice(verity_device), ZX_OK);
  MockFactoryfsDevice device;
  EXPECT_EQ(manager.AddDevice(device), ZX_OK);
  EXPECT_TRUE(device.checked());
  EXPECT_FALSE(device.formatted());
  EXPECT_TRUE(device.mounted());
}

// Tests adding factoryfs with a valid superblock, as a device which is not a
// verified child of a block-verity device.
TEST(AddDeviceTestCase, AddUnverifiedFactoryFsDevice) {
  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  MockBlockDevice gpt_device(MockBlockDevice::GptOptions());
  EXPECT_EQ(manager.AddDevice(gpt_device), ZX_OK);
  MockFactoryfsDevice device;
  EXPECT_EQ(manager.AddDevice(device), ZX_ERR_NOT_SUPPORTED);
  EXPECT_FALSE(device.checked());
  EXPECT_FALSE(device.formatted());
  EXPECT_FALSE(device.mounted());
}

TEST(AddDeviceTestCase, MultipleFvmDevicesDoNotMatch) {
  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  {
    MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
    EXPECT_EQ(manager.AddDevice(fvm_device), ZX_OK);
  }
  // If another FVM device appears, it should fail.
  {
    MockBlockDevice fvm_device(MockBlockDevice::FvmOptions());
    EXPECT_EQ(ZX_ERR_NOT_SUPPORTED, manager.AddDevice(fvm_device));
  }
}

TEST(AddDeviceTestCase, MultipleGptDevicesDoNotMatch) {
  Config config(TestOptions());
  BlockDeviceManager manager(&config);
  {
    MockBlockDevice gpt_device(MockBlockDevice::GptOptions());
    EXPECT_EQ(manager.AddDevice(gpt_device), ZX_OK);
  }
  // If another GPT device appears, it should fail.
  {
    MockBlockDevice gpt_device(MockBlockDevice::GptOptions());
    EXPECT_EQ(ZX_ERR_NOT_SUPPORTED, manager.AddDevice(gpt_device));
  }
}

TEST(AddDeviceTestCase, MultipleGptDevicesWithGptAllOptionMatch) {
  auto options = TestOptions();
  options.insert({Config::kGptAll, {}});
  Config config(options);
  BlockDeviceManager manager(&config);
  {
    MockBlockDevice gpt_device(MockBlockDevice::GptOptions());
    EXPECT_EQ(manager.AddDevice(gpt_device), ZX_OK);
  }
  {
    MockBlockDevice gpt_device(MockBlockDevice::GptOptions());
    EXPECT_EQ(manager.AddDevice(gpt_device), ZX_OK);
  }
}

class BlockWatcherTest : public FshostIntegrationTest {
 protected:
  isolated_devmgr::RamDisk CreateGptRamdisk() {
    zx::vmo ramdisk_vmo;
    EXPECT_EQ(zx::vmo::create(kTestDiskSectors * kBlockSize, 0, &ramdisk_vmo), ZX_OK);
    // Write the GPT into the VMO.
    EXPECT_EQ(ramdisk_vmo.write(kTestGptProtectiveMbr, 0, sizeof(kTestGptProtectiveMbr)), ZX_OK);
    EXPECT_EQ(ramdisk_vmo.write(kTestGptBlock1, kBlockSize, sizeof(kTestGptBlock1)), ZX_OK);
    EXPECT_EQ(ramdisk_vmo.write(kTestGptBlock2, 2 * kBlockSize, sizeof(kTestGptBlock2)), ZX_OK);

    return isolated_devmgr::RamDisk::CreateWithVmo(std::move(ramdisk_vmo), kBlockSize).value();
  }

  fbl::unique_fd WaitForBlockDevice(int number) {
    auto path = fbl::StringPrintf("/dev/class/block/%03d", number);
    EXPECT_EQ(wait_for_device(path.data(), ZX_TIME_INFINITE), ZX_OK);
    return fbl::unique_fd(open(path.data(), O_RDWR));
  }

  // Check that the number of block devices bound by the block watcher
  // matches what we expect. Can only be called while the block watcher is running.
  //
  // This works by adding a new block device with a valid GPT.
  // We then wait for that block device to appear at class/block/|next_device_number|.
  // The block watcher should then bind the GPT driver to that block device, causing
  // another entry in class/block to appear representing the only partition on the GPT.
  //
  // We make sure that this entry's toplogical path corresponds to it being the first partition
  // of the block device we added.
  void CheckEventsDropped(int& next_device_number, isolated_devmgr::RamDisk& ramdisk) {
    ASSERT_NO_FATAL_FAILURE(ramdisk = CreateGptRamdisk());

    // Wait for the basic block driver to be bound
    WaitForBlockDevice(next_device_number);
    next_device_number += 1;

    // And now, wait for the GPT driver to be bound, and the first
    // partition to appear.
    fbl::unique_fd fd = WaitForBlockDevice(next_device_number);
    next_device_number += 1;

    // Figure out the expected topological path of the last block device.
    std::string expected_path = ramdisk.path() + "/part-000/block";

    fidl::ClientEnd<llcpp::fuchsia::device::Controller> controller;
    ASSERT_EQ(fdio_get_service_handle(fd.release(), controller.channel().reset_and_get_address()),
              ZX_OK);
    // Get the actual topological path of the block device.
    auto result = fidl::BindSyncClient(std::move(controller)).GetTopologicalPath();
    ASSERT_EQ(result.status(), ZX_OK);
    ASSERT_FALSE(result->result.is_err());

    auto actual_path =
        std::string(result->result.response().path.begin(), result->result.response().path.size());
    // Make sure expected path matches the actual path.
    ASSERT_EQ(actual_path, expected_path);
  }
};

TEST_F(BlockWatcherTest, TestBlockWatcherDisable) {
  ASSERT_NO_FATAL_FAILURE(PauseWatcher());

  // Add a block device.
  isolated_devmgr::RamDisk client;
  ASSERT_NO_FATAL_FAILURE(client = CreateGptRamdisk());

  // Figure out what the next device number will be.
  int next_device_number;
  {
    files::Glob glob("/dev/class/block/*");
    ASSERT_GT(glob.size(), 0ul);
    auto iterator = glob.end();
    --iterator;
    ASSERT_EQ(sscanf(*iterator, "/dev/class/block/%d", &next_device_number), 1);
  }
  next_device_number++;

  ASSERT_NO_FATAL_FAILURE(ResumeWatcher());

  isolated_devmgr::RamDisk client2;
  ASSERT_NO_FATAL_FAILURE(CheckEventsDropped(next_device_number, client2));
}

TEST_F(BlockWatcherTest, TestBlockWatcherAdd) {
  // Add a block device.
  isolated_devmgr::RamDisk client;
  ASSERT_NO_FATAL_FAILURE(client = CreateGptRamdisk());

  // Wait for fshost to bind the gpt driver.
  EXPECT_EQ(wait_for_device((client.path() + "/part-000/block").c_str(), ZX_TIME_INFINITE), ZX_OK);
}

TEST_F(BlockWatcherTest, TestBlockWatcherUnmatchedResume) {
  auto result = llcpp::fuchsia::fshost::BlockWatcher::Call::Resume(watcher_channel().borrow());
  ASSERT_EQ(result.status(), ZX_OK);
  ASSERT_EQ(result->status, ZX_ERR_BAD_STATE);
}

TEST_F(BlockWatcherTest, TestMultiplePause) {
  ASSERT_NO_FATAL_FAILURE(PauseWatcher());
  ASSERT_NO_FATAL_FAILURE(PauseWatcher());
  int next_device_number = 0;

  // Add a block device.
  isolated_devmgr::RamDisk client;
  ASSERT_NO_FATAL_FAILURE(client = CreateGptRamdisk());

  // Figure out what the next device number will be.
  {
    files::Glob glob("/dev/class/block/*");
    ASSERT_GT(glob.size(), 0ul);
    auto iterator = glob.end();
    --iterator;
    ASSERT_EQ(sscanf(*iterator, "/dev/class/block/%d", &next_device_number), 1);
  }
  next_device_number++;

  // Resume once.
  ASSERT_NO_FATAL_FAILURE(ResumeWatcher());

  isolated_devmgr::RamDisk client2;
  ASSERT_NO_FATAL_FAILURE(client2 = CreateGptRamdisk());
  ASSERT_NO_FATAL_FAILURE(WaitForBlockDevice(next_device_number));
  next_device_number++;

  ASSERT_EQ(wait_for_device(client2.path().c_str(), ZX_TIME_INFINITE), ZX_OK);
  // Resume again. The block watcher should be running again.
  ASSERT_NO_FATAL_FAILURE(ResumeWatcher());

  // Make sure neither device was seen by the watcher.
  isolated_devmgr::RamDisk client3;
  ASSERT_NO_FATAL_FAILURE(CheckEventsDropped(next_device_number, client3));

  // Pause again.
  ASSERT_NO_FATAL_FAILURE(PauseWatcher());
  isolated_devmgr::RamDisk client4;
  client4 = CreateGptRamdisk();
  ASSERT_NO_FATAL_FAILURE(WaitForBlockDevice(next_device_number));
  next_device_number++;
  // Resume again.
  ASSERT_NO_FATAL_FAILURE(ResumeWatcher());

  // Make sure the last device wasn't added.
  isolated_devmgr::RamDisk client5;
  ASSERT_NO_FATAL_FAILURE(CheckEventsDropped(next_device_number, client5));
}

TEST_F(BlockWatcherTest, TestResumeThenImmediatelyPause) {
  ASSERT_NO_FATAL_FAILURE(PauseWatcher());
  int next_device_number = 0;

  // Add a block device, which should be ignored.
  isolated_devmgr::RamDisk client;
  ASSERT_NO_FATAL_FAILURE(client = CreateGptRamdisk());

  // Figure out what the next device number will be.
  {
    files::Glob glob("/dev/class/block/*");
    ASSERT_GT(glob.size(), 0ul);
    auto iterator = glob.end();
    --iterator;
    ASSERT_EQ(sscanf(*iterator, "/dev/class/block/%d", &next_device_number), 1);
  }
  next_device_number++;

  // Resume.
  ASSERT_NO_FATAL_FAILURE(ResumeWatcher());
  // Pause immediately.
  ASSERT_NO_FATAL_FAILURE(PauseWatcher());

  // Add another block device, which should also be ignored.
  isolated_devmgr::RamDisk client2;
  ASSERT_NO_FATAL_FAILURE(client2 = CreateGptRamdisk());
  ASSERT_NO_FATAL_FAILURE(WaitForBlockDevice(next_device_number));
  next_device_number++;

  // Resume again.
  ASSERT_NO_FATAL_FAILURE(ResumeWatcher());

  // Make sure the block watcher correctly resumed.
  isolated_devmgr::RamDisk client3;
  ASSERT_NO_FATAL_FAILURE(CheckEventsDropped(next_device_number, client3));
}

}  // namespace
}  // namespace devmgr
