• 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 #ifndef BASE_FUCHSIA_TEST_COMPONENT_CONTEXT_FOR_PROCESS_H_
6 #define BASE_FUCHSIA_TEST_COMPONENT_CONTEXT_FOR_PROCESS_H_
7 
8 #include <fidl/fuchsia.io/cpp/fidl.h>
9 
10 #include <memory>
11 
12 #include "base/base_export.h"
13 #include "base/containers/span.h"
14 #include "base/strings/string_piece.h"
15 
16 namespace sys {
17 class ComponentContext;
18 class OutgoingDirectory;
19 class ServiceDirectory;
20 }  // namespace sys
21 
22 namespace base {
23 
24 class FilteredServiceDirectory;
25 
26 // Replaces the process-global sys::ComponentContext (as returned by the
27 // base::ComponentContextForProcess() function) with an empty instance which the
28 // calling test can configure, and restores the original when deleted.
29 //
30 // The test ComponentContext runs on the test main thread, which means that:
31 // - Tests using TestComponentContextForProcess must instantiate a
32 //   [SingleThread]TaskEnvironment with UI or IO main-thread-type.
33 // - If all services exposed via the test ComponentContext run on the test
34 //   main thread, and the code under test does as well, then RunUntilIdle() can
35 //   normally be used to "flush" any pending FIDL requests and related work.
36 //   Note that this is not true if any services, or code under test, use threads
37 //   or processes!
38 //
39 // The test ComponentContext is typically instantiated within a test body or
40 // test base-class:
41 //
42 //   TEST(MyFunkyTest, IsFunky) {
43 //     TestComponentContextForProcess test_context;
44 //     // Configure the |test_context|.
45 //     // Run tests of code that uses ComponentContextForProcess().
46 //   }
47 //
48 // By default created context doesn't expose any services. Services from the
49 // original process-global ComponentContext (usually the environment in which
50 // the test process is running), can be exposed through the |test_context| with
51 // AddServices(), during test setup:
52 //
53 //   test_context.AddServices({fuchsia::memorypressure::Provider::Name_, ...});
54 //   // ... Execute tests which use fuchsia.memorypressure.Provider ...
55 //
56 // Alternatively InitialState::kCloneAll can be passed to the constructor to
57 // expose all services listed in /svc, e.g.:
58 //
59 //   TestComponentContextForProcess test_context(
60 //       TestComponentContextForProcess::InitialState::kCloneAll);
61 //
62 // Fake/mock implementations can be exposed via additional_services():
63 //
64 //   ScopedServiceBinding<funky::Service> binding(
65 //       test_context.additional_services(), &funky_implementation);
66 //   // ... Execute tests which use funky.Service.
67 //
68 // Services published to the process' ComponentContext by code-under-test
69 // can be accessed via published_services():
70 //
71 //   funky::HamsterPtr hamster_service;
72 //   test_context.published_services()->Connect(hamster_service.NewRequest());
73 //   // ... Execute tests which exercise the funky.Hamster implementation.
74 //
75 class BASE_EXPORT TestComponentContextForProcess {
76  public:
77   enum class InitialState {
78     kEmpty,
79     kCloneAll,
80   };
81 
82   explicit TestComponentContextForProcess(
83       InitialState initial_state = InitialState::kEmpty);
84   ~TestComponentContextForProcess();
85 
86   TestComponentContextForProcess(const TestComponentContextForProcess&) =
87       delete;
88   TestComponentContextForProcess& operator=(
89       const TestComponentContextForProcess&) = delete;
90 
91   // Returns an OutgoingDirectory into which additional services may be
92   // published for use by the code-under test.
93   sys::OutgoingDirectory* additional_services();
94 
95   // Allows the specified service(s) from the original ComponentContext to be
96   // exposed via the test default ComponentContext.
97   void AddService(const base::StringPiece service);
98   void AddServices(base::span<const base::StringPiece> services);
99 
100   // Returns the directory of services that the code under test has published
101   // to its outgoing service directory.
published_services()102   std::shared_ptr<sys::ServiceDirectory> published_services() const {
103     return published_services_;
104   }
105 
106   fidl::UnownedClientEnd<fuchsia_io::Directory> published_services_natural();
107 
108  private:
109   std::unique_ptr<sys::ComponentContext> old_context_;
110 
111   std::unique_ptr<FilteredServiceDirectory> context_services_;
112   std::shared_ptr<sys::ServiceDirectory> published_services_;
113   fidl::ClientEnd<fuchsia_io::Directory> published_services_natural_;
114 };
115 
116 }  // namespace base
117 
118 #endif  // BASE_FUCHSIA_TEST_COMPONENT_CONTEXT_FOR_PROCESS_H_
119