// Copyright 2020 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/fuchsia/test_component_context_for_process.h" #include #include #include #include #include "base/fuchsia/fuchsia_component_connect.h" #include "base/fuchsia/fuchsia_logging.h" #include "base/fuchsia/process_context.h" #include "base/fuchsia/scoped_service_binding.h" #include "base/fuchsia/test_interface_impl.h" #include "base/fuchsia/test_interface_natural_impl.h" #include "base/run_loop.h" #include "base/test/task_environment.h" #include "base/testfidl/cpp/fidl.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { class TestComponentContextForProcessTest : public testing::Test { public: TestComponentContextForProcessTest() : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {} bool CanConnectToTestInterfaceServiceHlcpp() { auto test_interface_ptr = ComponentContextForProcess()->svc()->Connect(); return VerifyTestInterface(test_interface_ptr) == ZX_OK; } bool CanConnectToTestInterfaceServiceNatural() { auto client_end = fuchsia_component::Connect(); EXPECT_TRUE(client_end.is_ok()) << client_end.status_string(); fidl::Client client(std::move(client_end.value()), async_get_default_dispatcher()); return VerifyTestInterface(client) == ZX_OK; } bool HasPublishedTestInterfaceHlcpp() { auto test_interface_ptr = test_context_.published_services()->Connect(); return VerifyTestInterface(test_interface_ptr) == ZX_OK; } bool HasPublishedTestInterfaceNatural() { auto client_end = fuchsia_component::ConnectAt( test_context_.published_services_natural()); EXPECT_TRUE(client_end.is_ok()) << client_end.status_string(); fidl::Client client(std::move(client_end.value()), async_get_default_dispatcher()); return VerifyTestInterface(client) == ZX_OK; } protected: const base::test::SingleThreadTaskEnvironment task_environment_; base::TestComponentContextForProcess test_context_; }; TEST_F(TestComponentContextForProcessTest, NoServices) { // No services should be available. EXPECT_FALSE(CanConnectToTestInterfaceServiceHlcpp()); EXPECT_FALSE(CanConnectToTestInterfaceServiceNatural()); } TEST_F(TestComponentContextForProcessTest, InjectTestInterface) { TestInterfaceImpl test_interface_impl; // Publish a fake TestInterface for the process' ComponentContext to expose. base::ScopedServiceBinding service_binding( test_context_.additional_services(), &test_interface_impl); // Verify that the TestInterface is accessible & usable. EXPECT_TRUE(CanConnectToTestInterfaceServiceHlcpp()); EXPECT_TRUE(CanConnectToTestInterfaceServiceNatural()); } TEST_F(TestComponentContextForProcessTest, PublishTestInterface) { TestInterfaceImpl test_interface_impl; // Publish TestInterface to the process' outgoing-directory. base::ScopedServiceBinding service_binding( ComponentContextForProcess()->outgoing().get(), &test_interface_impl); // Attempt to use the TestInterface from the outgoing-directory. EXPECT_TRUE(HasPublishedTestInterfaceHlcpp()); EXPECT_TRUE(HasPublishedTestInterfaceNatural()); } TEST_F(TestComponentContextForProcessTest, ProvideSystemService) { // Expose fuchsia.buildinfo.Provider through the // TestComponentContextForProcess. This service was chosen because it is one // of the ambient services in Fuchsia's hermetic environment for Chromium // tests. const base::StringPiece kServiceNames[] = { ::fuchsia::buildinfo::Provider::Name_}; test_context_.AddServices(kServiceNames); // Connect to the BuildInfo provider service via the process // TestComponentContextForProcess. RunLoop wait_loop; auto provider = ComponentContextForProcess() ->svc() ->Connect<::fuchsia::buildinfo::Provider>(); provider.set_error_handler( [quit_loop = wait_loop.QuitClosure()](zx_status_t status) { ZX_LOG(ERROR, status); ADD_FAILURE(); quit_loop.Run(); }); // If the BuildInfo service is actually connected then GetBuildInfo() will // return a result, otherwise the channel will be observed closing (as above). provider->GetBuildInfo([quit_loop = wait_loop.QuitClosure()]( auto build_info) { quit_loop.Run(); }); wait_loop.Run(); } TEST_F(TestComponentContextForProcessTest, ProvideSystemServiceNatural) { // Expose fuchsia.buildinfo.Provider through the // TestComponentContextForProcess. This service was chosen because it is one // of the ambient services in Fuchsia's hermetic environment for Chromium // tests. const base::StringPiece kServiceNames[] = { fidl::DiscoverableProtocolName}; test_context_.AddServices(kServiceNames); // Connect to the BuildInfo provider service via the process // TestComponentContextForProcess. RunLoop wait_loop; auto client_end = fuchsia_component::Connect(); ASSERT_TRUE(client_end.is_ok()); fidl::Client provider(std::move(client_end.value()), async_get_default_dispatcher()); // If the BuildInfo service is actually connected then GetBuildInfo() will // return a result, otherwise the bindings will report an error. provider->GetBuildInfo().Then( [quit_loop = wait_loop.QuitClosure()](auto build_info) { EXPECT_FALSE(build_info.is_error()) << build_info.error_value().status(); quit_loop.Run(); }); wait_loop.Run(); } } // namespace base