Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / mojo / public / cpp / system / tests / core_unittest.cc
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.
4
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.
8
9 #include "mojo/public/cpp/system/core.h"
10
11 #include <map>
12
13 #include "mojo/public/cpp/system/macros.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace mojo {
17 namespace {
18
19 TEST(CoreCppTest, GetTimeTicksNow) {
20   const MojoTimeTicks start = GetTimeTicksNow();
21   EXPECT_NE(static_cast<MojoTimeTicks>(0), start)
22       << "GetTimeTicksNow should return nonzero value";
23 }
24
25 TEST(CoreCppTest, Basic) {
26   // Basic |Handle| implementation:
27   {
28     EXPECT_EQ(MOJO_HANDLE_INVALID, kInvalidHandleValue);
29
30     Handle h0;
31     EXPECT_EQ(kInvalidHandleValue, h0.value());
32     EXPECT_EQ(kInvalidHandleValue, *h0.mutable_value());
33     EXPECT_FALSE(h0.is_valid());
34
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());
42
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());
47
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());
54
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());
61
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;
72
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());
84
85     // TODO(vtl): With C++11, support |std::unordered_map|s, etc. (Or figure out
86     // how to support the variations of |hash_map|.)
87   }
88
89   // |Handle|/|ScopedHandle| functions:
90   {
91     ScopedHandle h;
92
93     EXPECT_EQ(kInvalidHandleValue, h.get().value());
94
95     // This should be a no-op.
96     Close(h.Pass());
97
98     // It should still be invalid.
99     EXPECT_EQ(kInvalidHandleValue, h.get().value());
100
101     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
102               Wait(h.get(), ~MOJO_HANDLE_SIGNAL_NONE, 1000000));
103
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));
110   }
111
112   // |MakeScopedHandle| (just compilation tests):
113   {
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());
119   }
120
121   // |MessagePipeHandle|/|ScopedMessagePipeHandle| functions:
122   {
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,
135                               0,
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));
152
153     // Basic tests of waiting and closing.
154     MojoHandle hv0 = kInvalidHandleValue;
155     {
156       ScopedMessagePipeHandle h0;
157       ScopedMessagePipeHandle h1;
158       EXPECT_FALSE(h0.get().is_valid());
159       EXPECT_FALSE(h1.get().is_valid());
160
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();
169
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));
179
180       // Test closing |h1| explicitly.
181       Close(h1.Pass());
182       EXPECT_FALSE(h1.get().is_valid());
183
184       // Make sure |h1| is closed.
185       EXPECT_EQ(
186           MOJO_RESULT_INVALID_ARGUMENT,
187           MojoWait(hv1, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE));
188
189       EXPECT_EQ(
190           MOJO_RESULT_FAILED_PRECONDITION,
191           Wait(
192               h0.get(), MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
193     }
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));
197
198     // Actually test writing/reading messages.
199     {
200       ScopedMessagePipeHandle h0;
201       ScopedMessagePipeHandle h1;
202       CreateMessagePipe(nullptr, &h0, &h1);
203
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,
211                                 0,
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);
228
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;
233
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,
242                                 0,
243                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
244
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]));
260
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]);
282
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);
306     }
307     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(hv0));
308   }
309
310   // TODO(vtl): Test |CloseRaw()|.
311   // TODO(vtl): Test |reset()| more thoroughly?
312 }
313
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.
317   {
318     ScopedMessagePipeHandle h0;
319     ScopedMessagePipeHandle h1;
320     CreateMessagePipe(nullptr, &h0, &h1);
321
322     // Send a handle over the previously-establish message pipe.
323     ScopedMessagePipeHandle h2;
324     ScopedMessagePipeHandle h3;
325     CreateMessagePipe(nullptr, &h2, &h3);
326
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,
335                               0,
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,
343                               0,
344                               MOJO_WRITE_MESSAGE_FLAG_NONE));
345
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,
358                               1,
359                               MOJO_WRITE_MESSAGE_FLAG_NONE));
360     // |h3_value| should actually be invalid now.
361     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(h3_value));
362
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()));
366   }
367
368   // Do this in a different order: make the enqueued message pipe handle only
369   // half-alive.
370   {
371     ScopedMessagePipeHandle h0;
372     ScopedMessagePipeHandle h1;
373     CreateMessagePipe(nullptr, &h0, &h1);
374
375     // Send a handle over the previously-establish message pipe.
376     ScopedMessagePipeHandle h2;
377     ScopedMessagePipeHandle h3;
378     CreateMessagePipe(nullptr, &h2, &h3);
379
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,
388                               0,
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,
396                               0,
397                               MOJO_WRITE_MESSAGE_FLAG_NONE));
398
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,
411                               1,
412                               MOJO_WRITE_MESSAGE_FLAG_NONE));
413     // |h3_value| should actually be invalid now.
414     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(h3_value));
415
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()));
419   }
420 }
421
422 TEST(CoreCppTest, ScopedHandleMoveCtor) {
423   ScopedSharedBufferHandle buffer1;
424   EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer1));
425   EXPECT_TRUE(buffer1.is_valid());
426
427   ScopedSharedBufferHandle buffer2;
428   EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer2));
429   EXPECT_TRUE(buffer2.is_valid());
430
431   // If this fails to close buffer1, ScopedHandleBase::CloseIfNecessary() will
432   // assert.
433   buffer1 = buffer2.Pass();
434
435   EXPECT_TRUE(buffer1.is_valid());
436   EXPECT_FALSE(buffer2.is_valid());
437 }
438
439 TEST(CoreCppTest, ScopedHandleMoveCtorSelf) {
440   ScopedSharedBufferHandle buffer1;
441   EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer1));
442   EXPECT_TRUE(buffer1.is_valid());
443
444   buffer1 = buffer1.Pass();
445
446   EXPECT_TRUE(buffer1.is_valid());
447 }
448
449 // TODO(vtl): Write data pipe tests.
450
451 }  // namespace
452 }  // namespace mojo