Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: mojo/edk/test/mojo_test_base.h

Issue 1585493002: [mojo] Ports EDK (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
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 MOJO_EDK_TEST_MOJO_TEST_BASE_H_
6 #define MOJO_EDK_TEST_MOJO_TEST_BASE_H_
7
8 #include <string>
9 #include <utility>
10
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/logging.h"
14 #include "base/macros.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/message_loop/message_loop.h"
18 #include "base/run_loop.h"
19 #include "base/task_runner.h"
20 #include "base/thread_task_runner_handle.h"
21 #include "mojo/edk/embedder/embedder.h"
22 #include "mojo/edk/test/multiprocess_test_helper.h"
23 #include "mojo/public/c/system/types.h"
24 #include "mojo/public/cpp/system/message_pipe.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 namespace mojo {
28 namespace edk {
29 namespace test {
30
31 class MojoTestBase : public testing::Test {
32 public:
33 MojoTestBase();
34 ~MojoTestBase() override;
35
36 protected:
37 using HandlerCallback = base::Callback<void(ScopedMessagePipeHandle)>;
38
39 class ClientController {
40 public:
41 ClientController(const std::string& client_name,
42 MojoTestBase* test,
43 const HandlerCallback& callback);
44 ~ClientController();
45
46 int WaitForShutdown();
47
48 private:
49 friend class MojoTestBase;
50
51 MojoTestBase* test_;
52 MultiprocessTestHelper helper_;
53 bool was_shutdown_ = false;
54
55 DISALLOW_COPY_AND_ASSIGN(ClientController);
56 };
57
58 ClientController& StartClient(
59 const std::string& client_name,
60 const HandlerCallback& callback);
61
62 static void RunHandlerOnMainThread(
63 std::function<void(MojoHandle, int*, const base::Closure&)> handler,
64 int* expected_exit_code,
65 const base::Closure& quit_closure,
66 ScopedMessagePipeHandle pipe) {
67 handler(pipe.get().value(), expected_exit_code, quit_closure);
68 }
69
70 static void RunHandler(
71 std::function<void(MojoHandle, int*, const base::Closure&)> handler,
72 int* expected_exit_code,
73 const base::Closure& quit_closure,
74 scoped_refptr<base::TaskRunner> task_runner,
75 ScopedMessagePipeHandle pipe) {
76 task_runner->PostTask(
77 FROM_HERE,
78 base::Bind(&RunHandlerOnMainThread, handler,
79 base::Unretained(expected_exit_code), quit_closure,
80 base::Passed(&pipe)));
81 }
82
83 template <typename HandlerFunc>
84 void StartClientWithHandler(const std::string& client_name,
85 HandlerFunc handler) {
86 base::MessageLoop::ScopedNestableTaskAllower nesting(&message_loop_);
87 base::RunLoop run_loop;
88 int expected_exit_code;
89 ClientController& c =
90 StartClient(client_name,
91 base::Bind(&RunHandler, handler,
92 base::Unretained(&expected_exit_code),
93 run_loop.QuitClosure(),
94 base::ThreadTaskRunnerHandle::Get()));
95 run_loop.Run();
96 EXPECT_EQ(expected_exit_code, c.WaitForShutdown());
97 }
98
99 // Closes a handle and expects success.
100 static void CloseHandle(MojoHandle h);
101
102 ////// Message pipe test utilities ///////
103
104 // Creates a new pipe, returning endpoint handles in |p0| and |p1|.
105 static void CreateMessagePipe(MojoHandle* p0, MojoHandle* p1);
106
107 // Writes a string to the pipe, transferring handles in the process.
108 static void WriteMessageWithHandles(MojoHandle mp,
109 const std::string& message,
110 const MojoHandle* handles,
111 uint32_t num_handles);
112
113 // Writes a string to the pipe with no handles.
114 static void WriteMessage(MojoHandle mp, const std::string& message);
115
116 // Reads a string from the pipe, expecting to read an exact number of handles
117 // in the process. Returns the read string.
118 static std::string ReadMessageWithHandles(MojoHandle mp,
119 MojoHandle* handles,
120 uint32_t expected_num_handles);
121
122 // Reads a string from the pipe, expecting either zero or one handles.
123 // If no handle is read, |handle| will be reset.
124 static std::string ReadMessageWithOptionalHandle(MojoHandle mp,
125 MojoHandle* handle);
126
127 // Reads a string from the pipe, expecting to read no handles.
128 // Returns the string.
129 static std::string ReadMessage(MojoHandle mp);
130
131 // Reads a string from the pipe, expecting to read no handles and exactly
132 // |num_bytes| bytes, which are read into |data|.
133 static void ReadMessage(MojoHandle mp, char* data, size_t num_bytes);
134
135 // Writes |message| to |in| and expects to read it back from |out|.
136 static void VerifyTransmission(MojoHandle in,
137 MojoHandle out,
138 const std::string& message);
139
140 // Writes |message| to |mp| and expects to read it back from the same handle.
141 static void VerifyEcho(MojoHandle mp, const std::string& message);
142
143 //////// Shared buffer test utilities /////////
144
145 // Creates a new shared buffer.
146 static MojoHandle CreateBuffer(uint64_t size);
147
148 // Duplicates a shared buffer to a new handle.
149 static MojoHandle DuplicateBuffer(MojoHandle h);
150
151 // Maps a buffer, writes some data into it, and unmaps it.
152 static void WriteToBuffer(MojoHandle h,
153 size_t offset,
154 const base::StringPiece& s);
155
156 // Maps a buffer, tests the value of some of its contents, and unmaps it.
157 static void ExpectBufferContents(MojoHandle h,
158 size_t offset,
159 const base::StringPiece& s);
160
161 private:
162 friend class ClientController;
163
164 base::MessageLoop message_loop_;
165 std::vector<scoped_ptr<ClientController>> clients_;
166
167 DISALLOW_COPY_AND_ASSIGN(MojoTestBase);
168 };
169
170 // Launches a new child process running the test client |client_name| connected
171 // to a new message pipe bound to |pipe_name|. |pipe_name| is automatically
172 // closed on test teardown.
173 #define RUN_CHILD_ON_PIPE(client_name, pipe_name) \
174 StartClientWithHandler( \
175 #client_name, \
176 [&](MojoHandle pipe_name, \
177 int *expected_exit_code, \
178 const base::Closure& quit_closure) { {
179
180 // Waits for the client to terminate and expects a return code of zero.
181 #define END_CHILD() \
182 } \
183 *expected_exit_code = 0; \
184 quit_closure.Run(); \
185 });
186
187 // Wait for the client to terminate with a specific return code.
188 #define END_CHILD_AND_EXPECT_EXIT_CODE(code) \
189 } \
190 *expected_exit_code = code; \
191 quit_closure.Run(); \
192 });
193
194 // Use this to declare the child process's "main()" function for tests using
195 // MojoTestBase and MultiprocessTestHelper. It returns an |int|, which will
196 // will be the process's exit code (but see the comment about
197 // WaitForChildShutdown()).
198 //
199 // The function is defined as a static member of a subclass of |test_base|
200 // to facilitate shared code between test clients.
201 //
202 // |pipe_name| will be bound to the MojoHandle of a message pipe connected
203 // to the parent process (see RUN_CHILD_ON_PIPE above.) This pipe handle is
204 // automatically closed on test client teardown.
205 #define DEFINE_TEST_CLIENT_WITH_PIPE(client_name, test_base, pipe_name) \
206 class client_name##_MainFixture : public test_base { \
207 public: \
208 static int ClientMain(MojoHandle pipe); \
209 }; \
210 MULTIPROCESS_TEST_MAIN_WITH_SETUP( \
211 client_name##TestChildMain, \
212 test::MultiprocessTestHelper::ChildSetup) { \
213 return test::MultiprocessTestHelper::RunClientMain( \
214 base::Bind(&client_name##_MainFixture::ClientMain)); \
215 } \
216 int client_name##_MainFixture::ClientMain(MojoHandle pipe_name)
217
218
219 // This is a version of DEFINE_TEST_CLIENT_WITH_PIPE which can be used with
220 // gtest ASSERT/EXPECT macros.
221 #define DEFINE_TEST_CLIENT_TEST_WITH_PIPE(client_name, test_base, pipe_name) \
222 class client_name##_MainFixture : public test_base { \
223 public: \
224 static void ClientMain(MojoHandle pipe); \
225 }; \
226 MULTIPROCESS_TEST_MAIN_WITH_SETUP( \
227 client_name##TestChildMain, \
228 test::MultiprocessTestHelper::ChildSetup) { \
229 return test::MultiprocessTestHelper::RunClientTestMain( \
230 base::Bind(&client_name##_MainFixture::ClientMain)); \
231 } \
232 void client_name##_MainFixture::ClientMain(MojoHandle pipe_name)
233
234
235
236 } // namespace test
237 } // namespace edk
238 } // namespace mojo
239
240 #endif // MOJO_EDK_TEST_MOJO_TEST_BASE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698