#include <lib/async/default.h>
#include <lib/sys/cpp/component_context.h>
#include "base/fuchsia/process_context.h"
#include "base/fuchsia/scoped_service_binding.h"
#include "base/fuchsia/test_component_context_for_process.h"
#include "base/fuchsia/test_interface_natural_impl.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
class ScopedNaturalServiceBindingTest : public testing::Test {
protected:
ScopedNaturalServiceBindingTest() = default;
~ScopedNaturalServiceBindingTest() override = default;
const base::test::SingleThreadTaskEnvironment task_environment_{
base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
TestComponentContextForProcess test_context_;
TestInterfaceNaturalImpl test_service_;
};
TEST_F(ScopedNaturalServiceBindingTest, ConnectTwice) {
ScopedNaturalServiceBinding<base_testfidl::TestInterface> binding(
ComponentContextForProcess()->outgoing().get(), &test_service_);
auto stub =
CreateTestInterfaceClient(test_context_.published_services_natural());
auto stub2 =
CreateTestInterfaceClient(test_context_.published_services_natural());
EXPECT_EQ(VerifyTestInterface(stub), ZX_OK);
EXPECT_EQ(VerifyTestInterface(stub2), ZX_OK);
}
TEST_F(ScopedNaturalServiceBindingTest, ConnectTwiceNameOverride) {
const char kInterfaceName[] = "fuchsia.TestInterface2";
ScopedNaturalServiceBinding<base_testfidl::TestInterface> new_service_binding(
ComponentContextForProcess()->outgoing().get(), &test_service_,
kInterfaceName);
auto stub = CreateTestInterfaceClient(
test_context_.published_services_natural(), kInterfaceName);
auto stub2 = CreateTestInterfaceClient(
test_context_.published_services_natural(), kInterfaceName);
EXPECT_EQ(VerifyTestInterface(stub), ZX_OK);
EXPECT_EQ(VerifyTestInterface(stub2), ZX_OK);
}
TEST_F(ScopedNaturalServiceBindingTest, ConnectDebugService) {
vfs::PseudoDir* const debug_dir =
ComponentContextForProcess()->outgoing()->debug_dir();
ScopedNaturalServiceBinding<base_testfidl::TestInterface>
debug_service_binding(debug_dir, &test_service_);
auto debug_directory_endpoints =
fidl::CreateEndpoints<fuchsia_io::Directory>();
ASSERT_TRUE(debug_directory_endpoints.is_ok())
<< debug_directory_endpoints.status_string();
debug_dir->Serve(fuchsia_io::wire::kPermReadable,
fidl::ServerEnd<fuchsia_io::Directory>(
debug_directory_endpoints->server.TakeChannel()));
auto debug_stub =
CreateTestInterfaceClient(std::move(debug_directory_endpoints->client));
EXPECT_EQ(VerifyTestInterface(debug_stub), ZX_OK);
auto release_stub =
CreateTestInterfaceClient(test_context_.published_services_natural());
EXPECT_EQ(VerifyTestInterface(release_stub), ZX_ERR_NOT_FOUND);
}
TEST_F(ScopedNaturalServiceBindingTest, MultipleLastClientCallback) {
ScopedNaturalServiceBinding<base_testfidl::TestInterface> binding(
ComponentContextForProcess()->outgoing().get(), &test_service_);
int disconnect_count = 0;
binding.SetOnLastClientCallback(
BindLambdaForTesting([&disconnect_count] { ++disconnect_count; }));
{
auto stub =
CreateTestInterfaceClient(test_context_.published_services_natural());
EXPECT_EQ(VerifyTestInterface(stub), ZX_OK);
}
RunLoop().RunUntilIdle();
EXPECT_EQ(disconnect_count, 1);
{
auto stub =
CreateTestInterfaceClient(test_context_.published_services_natural());
EXPECT_EQ(VerifyTestInterface(stub), ZX_OK);
}
RunLoop().RunUntilIdle();
EXPECT_EQ(disconnect_count, 2);
}
TEST_F(ScopedNaturalServiceBindingTest, LastClientCallbackOnlyForLastClient) {
ScopedNaturalServiceBinding<base_testfidl::TestInterface> binding(
ComponentContextForProcess()->outgoing().get(), &test_service_);
int disconnect_count = 0;
binding.SetOnLastClientCallback(
BindLambdaForTesting([&disconnect_count] { ++disconnect_count; }));
{
auto long_lived_stub =
CreateTestInterfaceClient(test_context_.published_services_natural());
EXPECT_EQ(VerifyTestInterface(long_lived_stub), ZX_OK);
{
auto stub =
CreateTestInterfaceClient(test_context_.published_services_natural());
EXPECT_EQ(VerifyTestInterface(stub), ZX_OK);
}
RunLoop().RunUntilIdle();
EXPECT_EQ(disconnect_count, 0);
{
auto stub =
CreateTestInterfaceClient(test_context_.published_services_natural());
EXPECT_EQ(VerifyTestInterface(stub), ZX_OK);
}
RunLoop().RunUntilIdle();
EXPECT_EQ(disconnect_count, 0);
}
RunLoop().RunUntilIdle();
EXPECT_EQ(disconnect_count, 1);
}
}