blob: bdfb5d9244c4575696396c90a27b6fa4e211978b [file] [log] [blame]
// 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 <fidl/fidl.test.echo/cpp/wire.h>
#include <fidl/fuchsia.io/cpp/wire.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/wait.h>
#include <lib/zx/channel.h>
#include <zircon/status.h>
#include <runtests-utils/service-proxy-dir.h>
#include <zxtest/zxtest.h>
#include "src/storage/lib/vfs/cpp/pseudo_dir.h"
#include "src/storage/lib/vfs/cpp/service.h"
#include "src/storage/lib/vfs/cpp/synchronous_vfs.h"
namespace fio = fuchsia_io;
namespace {
class Echo : public fidl::WireServer<fidl_test_echo::Echo> {
public:
explicit Echo(std::string response) : response_(std::move(response)) {}
void EchoString(EchoStringRequestView request, EchoStringCompleter::Sync& completer) override {
completer.Reply(fidl::StringView::FromExternal(response_));
}
private:
std::string response_;
};
constexpr char kTestString[] = "test";
constexpr char kEchoString[] = "echo";
constexpr char kProxyEchoString[] = "proxy_echo";
TEST(ServiceProxyDirTest, Simple) {
async::Loop loop{&kAsyncLoopConfigNoAttachToCurrentThread};
std::unique_ptr<fs::SynchronousVfs> vfs;
vfs = std::make_unique<fs::SynchronousVfs>(loop.dispatcher());
Echo echo(kEchoString);
auto dir = fbl::MakeRefCounted<fs::PseudoDir>();
dir->AddEntry(
kEchoString,
fbl::MakeRefCounted<fs::Service>(
[&echo, dispatcher = loop.dispatcher()](fidl::ServerEnd<fidl_test_echo::Echo> request) {
fidl::BindServer(dispatcher, std::move(request), &echo);
return ZX_OK;
}));
ASSERT_OK(loop.StartThread());
auto [client, server] = fidl::Endpoints<fio::Directory>::Create();
ASSERT_OK(vfs->ServeDirectory(std::move(dir), std::move(server)));
ASSERT_OK(loop.StartThread());
Echo proxy_echo(kProxyEchoString);
auto proxy_dir = fbl::MakeRefCounted<runtests::ServiceProxyDir>(std::move(client));
proxy_dir->AddEntry(
kProxyEchoString,
fbl::MakeRefCounted<fs::Service>([&proxy_echo, dispatcher = loop.dispatcher()](
fidl::ServerEnd<fidl_test_echo::Echo> request) {
fidl::BindServer(dispatcher, std::move(request), &proxy_echo);
return ZX_OK;
}));
ASSERT_OK(loop.StartThread());
auto [proxy_client, proxy_server] = fidl::Endpoints<fio::Directory>::Create();
ASSERT_OK(vfs->ServeDirectory(std::move(proxy_dir), std::move(proxy_server)));
ASSERT_OK(loop.StartThread());
// First check the service served directly by the proxy.
{
auto [client, server] = fidl::Endpoints<fio::Node>::Create();
ASSERT_OK(fidl::WireCall(proxy_client)
->Open({}, {}, fidl::StringView(kProxyEchoString), std::move(server))
.status());
const fidl::WireResult result =
fidl::WireCall(fidl::UnownedClientEnd<fidl_test_echo::Echo>{client.channel().borrow()})
->EchoString(kTestString);
ASSERT_OK(result.status());
const fidl::WireResponse response = result.value();
ASSERT_EQ(response.response.get(), kProxyEchoString);
}
// Second check the service that's being proxied by the proxy.
{
auto [client, server] = fidl::Endpoints<fio::Node>::Create();
ASSERT_OK(fidl::WireCall(proxy_client)
->Open({}, {}, fidl::StringView(kEchoString), std::move(server))
.status());
const fidl::WireResult result =
fidl::WireCall(fidl::UnownedClientEnd<fidl_test_echo::Echo>{client.channel().borrow()})
->EchoString(kTestString);
ASSERT_OK(result.status());
const fidl::WireResponse response = result.value();
ASSERT_EQ(response.response.get(), kEchoString);
}
loop.Shutdown();
}
} // anonymous namespace