blob: 31e00c820ec7db48e0ee8b229f580bed1123f0e5 [file] [log] [blame]
// Copyright 2021 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 "src/storage/lib/fs_management/cpp/fvm.h"
#include <fidl/fuchsia.device/cpp/wire_test_base.h>
#include <fidl/fuchsia.hardware.block.partition/cpp/wire.h>
#include <fidl/fuchsia.hardware.block.partition/cpp/wire_test_base.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/syslog/cpp/macros.h>
#include <gtest/gtest.h>
#include "src/storage/lib/fs_management/cpp/fvm_internal.h"
namespace fs_management {
namespace {
constexpr uuid::Uuid kValidTypeGUID = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
constexpr uuid::Uuid kValidInstanceGUID = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
constexpr uuid::Uuid kInvalidGUID1 = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f};
constexpr uuid::Uuid kInvalidGUID2 = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f};
constexpr std::string_view kValidLabel = "test";
constexpr std::string_view kInvalidLabel1 = "TheWrongLabel";
constexpr std::string_view kInvalidLabel2 = "StillTheWrongLabel";
constexpr std::string_view kDefaultPath = "/fake/block/device/1/partition/001";
constexpr std::string_view kParent = "/fake/block/device/1";
constexpr std::string_view kNotParent = "/fake/block/device/2";
class FakePartition
: public fidl::testing::WireTestBase<fuchsia_hardware_block_partition::Partition> {
public:
FakePartition(const uuid::Uuid& type, const uuid::Uuid& instance, std::string_view label)
: type_guid_(type), instance_guid_(instance), label_(label) {}
void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) override {
FAIL() << name << " was called unexpectedly";
}
void GetTypeGuid(GetTypeGuidCompleter::Sync& completer) override {
fuchsia_hardware_block_partition::wire::Guid guid;
std::copy(type_guid_.begin(), type_guid_.end(), guid.value.begin());
auto guid_object =
fidl::ObjectView<fuchsia_hardware_block_partition::wire::Guid>(allocator_, guid);
completer.Reply(ZX_OK, guid_object);
}
void GetInstanceGuid(GetInstanceGuidCompleter::Sync& completer) override {
fuchsia_hardware_block_partition::wire::Guid guid;
std::copy(instance_guid_.begin(), instance_guid_.end(), guid.value.begin());
auto guid_object =
fidl::ObjectView<fuchsia_hardware_block_partition::wire::Guid>(allocator_, guid);
completer.Reply(ZX_OK, guid_object);
}
void GetName(GetNameCompleter::Sync& completer) override {
auto label_object = fidl::StringView(allocator_, label_);
completer.Reply(ZX_OK, label_object);
}
private:
fidl::Arena<1024> allocator_;
uuid::Uuid type_guid_;
uuid::Uuid instance_guid_;
std::string_view label_;
};
class FakePartitionDevice : public fidl::testing::WireTestBase<fuchsia_device::Controller> {
public:
FakePartitionDevice(async_dispatcher_t* dispatcher, const uuid::Uuid& type,
const uuid::Uuid& instance, std::string_view label, std::string_view path)
: dispatcher_(dispatcher), partition_(type, instance, label), path_(path) {}
void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) override {
FAIL() << name << " was called unexpectedly";
}
void GetTopologicalPath(GetTopologicalPathCompleter::Sync& completer) override {
completer.ReplySuccess(fidl::StringView::FromExternal(path_));
}
void ConnectToDeviceFidl(ConnectToDeviceFidlRequestView request,
ConnectToDeviceFidlCompleter::Sync& completer) override {
fidl::BindServer(
dispatcher_,
fidl::ServerEnd<fuchsia_hardware_block_partition::Partition>(std::move(request->server)),
&partition_);
}
zx::result<fidl::ClientEnd<fuchsia_device::Controller>> GetClient() {
zx::result endpoints = fidl::CreateEndpoints<fuchsia_device::Controller>();
if (endpoints.is_error()) {
return endpoints.take_error();
}
fidl::BindServer(dispatcher_, std::move(endpoints->server), this);
return zx::ok(std::move(endpoints->client));
}
private:
async_dispatcher_t* dispatcher_;
FakePartition partition_;
std::string_view path_;
};
class PartitionMatchesTest : public testing::Test {
public:
PartitionMatchesTest()
: loop_(&kAsyncLoopConfigNeverAttachToThread),
partition_(loop_.dispatcher(), kValidTypeGUID, kValidInstanceGUID, kValidLabel,
kDefaultPath) {}
void SetUp() override {
ASSERT_EQ(loop_.StartThread("test-fidl-loop"), ZX_OK);
auto client = partition_.GetClient();
ASSERT_EQ(client.status_value(), ZX_OK);
client_ = std::move(client.value());
}
protected:
async::Loop loop_;
FakePartitionDevice partition_;
fidl::ClientEnd<fuchsia_device::Controller> client_;
};
TEST_F(PartitionMatchesTest, TestTypeMatch) {
const PartitionMatcher kMatcher = {.type_guids = {kInvalidGUID1, kValidTypeGUID, kInvalidGUID2}};
zx::result result = PartitionMatches(client_, kMatcher);
ASSERT_TRUE(result.is_ok()) << result.status_string();
ASSERT_TRUE(result.value());
}
TEST_F(PartitionMatchesTest, TestInstanceMatch) {
const PartitionMatcher kMatcher = {
.instance_guids = {kInvalidGUID1, kValidInstanceGUID, kInvalidGUID2}};
zx::result result = PartitionMatches(client_, kMatcher);
ASSERT_TRUE(result.is_ok()) << result.status_string();
ASSERT_TRUE(result.value());
}
TEST_F(PartitionMatchesTest, TestTypeAndInstanceMatch) {
const PartitionMatcher kMatcher = {
.type_guids = {kInvalidGUID1, kValidTypeGUID, kInvalidGUID2},
.instance_guids = {kInvalidGUID1, kValidInstanceGUID, kInvalidGUID2}};
zx::result result = PartitionMatches(client_, kMatcher);
ASSERT_TRUE(result.is_ok()) << result.status_string();
ASSERT_TRUE(result.value());
}
TEST_F(PartitionMatchesTest, TestParentMatch) {
{
const PartitionMatcher kMatcher = {.parent_device = kParent};
zx::result result = PartitionMatches(client_, kMatcher);
ASSERT_TRUE(result.is_ok()) << result.status_string();
ASSERT_TRUE(result.value());
}
{
const PartitionMatcher kMatcher = {.parent_device = kNotParent};
zx::result result = PartitionMatches(client_, kMatcher);
ASSERT_TRUE(result.is_ok()) << result.status_string();
ASSERT_FALSE(result.value());
}
}
TEST_F(PartitionMatchesTest, TestLabelMatch) {
const PartitionMatcher kMatcher = {.labels = {
kInvalidLabel1,
kValidLabel,
kInvalidLabel2,
}};
zx::result result = PartitionMatches(client_, kMatcher);
ASSERT_TRUE(result.is_ok()) << result.status_string();
ASSERT_TRUE(result.value());
}
TEST_F(PartitionMatchesTest, TestTypeAndLabelMatch) {
const PartitionMatcher kMatcher = {
.type_guids = {kValidTypeGUID},
.labels = {kValidLabel},
};
zx::result result = PartitionMatches(client_, kMatcher);
ASSERT_TRUE(result.is_ok()) << result.status_string();
ASSERT_TRUE(result.value());
}
TEST_F(PartitionMatchesTest, TestTypeMismatch) {
const PartitionMatcher kMatcher = {.type_guids = {kInvalidGUID1}};
zx::result result = PartitionMatches(client_, kMatcher);
ASSERT_TRUE(result.is_ok()) << result.status_string();
ASSERT_FALSE(result.value());
}
TEST_F(PartitionMatchesTest, TestInstanceMismatch) {
const PartitionMatcher kMatcher = {.type_guids = {kValidTypeGUID},
.instance_guids = {kInvalidGUID2}};
zx::result result = PartitionMatches(client_, kMatcher);
ASSERT_TRUE(result.is_ok()) << result.status_string();
ASSERT_FALSE(result.value());
}
TEST_F(PartitionMatchesTest, TestLabelMismatch) {
const PartitionMatcher kMatcher = {.type_guids = {kValidTypeGUID},
.labels = {
kInvalidLabel1,
kInvalidLabel2,
}};
zx::result result = PartitionMatches(client_, kMatcher);
ASSERT_TRUE(result.is_ok()) << result.status_string();
ASSERT_FALSE(result.value());
}
} // namespace
} // namespace fs_management