blob: e81fa68b398ca9c9a60453132803ed74f75de79c [file] [log] [blame]
// Copyright 2024 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 <fidl/fuchsia.hardware.test/cpp/fidl.h>
#include <lib/async-loop/default.h>
#include <lib/async/default.h>
#include <lib/async_patterns/testing/cpp/dispatcher_bound.h>
#include <lib/component/outgoing/cpp/outgoing_directory.h>
#include <ddktl/metadata_server.h>
#include <gtest/gtest.h>
#include "src/devices/testing/mock-ddk/mock-device.h"
#include "src/lib/ddktl/tests/metadata-server-test/metadata-retriever-test-driver/metadata_retriever_test_device.h"
#include "src/lib/testing/predicates/status.h"
namespace ddk::test {
class IncomingNamespace {
public:
void Init(fidl::ServerEnd<fuchsia_io::Directory> outgoing_server) {
ASSERT_OK(metadata_server_.Serve(outgoing_, async_get_default_dispatcher()));
ASSERT_OK(outgoing_.Serve(std::move(outgoing_server)));
}
void SetMetadata(const fuchsia_hardware_test::wire::Metadata& metadata) {
metadata_server_.SetMetadata(metadata);
}
private:
ddk::MetadataServer<fuchsia_hardware_test::wire::Metadata> metadata_server_;
component::OutgoingDirectory outgoing_{async_get_default_dispatcher()};
};
class MetadataServerMockDdkTest : public ::testing::Test {
public:
void SetUp() override {
// Set-up driver's incoming namespace.
ASSERT_OK(incoming_loop_.StartThread("incoming-namespace"));
auto incoming_namespace_endpoints = fidl::Endpoints<fuchsia_io::Directory>::Create();
incoming_namespace_.SyncCall(&IncomingNamespace::Init,
std::move(incoming_namespace_endpoints.server));
parent_->AddFidlService(MetadataServer<fuchsia_hardware_test::Metadata>::kFidlServiceName,
std::move(incoming_namespace_endpoints.client), "default");
// Start driver.
auto result = fdf::RunOnDispatcherSync(driver_dispatcher_->async_dispatcher(), [&]() {
ASSERT_OK(MetadataRetrieverTestDevice::Bind(nullptr, parent_.get()));
});
ASSERT_OK(result);
// Connect to metadata retriever driver's FIDL protocol.
auto metadata_retriever_endpoints =
fidl::Endpoints<fuchsia_hardware_test::MetadataRetriever>::Create();
fidl::BindServer(driver_dispatcher_->async_dispatcher(),
std::move(metadata_retriever_endpoints.server),
parent_->GetLatestChild()->GetDeviceContext<MetadataRetrieverTestDevice>());
client_.Bind(std::move(metadata_retriever_endpoints.client));
}
protected:
void SetMetadata(const fuchsia_hardware_test::wire::Metadata& metadata) {
incoming_namespace_.SyncCall(&IncomingNamespace::SetMetadata, metadata);
}
fidl::SyncClient<fuchsia_hardware_test::MetadataRetriever>& client() { return client_; }
private:
std::shared_ptr<MockDevice> parent_ = MockDevice::FakeRootParent();
async::Loop incoming_loop_{&kAsyncLoopConfigNoAttachToCurrentThread};
async_patterns::TestDispatcherBound<IncomingNamespace> incoming_namespace_{
incoming_loop_.dispatcher(), std::in_place};
fdf::UnownedSynchronizedDispatcher driver_dispatcher_ =
fdf_testing::DriverRuntime::GetInstance()->StartBackgroundDispatcher();
fidl::ServerBindingGroup<fuchsia_hardware_test::MetadataRetriever> bindings_;
fidl::SyncClient<fuchsia_hardware_test::MetadataRetriever> client_;
};
// Verify that a driver can retrieve metadata via `ddk::GetMetadata()` from a mock parent device
// created by the mock-ddk library.
TEST_F(MetadataServerMockDdkTest, GetMetadata) {
const char* kTestPropertyValue = "test-value";
// Set the metadata to be retrieved.
fidl::Arena arena;
auto metadata = fuchsia_hardware_test::wire::Metadata::Builder(arena)
.test_property(kTestPropertyValue)
.Build();
SetMetadata(metadata);
// Get the metadata.
fidl::Result result = client()->GetMetadata();
ASSERT_TRUE(result.is_ok()) << result.error_value();
auto test_property = result->metadata().test_property();
ASSERT_TRUE(test_property.has_value());
ASSERT_EQ(test_property.value(), kTestPropertyValue);
}
} // namespace ddk::test