Remove the RenderProcessHost observer and attach the WebContentsObserver earlier...
[chromium-blink-merge.git] / mojo / public / cpp / system / tests / core_unittest.cc
blob90650e7a60ba514198c5f79cc5dfd33a00575177
1 // Copyright 2014 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.
5 // This file tests the C++ Mojo system core wrappers.
6 // TODO(vtl): Maybe rename "CoreCppTest" -> "CoreTest" if/when this gets
7 // compiled into a different binary from the C API tests.
9 #include "mojo/public/cpp/system/core.h"
11 #include <map>
13 #include "mojo/public/cpp/system/macros.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace mojo {
17 namespace {
19 TEST(CoreCppTest, GetTimeTicksNow) {
20 const MojoTimeTicks start = GetTimeTicksNow();
21 EXPECT_NE(static_cast<MojoTimeTicks>(0), start)
22 << "GetTimeTicksNow should return nonzero value";
25 TEST(CoreCppTest, Basic) {
26 // Basic |Handle| implementation:
28 EXPECT_EQ(MOJO_HANDLE_INVALID, kInvalidHandleValue);
30 Handle h0;
31 EXPECT_EQ(kInvalidHandleValue, h0.value());
32 EXPECT_EQ(kInvalidHandleValue, *h0.mutable_value());
33 EXPECT_FALSE(h0.is_valid());
35 Handle h1(static_cast<MojoHandle>(123));
36 EXPECT_EQ(static_cast<MojoHandle>(123), h1.value());
37 EXPECT_EQ(static_cast<MojoHandle>(123), *h1.mutable_value());
38 EXPECT_TRUE(h1.is_valid());
39 *h1.mutable_value() = static_cast<MojoHandle>(456);
40 EXPECT_EQ(static_cast<MojoHandle>(456), h1.value());
41 EXPECT_TRUE(h1.is_valid());
43 h1.swap(h0);
44 EXPECT_EQ(static_cast<MojoHandle>(456), h0.value());
45 EXPECT_TRUE(h0.is_valid());
46 EXPECT_FALSE(h1.is_valid());
48 h1.set_value(static_cast<MojoHandle>(789));
49 h0.swap(h1);
50 EXPECT_EQ(static_cast<MojoHandle>(789), h0.value());
51 EXPECT_TRUE(h0.is_valid());
52 EXPECT_EQ(static_cast<MojoHandle>(456), h1.value());
53 EXPECT_TRUE(h1.is_valid());
55 // Make sure copy constructor works.
56 Handle h2(h0);
57 EXPECT_EQ(static_cast<MojoHandle>(789), h2.value());
58 // And assignment.
59 h2 = h1;
60 EXPECT_EQ(static_cast<MojoHandle>(456), h2.value());
62 // Make sure that we can put |Handle|s into |std::map|s.
63 h0 = Handle(static_cast<MojoHandle>(987));
64 h1 = Handle(static_cast<MojoHandle>(654));
65 h2 = Handle(static_cast<MojoHandle>(321));
66 Handle h3;
67 std::map<Handle, int> handle_to_int;
68 handle_to_int[h0] = 0;
69 handle_to_int[h1] = 1;
70 handle_to_int[h2] = 2;
71 handle_to_int[h3] = 3;
73 EXPECT_EQ(4u, handle_to_int.size());
74 EXPECT_FALSE(handle_to_int.find(h0) == handle_to_int.end());
75 EXPECT_EQ(0, handle_to_int[h0]);
76 EXPECT_FALSE(handle_to_int.find(h1) == handle_to_int.end());
77 EXPECT_EQ(1, handle_to_int[h1]);
78 EXPECT_FALSE(handle_to_int.find(h2) == handle_to_int.end());
79 EXPECT_EQ(2, handle_to_int[h2]);
80 EXPECT_FALSE(handle_to_int.find(h3) == handle_to_int.end());
81 EXPECT_EQ(3, handle_to_int[h3]);
82 EXPECT_TRUE(handle_to_int.find(Handle(static_cast<MojoHandle>(13579))) ==
83 handle_to_int.end());
85 // TODO(vtl): With C++11, support |std::unordered_map|s, etc. (Or figure out
86 // how to support the variations of |hash_map|.)
89 // |Handle|/|ScopedHandle| functions:
91 ScopedHandle h;
93 EXPECT_EQ(kInvalidHandleValue, h.get().value());
95 // This should be a no-op.
96 Close(h.Pass());
98 // It should still be invalid.
99 EXPECT_EQ(kInvalidHandleValue, h.get().value());
101 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
102 Wait(h.get(), ~MOJO_HANDLE_SIGNAL_NONE, 1000000));
104 std::vector<Handle> wh;
105 wh.push_back(h.get());
106 std::vector<MojoHandleSignals> sigs;
107 sigs.push_back(~MOJO_HANDLE_SIGNAL_NONE);
108 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
109 WaitMany(wh, sigs, MOJO_DEADLINE_INDEFINITE));
112 // |MakeScopedHandle| (just compilation tests):
114 EXPECT_FALSE(MakeScopedHandle(Handle()).is_valid());
115 EXPECT_FALSE(MakeScopedHandle(MessagePipeHandle()).is_valid());
116 EXPECT_FALSE(MakeScopedHandle(DataPipeProducerHandle()).is_valid());
117 EXPECT_FALSE(MakeScopedHandle(DataPipeConsumerHandle()).is_valid());
118 EXPECT_FALSE(MakeScopedHandle(SharedBufferHandle()).is_valid());
121 // |MessagePipeHandle|/|ScopedMessagePipeHandle| functions:
123 MessagePipeHandle h_invalid;
124 EXPECT_FALSE(h_invalid.is_valid());
125 EXPECT_EQ(
126 MOJO_RESULT_INVALID_ARGUMENT,
127 WriteMessageRaw(
128 h_invalid, nullptr, 0, nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
129 char buffer[10] = {0};
130 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
131 WriteMessageRaw(h_invalid,
132 buffer,
133 sizeof(buffer),
134 nullptr,
136 MOJO_WRITE_MESSAGE_FLAG_NONE));
137 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
138 ReadMessageRaw(h_invalid,
139 nullptr,
140 nullptr,
141 nullptr,
142 nullptr,
143 MOJO_READ_MESSAGE_FLAG_NONE));
144 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
145 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
146 ReadMessageRaw(h_invalid,
147 buffer,
148 &buffer_size,
149 nullptr,
150 nullptr,
151 MOJO_READ_MESSAGE_FLAG_NONE));
153 // Basic tests of waiting and closing.
154 MojoHandle hv0 = kInvalidHandleValue;
156 ScopedMessagePipeHandle h0;
157 ScopedMessagePipeHandle h1;
158 EXPECT_FALSE(h0.get().is_valid());
159 EXPECT_FALSE(h1.get().is_valid());
161 CreateMessagePipe(nullptr, &h0, &h1);
162 EXPECT_TRUE(h0.get().is_valid());
163 EXPECT_TRUE(h1.get().is_valid());
164 EXPECT_NE(h0.get().value(), h1.get().value());
165 // Save the handle values, so we can check that things got closed
166 // correctly.
167 hv0 = h0.get().value();
168 MojoHandle hv1 = h1.get().value();
170 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
171 Wait(h0.get(), MOJO_HANDLE_SIGNAL_READABLE, 0));
172 std::vector<Handle> wh;
173 wh.push_back(h0.get());
174 wh.push_back(h1.get());
175 std::vector<MojoHandleSignals> sigs;
176 sigs.push_back(MOJO_HANDLE_SIGNAL_READABLE);
177 sigs.push_back(MOJO_HANDLE_SIGNAL_WRITABLE);
178 EXPECT_EQ(1, WaitMany(wh, sigs, 1000));
180 // Test closing |h1| explicitly.
181 Close(h1.Pass());
182 EXPECT_FALSE(h1.get().is_valid());
184 // Make sure |h1| is closed.
185 EXPECT_EQ(
186 MOJO_RESULT_INVALID_ARGUMENT,
187 MojoWait(hv1, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE));
189 EXPECT_EQ(
190 MOJO_RESULT_FAILED_PRECONDITION,
191 Wait(
192 h0.get(), MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
194 // |hv0| should have been closed when |h0| went out of scope, so this close
195 // should fail.
196 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(hv0));
198 // Actually test writing/reading messages.
200 ScopedMessagePipeHandle h0;
201 ScopedMessagePipeHandle h1;
202 CreateMessagePipe(nullptr, &h0, &h1);
204 const char kHello[] = "hello";
205 const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello));
206 EXPECT_EQ(MOJO_RESULT_OK,
207 WriteMessageRaw(h0.get(),
208 kHello,
209 kHelloSize,
210 nullptr,
212 MOJO_WRITE_MESSAGE_FLAG_NONE));
213 EXPECT_EQ(
214 MOJO_RESULT_OK,
215 Wait(
216 h1.get(), MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
217 char buffer[10] = {0};
218 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
219 EXPECT_EQ(MOJO_RESULT_OK,
220 ReadMessageRaw(h1.get(),
221 buffer,
222 &buffer_size,
223 nullptr,
224 nullptr,
225 MOJO_READ_MESSAGE_FLAG_NONE));
226 EXPECT_EQ(kHelloSize, buffer_size);
227 EXPECT_STREQ(kHello, buffer);
229 // Send a handle over the previously-establish message pipe. Use the
230 // |MessagePipe| wrapper (to test it), which automatically creates a
231 // message pipe.
232 MessagePipe mp;
234 // Write a message to |mp.handle0|, before we send |mp.handle1|.
235 const char kWorld[] = "world!";
236 const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld));
237 EXPECT_EQ(MOJO_RESULT_OK,
238 WriteMessageRaw(mp.handle0.get(),
239 kWorld,
240 kWorldSize,
241 nullptr,
243 MOJO_WRITE_MESSAGE_FLAG_NONE));
245 // Send |mp.handle1| over |h1| to |h0|.
246 MojoHandle handles[5];
247 handles[0] = mp.handle1.release().value();
248 EXPECT_NE(kInvalidHandleValue, handles[0]);
249 EXPECT_FALSE(mp.handle1.get().is_valid());
250 uint32_t handles_count = 1;
251 EXPECT_EQ(MOJO_RESULT_OK,
252 WriteMessageRaw(h1.get(),
253 kHello,
254 kHelloSize,
255 handles,
256 handles_count,
257 MOJO_WRITE_MESSAGE_FLAG_NONE));
258 // |handles[0]| should actually be invalid now.
259 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handles[0]));
261 // Read "hello" and the sent handle.
262 EXPECT_EQ(
263 MOJO_RESULT_OK,
264 Wait(
265 h0.get(), MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
266 memset(buffer, 0, sizeof(buffer));
267 buffer_size = static_cast<uint32_t>(sizeof(buffer));
268 for (size_t i = 0; i < MOJO_ARRAYSIZE(handles); i++)
269 handles[i] = kInvalidHandleValue;
270 handles_count = static_cast<uint32_t>(MOJO_ARRAYSIZE(handles));
271 EXPECT_EQ(MOJO_RESULT_OK,
272 ReadMessageRaw(h0.get(),
273 buffer,
274 &buffer_size,
275 handles,
276 &handles_count,
277 MOJO_READ_MESSAGE_FLAG_NONE));
278 EXPECT_EQ(kHelloSize, buffer_size);
279 EXPECT_STREQ(kHello, buffer);
280 EXPECT_EQ(1u, handles_count);
281 EXPECT_NE(kInvalidHandleValue, handles[0]);
283 // Read from the sent/received handle.
284 mp.handle1.reset(MessagePipeHandle(handles[0]));
285 // Save |handles[0]| to check that it gets properly closed.
286 hv0 = handles[0];
287 EXPECT_EQ(MOJO_RESULT_OK,
288 Wait(mp.handle1.get(),
289 MOJO_HANDLE_SIGNAL_READABLE,
290 MOJO_DEADLINE_INDEFINITE));
291 memset(buffer, 0, sizeof(buffer));
292 buffer_size = static_cast<uint32_t>(sizeof(buffer));
293 for (size_t i = 0; i < MOJO_ARRAYSIZE(handles); i++)
294 handles[i] = kInvalidHandleValue;
295 handles_count = static_cast<uint32_t>(MOJO_ARRAYSIZE(handles));
296 EXPECT_EQ(MOJO_RESULT_OK,
297 ReadMessageRaw(mp.handle1.get(),
298 buffer,
299 &buffer_size,
300 handles,
301 &handles_count,
302 MOJO_READ_MESSAGE_FLAG_NONE));
303 EXPECT_EQ(kWorldSize, buffer_size);
304 EXPECT_STREQ(kWorld, buffer);
305 EXPECT_EQ(0u, handles_count);
307 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(hv0));
310 // TODO(vtl): Test |CloseRaw()|.
311 // TODO(vtl): Test |reset()| more thoroughly?
314 TEST(CoreCppTest, TearDownWithMessagesEnqueued) {
315 // Tear down a message pipe which still has a message enqueued, with the
316 // message also having a valid message pipe handle.
318 ScopedMessagePipeHandle h0;
319 ScopedMessagePipeHandle h1;
320 CreateMessagePipe(nullptr, &h0, &h1);
322 // Send a handle over the previously-establish message pipe.
323 ScopedMessagePipeHandle h2;
324 ScopedMessagePipeHandle h3;
325 CreateMessagePipe(nullptr, &h2, &h3);
327 // Write a message to |h2|, before we send |h3|.
328 const char kWorld[] = "world!";
329 const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld));
330 EXPECT_EQ(MOJO_RESULT_OK,
331 WriteMessageRaw(h2.get(),
332 kWorld,
333 kWorldSize,
334 nullptr,
336 MOJO_WRITE_MESSAGE_FLAG_NONE));
337 // And also a message to |h3|.
338 EXPECT_EQ(MOJO_RESULT_OK,
339 WriteMessageRaw(h3.get(),
340 kWorld,
341 kWorldSize,
342 nullptr,
344 MOJO_WRITE_MESSAGE_FLAG_NONE));
346 // Send |h3| over |h1| to |h0|.
347 const char kHello[] = "hello";
348 const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello));
349 MojoHandle h3_value;
350 h3_value = h3.release().value();
351 EXPECT_NE(kInvalidHandleValue, h3_value);
352 EXPECT_FALSE(h3.get().is_valid());
353 EXPECT_EQ(MOJO_RESULT_OK,
354 WriteMessageRaw(h1.get(),
355 kHello,
356 kHelloSize,
357 &h3_value,
359 MOJO_WRITE_MESSAGE_FLAG_NONE));
360 // |h3_value| should actually be invalid now.
361 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(h3_value));
363 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0.release().value()));
364 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1.release().value()));
365 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h2.release().value()));
368 // Do this in a different order: make the enqueued message pipe handle only
369 // half-alive.
371 ScopedMessagePipeHandle h0;
372 ScopedMessagePipeHandle h1;
373 CreateMessagePipe(nullptr, &h0, &h1);
375 // Send a handle over the previously-establish message pipe.
376 ScopedMessagePipeHandle h2;
377 ScopedMessagePipeHandle h3;
378 CreateMessagePipe(nullptr, &h2, &h3);
380 // Write a message to |h2|, before we send |h3|.
381 const char kWorld[] = "world!";
382 const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld));
383 EXPECT_EQ(MOJO_RESULT_OK,
384 WriteMessageRaw(h2.get(),
385 kWorld,
386 kWorldSize,
387 nullptr,
389 MOJO_WRITE_MESSAGE_FLAG_NONE));
390 // And also a message to |h3|.
391 EXPECT_EQ(MOJO_RESULT_OK,
392 WriteMessageRaw(h3.get(),
393 kWorld,
394 kWorldSize,
395 nullptr,
397 MOJO_WRITE_MESSAGE_FLAG_NONE));
399 // Send |h3| over |h1| to |h0|.
400 const char kHello[] = "hello";
401 const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello));
402 MojoHandle h3_value;
403 h3_value = h3.release().value();
404 EXPECT_NE(kInvalidHandleValue, h3_value);
405 EXPECT_FALSE(h3.get().is_valid());
406 EXPECT_EQ(MOJO_RESULT_OK,
407 WriteMessageRaw(h1.get(),
408 kHello,
409 kHelloSize,
410 &h3_value,
412 MOJO_WRITE_MESSAGE_FLAG_NONE));
413 // |h3_value| should actually be invalid now.
414 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(h3_value));
416 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h2.release().value()));
417 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0.release().value()));
418 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1.release().value()));
422 TEST(CoreCppTest, ScopedHandleMoveCtor) {
423 ScopedSharedBufferHandle buffer1;
424 EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer1));
425 EXPECT_TRUE(buffer1.is_valid());
427 ScopedSharedBufferHandle buffer2;
428 EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer2));
429 EXPECT_TRUE(buffer2.is_valid());
431 // If this fails to close buffer1, ScopedHandleBase::CloseIfNecessary() will
432 // assert.
433 buffer1 = buffer2.Pass();
435 EXPECT_TRUE(buffer1.is_valid());
436 EXPECT_FALSE(buffer2.is_valid());
439 TEST(CoreCppTest, ScopedHandleMoveCtorSelf) {
440 ScopedSharedBufferHandle buffer1;
441 EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer1));
442 EXPECT_TRUE(buffer1.is_valid());
444 buffer1 = buffer1.Pass();
446 EXPECT_TRUE(buffer1.is_valid());
449 // TODO(vtl): Write data pipe tests.
451 } // namespace
452 } // namespace mojo