1 // Copyright 2013 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 API.
7 #include "mojo/public/c/system/core.h"
11 #include "testing/gtest/include/gtest/gtest.h"
16 const MojoHandleSignals kSignalReadadableWritable
=
17 MOJO_HANDLE_SIGNAL_READABLE
| MOJO_HANDLE_SIGNAL_WRITABLE
;
19 const MojoHandleSignals kSignalAll
= MOJO_HANDLE_SIGNAL_READABLE
|
20 MOJO_HANDLE_SIGNAL_WRITABLE
|
21 MOJO_HANDLE_SIGNAL_PEER_CLOSED
;
23 TEST(CoreTest
, GetTimeTicksNow
) {
24 const MojoTimeTicks start
= MojoGetTimeTicksNow();
25 EXPECT_NE(static_cast<MojoTimeTicks
>(0), start
)
26 << "MojoGetTimeTicksNow should return nonzero value";
29 // The only handle that's guaranteed to be invalid is |MOJO_HANDLE_INVALID|.
30 // Tests that everything that takes a handle properly recognizes it.
31 TEST(CoreTest
, InvalidHandle
) {
33 MojoHandleSignals sig
;
34 char buffer
[10] = {0};
37 const void* read_pointer
;
40 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
, MojoClose(MOJO_HANDLE_INVALID
));
43 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
,
44 MojoNewWait(MOJO_HANDLE_INVALID
, ~MOJO_HANDLE_SIGNAL_NONE
, 1000000,
47 h0
= MOJO_HANDLE_INVALID
;
48 sig
= ~MOJO_HANDLE_SIGNAL_NONE
;
50 MOJO_RESULT_INVALID_ARGUMENT
,
51 MojoNewWaitMany(&h0
, &sig
, 1, MOJO_DEADLINE_INDEFINITE
, NULL
, NULL
));
55 MOJO_RESULT_INVALID_ARGUMENT
,
56 MojoWriteMessage(h0
, buffer
, 3, NULL
, 0, MOJO_WRITE_MESSAGE_FLAG_NONE
));
57 buffer_size
= static_cast<uint32_t>(sizeof(buffer
));
58 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
,
59 MojoReadMessage(h0
, buffer
, &buffer_size
, NULL
, NULL
,
60 MOJO_READ_MESSAGE_FLAG_NONE
));
63 buffer_size
= static_cast<uint32_t>(sizeof(buffer
));
64 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
,
65 MojoWriteData(h0
, buffer
, &buffer_size
, MOJO_WRITE_DATA_FLAG_NONE
));
67 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
,
68 MojoBeginWriteData(h0
, &write_pointer
, &buffer_size
,
69 MOJO_WRITE_DATA_FLAG_NONE
));
70 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
, MojoEndWriteData(h0
, 1));
71 buffer_size
= static_cast<uint32_t>(sizeof(buffer
));
72 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
,
73 MojoReadData(h0
, buffer
, &buffer_size
, MOJO_READ_DATA_FLAG_NONE
));
75 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
,
76 MojoBeginReadData(h0
, &read_pointer
, &buffer_size
,
77 MOJO_READ_DATA_FLAG_NONE
));
78 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
, MojoEndReadData(h0
, 1));
81 h1
= MOJO_HANDLE_INVALID
;
82 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
,
83 MojoDuplicateBufferHandle(h0
, NULL
, &h1
));
84 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
,
85 MojoMapBuffer(h0
, 0, 1, &write_pointer
, MOJO_MAP_BUFFER_FLAG_NONE
));
88 TEST(CoreTest
, BasicMessagePipe
) {
90 MojoHandleSignals sig
;
91 char buffer
[10] = {0};
94 h0
= MOJO_HANDLE_INVALID
;
95 h1
= MOJO_HANDLE_INVALID
;
96 EXPECT_EQ(MOJO_RESULT_OK
, MojoCreateMessagePipe(NULL
, &h0
, &h1
));
97 EXPECT_NE(h0
, MOJO_HANDLE_INVALID
);
98 EXPECT_NE(h1
, MOJO_HANDLE_INVALID
);
100 // Shouldn't be readable, we haven't written anything.
101 MojoHandleSignalsState state
;
102 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED
,
103 MojoNewWait(h0
, MOJO_HANDLE_SIGNAL_READABLE
, 0, &state
));
104 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE
, state
.satisfied_signals
);
105 EXPECT_EQ(kSignalAll
, state
.satisfiable_signals
);
107 // Should be writable.
108 EXPECT_EQ(MOJO_RESULT_OK
,
109 MojoNewWait(h0
, MOJO_HANDLE_SIGNAL_WRITABLE
, 0, &state
));
110 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE
, state
.satisfied_signals
);
111 EXPECT_EQ(kSignalAll
, state
.satisfiable_signals
);
114 buffer_size
= static_cast<uint32_t>(sizeof(buffer
));
115 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT
,
116 MojoReadMessage(h0
, buffer
, &buffer_size
, NULL
, NULL
,
117 MOJO_READ_MESSAGE_FLAG_NONE
));
120 static const char kHello
[] = "hello";
121 buffer_size
= static_cast<uint32_t>(sizeof(kHello
));
122 EXPECT_EQ(MOJO_RESULT_OK
, MojoWriteMessage(h1
, kHello
, buffer_size
, NULL
, 0,
123 MOJO_WRITE_MESSAGE_FLAG_NONE
));
125 // |h0| should be readable.
126 uint32_t result_index
= 1;
127 MojoHandleSignalsState states
[1];
128 sig
= MOJO_HANDLE_SIGNAL_READABLE
;
129 EXPECT_EQ(MOJO_RESULT_OK
,
130 MojoNewWaitMany(&h0
, &sig
, 1, MOJO_DEADLINE_INDEFINITE
,
131 &result_index
, states
));
133 EXPECT_EQ(0u, result_index
);
134 EXPECT_EQ(kSignalReadadableWritable
, states
[0].satisfied_signals
);
135 EXPECT_EQ(kSignalAll
, states
[0].satisfiable_signals
);
138 buffer_size
= static_cast<uint32_t>(sizeof(buffer
));
139 EXPECT_EQ(MOJO_RESULT_OK
, MojoReadMessage(h0
, buffer
, &buffer_size
, NULL
,
140 NULL
, MOJO_READ_MESSAGE_FLAG_NONE
));
141 EXPECT_EQ(static_cast<uint32_t>(sizeof(kHello
)), buffer_size
);
142 EXPECT_STREQ(kHello
, buffer
);
144 // |h0| should no longer be readable.
145 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED
,
146 MojoNewWait(h0
, MOJO_HANDLE_SIGNAL_READABLE
, 10, &state
));
148 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE
, state
.satisfied_signals
);
149 EXPECT_EQ(kSignalAll
, state
.satisfiable_signals
);
152 EXPECT_EQ(MOJO_RESULT_OK
, MojoClose(h0
));
154 // |h1| should no longer be readable or writable.
156 MOJO_RESULT_FAILED_PRECONDITION
,
157 MojoNewWait(h1
, MOJO_HANDLE_SIGNAL_READABLE
| MOJO_HANDLE_SIGNAL_WRITABLE
,
160 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED
, state
.satisfied_signals
);
161 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED
, state
.satisfiable_signals
);
163 EXPECT_EQ(MOJO_RESULT_OK
, MojoClose(h1
));
166 // TODO(ncbray): enable these tests once NaCl supports the corresponding APIs.
167 #ifdef __native_client__
168 #define MAYBE_BasicDataPipe DISABLED_BasicDataPipe
169 #define MAYBE_BasicSharedBuffer DISABLED_BasicSharedBuffer
171 #define MAYBE_BasicDataPipe BasicDataPipe
172 #define MAYBE_BasicSharedBuffer BasicSharedBuffer
175 TEST(CoreTest
, MAYBE_BasicDataPipe
) {
177 MojoHandleSignals sig
;
178 char buffer
[20] = {0};
179 uint32_t buffer_size
;
181 const void* read_pointer
;
183 hp
= MOJO_HANDLE_INVALID
;
184 hc
= MOJO_HANDLE_INVALID
;
185 EXPECT_EQ(MOJO_RESULT_OK
, MojoCreateDataPipe(NULL
, &hp
, &hc
));
186 EXPECT_NE(hp
, MOJO_HANDLE_INVALID
);
187 EXPECT_NE(hc
, MOJO_HANDLE_INVALID
);
189 // The consumer |hc| shouldn't be readable.
190 MojoHandleSignalsState state
;
191 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED
,
192 MojoNewWait(hc
, MOJO_HANDLE_SIGNAL_READABLE
, 0, &state
));
194 EXPECT_EQ(MOJO_HANDLE_SIGNAL_NONE
, state
.satisfied_signals
);
195 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE
| MOJO_HANDLE_SIGNAL_PEER_CLOSED
,
196 state
.satisfiable_signals
);
198 // The producer |hp| should be writable.
199 EXPECT_EQ(MOJO_RESULT_OK
,
200 MojoNewWait(hp
, MOJO_HANDLE_SIGNAL_WRITABLE
, 0, &state
));
202 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE
, state
.satisfied_signals
);
203 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE
| MOJO_HANDLE_SIGNAL_PEER_CLOSED
,
204 state
.satisfiable_signals
);
206 // Try to read from |hc|.
207 buffer_size
= static_cast<uint32_t>(sizeof(buffer
));
208 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT
,
209 MojoReadData(hc
, buffer
, &buffer_size
, MOJO_READ_DATA_FLAG_NONE
));
211 // Try to begin a two-phase read from |hc|.
213 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT
,
214 MojoBeginReadData(hc
, &read_pointer
, &buffer_size
,
215 MOJO_READ_DATA_FLAG_NONE
));
218 static const char kHello
[] = "hello ";
219 // Don't include terminating null.
220 buffer_size
= static_cast<uint32_t>(strlen(kHello
));
221 EXPECT_EQ(MOJO_RESULT_OK
, MojoWriteData(hp
, kHello
, &buffer_size
,
222 MOJO_WRITE_MESSAGE_FLAG_NONE
));
224 // |hc| should be(come) readable.
225 uint32_t result_index
= 1;
226 MojoHandleSignalsState states
[1];
227 sig
= MOJO_HANDLE_SIGNAL_READABLE
;
228 EXPECT_EQ(MOJO_RESULT_OK
,
229 MojoNewWaitMany(&hc
, &sig
, 1, MOJO_DEADLINE_INDEFINITE
,
230 &result_index
, states
));
232 EXPECT_EQ(0u, result_index
);
233 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE
, states
[0].satisfied_signals
);
234 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE
| MOJO_HANDLE_SIGNAL_PEER_CLOSED
,
235 states
[0].satisfiable_signals
);
237 // Do a two-phase write to |hp|.
238 EXPECT_EQ(MOJO_RESULT_OK
, MojoBeginWriteData(hp
, &write_pointer
, &buffer_size
,
239 MOJO_WRITE_DATA_FLAG_NONE
));
240 static const char kWorld
[] = "world";
241 ASSERT_GE(buffer_size
, sizeof(kWorld
));
242 // Include the terminating null.
243 memcpy(write_pointer
, kWorld
, sizeof(kWorld
));
244 EXPECT_EQ(MOJO_RESULT_OK
,
245 MojoEndWriteData(hp
, static_cast<uint32_t>(sizeof(kWorld
))));
247 // Read one character from |hc|.
248 memset(buffer
, 0, sizeof(buffer
));
250 EXPECT_EQ(MOJO_RESULT_OK
,
251 MojoReadData(hc
, buffer
, &buffer_size
, MOJO_READ_DATA_FLAG_NONE
));
254 EXPECT_EQ(MOJO_RESULT_OK
, MojoClose(hp
));
256 // |hc| should still be readable.
257 EXPECT_EQ(MOJO_RESULT_OK
,
258 MojoNewWait(hc
, MOJO_HANDLE_SIGNAL_READABLE
, 0, &state
));
260 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE
| MOJO_HANDLE_SIGNAL_PEER_CLOSED
,
261 state
.satisfied_signals
);
262 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE
| MOJO_HANDLE_SIGNAL_PEER_CLOSED
,
263 state
.satisfiable_signals
);
265 // Do a two-phase read from |hc|.
267 EXPECT_EQ(MOJO_RESULT_OK
, MojoBeginReadData(hc
, &read_pointer
, &buffer_size
,
268 MOJO_READ_DATA_FLAG_NONE
));
269 ASSERT_LE(buffer_size
, sizeof(buffer
) - 1);
270 memcpy(&buffer
[1], read_pointer
, buffer_size
);
271 EXPECT_EQ(MOJO_RESULT_OK
, MojoEndReadData(hc
, buffer_size
));
272 EXPECT_STREQ("hello world", buffer
);
274 // |hc| should no longer be readable.
275 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION
,
276 MojoNewWait(hc
, MOJO_HANDLE_SIGNAL_READABLE
, 1000, &state
));
278 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED
, state
.satisfied_signals
);
279 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED
, state
.satisfiable_signals
);
281 EXPECT_EQ(MOJO_RESULT_OK
, MojoClose(hc
));
283 // TODO(vtl): Test the other way around -- closing the consumer should make
284 // the producer never-writable?
287 TEST(CoreTest
, MAYBE_BasicSharedBuffer
) {
291 // Create a shared buffer (|h0|).
292 h0
= MOJO_HANDLE_INVALID
;
293 EXPECT_EQ(MOJO_RESULT_OK
, MojoCreateSharedBuffer(NULL
, 100, &h0
));
294 EXPECT_NE(h0
, MOJO_HANDLE_INVALID
);
298 EXPECT_EQ(MOJO_RESULT_OK
,
299 MojoMapBuffer(h0
, 0, 100, &pointer
, MOJO_MAP_BUFFER_FLAG_NONE
));
300 ASSERT_TRUE(pointer
);
301 static_cast<char*>(pointer
)[50] = 'x';
303 // Duplicate |h0| to |h1|.
304 h1
= MOJO_HANDLE_INVALID
;
305 EXPECT_EQ(MOJO_RESULT_OK
, MojoDuplicateBufferHandle(h0
, NULL
, &h1
));
306 EXPECT_NE(h1
, MOJO_HANDLE_INVALID
);
309 EXPECT_EQ(MOJO_RESULT_OK
, MojoClose(h0
));
311 // The mapping should still be good.
312 static_cast<char*>(pointer
)[51] = 'y';
315 EXPECT_EQ(MOJO_RESULT_OK
, MojoUnmapBuffer(pointer
));
319 EXPECT_EQ(MOJO_RESULT_OK
,
320 MojoMapBuffer(h1
, 50, 50, &pointer
, MOJO_MAP_BUFFER_FLAG_NONE
));
321 ASSERT_TRUE(pointer
);
323 // It should have what we wrote.
324 EXPECT_EQ('x', static_cast<char*>(pointer
)[0]);
325 EXPECT_EQ('y', static_cast<char*>(pointer
)[1]);
328 EXPECT_EQ(MOJO_RESULT_OK
, MojoUnmapBuffer(pointer
));
330 EXPECT_EQ(MOJO_RESULT_OK
, MojoClose(h1
));
333 // Defined in core_unittest_pure_c.c.
334 extern "C" const char* MinimalCTest(void);
336 // This checks that things actually work in C (not C++).
337 TEST(CoreTest
, MinimalCTest
) {
338 const char* failure
= MinimalCTest();
339 EXPECT_TRUE(failure
== NULL
) << failure
;
342 // TODO(vtl): Add multi-threaded tests.