1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/fuchsia/test_component_context_for_process.h"
6
7 #include <fidl/fuchsia.buildinfo/cpp/fidl.h>
8 #include <fuchsia/buildinfo/cpp/fidl.h>
9 #include <lib/async/default.h>
10 #include <lib/sys/cpp/component_context.h>
11
12 #include "base/fuchsia/fuchsia_component_connect.h"
13 #include "base/fuchsia/fuchsia_logging.h"
14 #include "base/fuchsia/process_context.h"
15 #include "base/fuchsia/scoped_service_binding.h"
16 #include "base/fuchsia/test_interface_impl.h"
17 #include "base/fuchsia/test_interface_natural_impl.h"
18 #include "base/run_loop.h"
19 #include "base/test/task_environment.h"
20 #include "base/testfidl/cpp/fidl.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 namespace base {
24
25 class TestComponentContextForProcessTest : public testing::Test {
26 public:
TestComponentContextForProcessTest()27 TestComponentContextForProcessTest()
28 : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}
29
CanConnectToTestInterfaceServiceHlcpp()30 bool CanConnectToTestInterfaceServiceHlcpp() {
31 auto test_interface_ptr =
32 ComponentContextForProcess()->svc()->Connect<testfidl::TestInterface>();
33 return VerifyTestInterface(test_interface_ptr) == ZX_OK;
34 }
35
CanConnectToTestInterfaceServiceNatural()36 bool CanConnectToTestInterfaceServiceNatural() {
37 auto client_end =
38 fuchsia_component::Connect<base_testfidl::TestInterface>();
39 EXPECT_TRUE(client_end.is_ok()) << client_end.status_string();
40 fidl::Client client(std::move(client_end.value()),
41 async_get_default_dispatcher());
42 return VerifyTestInterface(client) == ZX_OK;
43 }
44
HasPublishedTestInterfaceHlcpp()45 bool HasPublishedTestInterfaceHlcpp() {
46 auto test_interface_ptr =
47 test_context_.published_services()->Connect<testfidl::TestInterface>();
48 return VerifyTestInterface(test_interface_ptr) == ZX_OK;
49 }
50
HasPublishedTestInterfaceNatural()51 bool HasPublishedTestInterfaceNatural() {
52 auto client_end =
53 fuchsia_component::ConnectAt<base_testfidl::TestInterface>(
54 test_context_.published_services_natural());
55 EXPECT_TRUE(client_end.is_ok()) << client_end.status_string();
56 fidl::Client client(std::move(client_end.value()),
57 async_get_default_dispatcher());
58 return VerifyTestInterface(client) == ZX_OK;
59 }
60
61 protected:
62 const base::test::SingleThreadTaskEnvironment task_environment_;
63
64 base::TestComponentContextForProcess test_context_;
65 };
66
TEST_F(TestComponentContextForProcessTest,NoServices)67 TEST_F(TestComponentContextForProcessTest, NoServices) {
68 // No services should be available.
69 EXPECT_FALSE(CanConnectToTestInterfaceServiceHlcpp());
70 EXPECT_FALSE(CanConnectToTestInterfaceServiceNatural());
71 }
72
TEST_F(TestComponentContextForProcessTest,InjectTestInterface)73 TEST_F(TestComponentContextForProcessTest, InjectTestInterface) {
74 TestInterfaceImpl test_interface_impl;
75 // Publish a fake TestInterface for the process' ComponentContext to expose.
76 base::ScopedServiceBinding<testfidl::TestInterface> service_binding(
77 test_context_.additional_services(), &test_interface_impl);
78
79 // Verify that the TestInterface is accessible & usable.
80 EXPECT_TRUE(CanConnectToTestInterfaceServiceHlcpp());
81 EXPECT_TRUE(CanConnectToTestInterfaceServiceNatural());
82 }
83
TEST_F(TestComponentContextForProcessTest,PublishTestInterface)84 TEST_F(TestComponentContextForProcessTest, PublishTestInterface) {
85 TestInterfaceImpl test_interface_impl;
86 // Publish TestInterface to the process' outgoing-directory.
87 base::ScopedServiceBinding<testfidl::TestInterface> service_binding(
88 ComponentContextForProcess()->outgoing().get(), &test_interface_impl);
89
90 // Attempt to use the TestInterface from the outgoing-directory.
91 EXPECT_TRUE(HasPublishedTestInterfaceHlcpp());
92 EXPECT_TRUE(HasPublishedTestInterfaceNatural());
93 }
94
TEST_F(TestComponentContextForProcessTest,ProvideSystemService)95 TEST_F(TestComponentContextForProcessTest, ProvideSystemService) {
96 // Expose fuchsia.buildinfo.Provider through the
97 // TestComponentContextForProcess. This service was chosen because it is one
98 // of the ambient services in Fuchsia's hermetic environment for Chromium
99 // tests.
100 const base::StringPiece kServiceNames[] = {
101 ::fuchsia::buildinfo::Provider::Name_};
102 test_context_.AddServices(kServiceNames);
103
104 // Connect to the BuildInfo provider service via the process
105 // TestComponentContextForProcess.
106 RunLoop wait_loop;
107 auto provider = ComponentContextForProcess()
108 ->svc()
109 ->Connect<::fuchsia::buildinfo::Provider>();
110 provider.set_error_handler(
111 [quit_loop = wait_loop.QuitClosure()](zx_status_t status) {
112 ZX_LOG(ERROR, status);
113 ADD_FAILURE();
114 quit_loop.Run();
115 });
116
117 // If the BuildInfo service is actually connected then GetBuildInfo() will
118 // return a result, otherwise the channel will be observed closing (as above).
119 provider->GetBuildInfo([quit_loop = wait_loop.QuitClosure()](
120 auto build_info) { quit_loop.Run(); });
121 wait_loop.Run();
122 }
123
TEST_F(TestComponentContextForProcessTest,ProvideSystemServiceNatural)124 TEST_F(TestComponentContextForProcessTest, ProvideSystemServiceNatural) {
125 // Expose fuchsia.buildinfo.Provider through the
126 // TestComponentContextForProcess. This service was chosen because it is one
127 // of the ambient services in Fuchsia's hermetic environment for Chromium
128 // tests.
129 const base::StringPiece kServiceNames[] = {
130 fidl::DiscoverableProtocolName<fuchsia_buildinfo::Provider>};
131 test_context_.AddServices(kServiceNames);
132
133 // Connect to the BuildInfo provider service via the process
134 // TestComponentContextForProcess.
135 RunLoop wait_loop;
136 auto client_end = fuchsia_component::Connect<fuchsia_buildinfo::Provider>();
137 ASSERT_TRUE(client_end.is_ok());
138 fidl::Client provider(std::move(client_end.value()),
139 async_get_default_dispatcher());
140
141 // If the BuildInfo service is actually connected then GetBuildInfo() will
142 // return a result, otherwise the bindings will report an error.
143 provider->GetBuildInfo().Then(
144 [quit_loop = wait_loop.QuitClosure()](auto build_info) {
145 EXPECT_FALSE(build_info.is_error())
146 << build_info.error_value().status();
147 quit_loop.Run();
148 });
149 wait_loop.Run();
150 }
151
152 } // namespace base
153