• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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