blob: 1864582bc53c11ccc47aefd53476900570bc5b49 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_STORAGE_FSHOST_MOCK_BLOCK_DEVICE_H_
#define SRC_STORAGE_FSHOST_MOCK_BLOCK_DEVICE_H_
#include <zircon/hw/gpt.h>
#include <optional>
#include <gtest/gtest.h>
#include "src/storage/fshost/block-device-interface.h"
namespace devmgr {
class MockBlockDevice : public devmgr::BlockDeviceInterface {
public:
static const std::string& BaseTopologicalPath() {
static std::string* path = new std::string("/dev/mock_device/block");
return *path;
}
struct Options {
static Options Default() { return {}; }
disk_format_t content_format = DISK_FORMAT_UNKNOWN;
std::string_view driver_path;
std::string topological_path = MockBlockDevice::BaseTopologicalPath();
std::string partition_name;
};
static Options GptOptions() {
return {.content_format = DISK_FORMAT_GPT, .driver_path = kGPTDriverPath};
}
static Options FvmOptions() {
return {.content_format = DISK_FORMAT_FVM, .driver_path = kFVMDriverPath};
}
static Options DurableOptions() {
return {
.topological_path = MockBlockDevice::BaseTopologicalPath() +
"/" GPT_DURABLE_NAME "-004/block/zxcrypt/unsealed/block",
};
}
explicit MockBlockDevice(const Options& options = Options::Default()) : options_(options) {}
// Returns the value SetPartitionMaxSize() was called with. Will be a nullopt if uncalled.
const std::optional<uint64_t>& max_size() const { return max_size_; }
disk_format_t content_format() const override { return options_.content_format; }
const std::string& topological_path() const override { return options_.topological_path; }
const std::string& partition_name() const override { return options_.partition_name; }
disk_format_t GetFormat() final { return format_; }
void SetFormat(disk_format_t format) final { format_ = format; }
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 = 1024;
*out_info = info;
return ZX_OK;
}
const fuchsia_hardware_block_partition_GUID& GetInstanceGuid() const override {
ADD_FAILURE() << "Test should not invoke function " << __FUNCTION__;
static fuchsia_hardware_block_partition_GUID null_guid{};
return null_guid;
}
const fuchsia_hardware_block_partition_GUID& GetTypeGuid() const override {
ADD_FAILURE() << "Test should not invoke function " << __FUNCTION__;
static fuchsia_hardware_block_partition_GUID null_guid;
return null_guid;
}
zx_status_t AttachDriver(const std::string_view& driver) override {
EXPECT_EQ(driver, options_.driver_path);
EXPECT_FALSE(attached_);
attached_ = true;
return ZX_OK;
}
zx_status_t UnsealZxcrypt() override {
ADD_FAILURE() << "Test should not invoke function " << __FUNCTION__;
return ZX_ERR_INTERNAL;
}
zx_status_t FormatZxcrypt() override {
ADD_FAILURE() << "Test should not invoke function " << __FUNCTION__;
return ZX_ERR_INTERNAL;
}
bool ShouldCheckFilesystems() override {
ADD_FAILURE() << "Test should not invoke function " << __FUNCTION__;
return false;
}
zx_status_t CheckFilesystem() override {
ADD_FAILURE() << "Test should not invoke function " << __FUNCTION__;
return ZX_ERR_INTERNAL;
}
zx_status_t FormatFilesystem() override {
ADD_FAILURE() << "Test should not invoke function " << __FUNCTION__;
return ZX_ERR_INTERNAL;
}
zx_status_t MountFilesystem() override {
ADD_FAILURE() << "Test should not invoke function " << __FUNCTION__;
return ZX_ERR_INTERNAL;
}
zx::status<std::string> VeritySeal() override {
ADD_FAILURE() << "Test should not invoke function " << __FUNCTION__;
return zx::error(ZX_ERR_INTERNAL);
}
zx_status_t OpenBlockVerityForVerifiedRead(std::string seal_hex) override {
ADD_FAILURE() << "Test should not invoke function " << __FUNCTION__;
return ZX_ERR_INTERNAL;
}
bool ShouldAllowAuthoringFactory() override {
ADD_FAILURE() << "Test should not invoke function " << __FUNCTION__;
return false;
}
zx_status_t SetPartitionMaxSize(const std::string& fvm_path, uint64_t max_size) override {
max_size_ = max_size;
return ZX_OK;
}
bool attached() const { return attached_; }
private:
const Options options_;
disk_format_t format_ = DISK_FORMAT_UNKNOWN;
bool attached_ = false;
std::optional<uint64_t> max_size_;
};
class MockBlockVerityDevice : public MockBlockDevice {
public:
static Options VerityOptions() {
return Options{.driver_path = kBlockVerityDriverPath,
.topological_path = BaseTopologicalPath() + "/factory-001/block",
.partition_name = "factory"};
}
MockBlockVerityDevice(bool allow_authoring, const Options& options = VerityOptions())
: MockBlockDevice(options), allow_authoring_(allow_authoring) {}
const fuchsia_hardware_block_partition_GUID& GetTypeGuid() const final {
static fuchsia_hardware_block_partition_GUID guid = GPT_FACTORY_TYPE_GUID;
return guid;
}
bool ShouldAllowAuthoringFactory() override { return allow_authoring_; }
private:
const bool allow_authoring_;
};
static constexpr char kFakeSeal[] =
"0000000000000000000000000000000000000000000000000000000000000000";
class MockSealedBlockVerityDevice : public MockBlockVerityDevice {
public:
MockSealedBlockVerityDevice() : MockBlockVerityDevice(/*allow_authoring=*/false) {}
zx::status<std::string> VeritySeal() final { return zx::ok(std::string(kFakeSeal)); }
zx_status_t OpenBlockVerityForVerifiedRead(std::string seal_hex) final {
EXPECT_EQ(std::string_view(kFakeSeal), seal_hex);
opened_ = true;
return ZX_OK;
}
bool opened() const { return opened_; }
private:
bool opened_ = false;
};
class MockFactoryfsDevice : public MockBlockDevice {
public:
static Options FactoryfsOptions() {
return Options{
.topological_path = BaseTopologicalPath() + "/factory-001/block/verity/verified/block",
};
}
MockFactoryfsDevice() : MockBlockDevice(FactoryfsOptions()) {}
const fuchsia_hardware_block_partition_GUID& GetTypeGuid() const final {
static fuchsia_hardware_block_partition_GUID guid = GPT_FACTORY_TYPE_GUID;
return guid;
}
zx_status_t CheckFilesystem() override {
checked_ = true;
return ZX_OK;
}
zx_status_t FormatFilesystem() override {
formatted_ = true;
return ZX_OK;
}
zx_status_t MountFilesystem() override {
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;
};
class MockBlobfsDevice : public MockBlockDevice {
public:
static Options BlobfsOptions() {
return {
.topological_path = MockBlockDevice::BaseTopologicalPath() + "/fvm/blobfs-p-1/block",
.partition_name = "blobfs",
};
}
MockBlobfsDevice() : MockBlockDevice(BlobfsOptions()) {}
const fuchsia_hardware_block_partition_GUID& GetTypeGuid() const override {
static fuchsia_hardware_block_partition_GUID guid = GUID_BLOB_VALUE;
return guid;
}
zx_status_t CheckFilesystem() override {
checked_ = true;
return ZX_OK;
}
zx_status_t FormatFilesystem() override {
formatted_ = true;
return ZX_OK;
}
zx_status_t MountFilesystem() override {
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;
};
class MockZxcryptDevice : public MockBlockDevice {
public:
static Options ZxcryptOptions() {
return {
.content_format = DISK_FORMAT_ZXCRYPT,
.driver_path = kZxcryptDriverPath,
.topological_path = MockBlockDevice::BaseTopologicalPath() + "/fvm/minfs-p-2/block",
.partition_name = "minfs",
};
}
MockZxcryptDevice(const Options& options = ZxcryptOptions()) : MockBlockDevice(options) {}
const fuchsia_hardware_block_partition_GUID& GetTypeGuid() const override {
static fuchsia_hardware_block_partition_GUID guid = GUID_DATA_VALUE;
return guid;
}
zx_status_t FormatZxcrypt() final {
formatted_zxcrypt_ = true;
return ZX_OK;
}
zx_status_t UnsealZxcrypt() final { return ZX_OK; }
bool formatted_zxcrypt() const { return formatted_zxcrypt_; }
private:
bool formatted_zxcrypt_ = false;
};
class MockMinfsDevice : public MockBlockDevice {
public:
static Options MinfsOptions() {
return {
.topological_path =
MockBlockDevice::BaseTopologicalPath() + "/fvm/minfs-p-2/block/zxcrypt/unsealed/block",
};
}
MockMinfsDevice(Options options = MinfsOptions()) : MockBlockDevice(options) {}
const fuchsia_hardware_block_partition_GUID& GetTypeGuid() const final {
static fuchsia_hardware_block_partition_GUID guid = GUID_DATA_VALUE;
return guid;
}
zx_status_t CheckFilesystem() override {
checked_ = true;
return ZX_OK;
}
zx_status_t FormatFilesystem() override {
formatted_ = true;
return ZX_OK;
}
zx_status_t MountFilesystem() override {
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;
};
} // namespace devmgr
#endif // SRC_STORAGE_FSHOST_MOCK_BLOCK_DEVICE_H_