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