| // 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 <fidl/fuchsia.buildinfo/cpp/fidl.h> |
| #include <fuchsia/buildinfo/cpp/fidl.h> |
| #include <lib/async/default.h> |
| #include <lib/sys/cpp/component_context.h> |
| |
| #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<testfidl::TestInterface>(); |
| return VerifyTestInterface(test_interface_ptr) == ZX_OK; |
| } |
| |
| bool CanConnectToTestInterfaceServiceNatural() { |
| auto client_end = |
| fuchsia_component::Connect<base_testfidl::TestInterface>(); |
| 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<testfidl::TestInterface>(); |
| return VerifyTestInterface(test_interface_ptr) == ZX_OK; |
| } |
| |
| bool HasPublishedTestInterfaceNatural() { |
| auto client_end = |
| fuchsia_component::ConnectAt<base_testfidl::TestInterface>( |
| 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<testfidl::TestInterface> 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<testfidl::TestInterface> 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<fuchsia_buildinfo::Provider>}; |
| test_context_.AddServices(kServiceNames); |
| |
| // Connect to the BuildInfo provider service via the process |
| // TestComponentContextForProcess. |
| RunLoop wait_loop; |
| auto client_end = fuchsia_component::Connect<fuchsia_buildinfo::Provider>(); |
| 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().ThenExactlyOnce( |
| [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 |