OLD | NEW |
| (Empty) |
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. | |
4 | |
5 // This file tests the C API. | |
6 | |
7 #include "mojo/public/c/system/core.h" | |
8 | |
9 #include <string.h> | |
10 | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 | |
13 namespace mojo { | |
14 namespace { | |
15 | |
16 const MojoHandleSignals kSignalReadadableWritable = | |
17 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE; | |
18 | |
19 const MojoHandleSignals kSignalAll = MOJO_HANDLE_SIGNAL_READABLE | | |
20 MOJO_HANDLE_SIGNAL_WRITABLE | | |
21 MOJO_HANDLE_SIGNAL_PEER_CLOSED; | |
22 | |
23 TEST(CoreTest, GetTimeTicksNow) { | |
24 const MojoTimeTicks start = MojoGetTimeTicksNow(); | |
25 EXPECT_NE(static_cast<MojoTimeTicks>(0), start) | |
26 << "MojoGetTimeTicksNow should return nonzero value"; | |
27 } | |
28 | |
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) { | |
32 MojoHandle h0, h1; | |
33 MojoHandleSignals sig; | |
34 char buffer[10] = {0}; | |
35 uint32_t buffer_size; | |
36 void* write_pointer; | |
37 const void* read_pointer; | |
38 | |
39 // Close: | |
40 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(MOJO_HANDLE_INVALID)); | |
41 | |
42 // Wait: | |
43 EXPECT_EQ( | |
44 MOJO_RESULT_INVALID_ARGUMENT, | |
45 MojoWait(MOJO_HANDLE_INVALID, ~MOJO_HANDLE_SIGNAL_NONE, 1000000, NULL)); | |
46 | |
47 h0 = MOJO_HANDLE_INVALID; | |
48 sig = ~MOJO_HANDLE_SIGNAL_NONE; | |
49 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
50 MojoWaitMany(&h0, &sig, 1, MOJO_DEADLINE_INDEFINITE, NULL, NULL)); | |
51 | |
52 // Message pipe: | |
53 EXPECT_EQ( | |
54 MOJO_RESULT_INVALID_ARGUMENT, | |
55 MojoWriteMessage(h0, buffer, 3, NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
56 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
57 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
58 MojoReadMessage(h0, buffer, &buffer_size, NULL, NULL, | |
59 MOJO_READ_MESSAGE_FLAG_NONE)); | |
60 | |
61 // Data pipe: | |
62 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
63 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
64 MojoWriteData(h0, buffer, &buffer_size, MOJO_WRITE_DATA_FLAG_NONE)); | |
65 write_pointer = NULL; | |
66 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
67 MojoBeginWriteData(h0, &write_pointer, &buffer_size, | |
68 MOJO_WRITE_DATA_FLAG_NONE)); | |
69 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoEndWriteData(h0, 1)); | |
70 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
71 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
72 MojoReadData(h0, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE)); | |
73 read_pointer = NULL; | |
74 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
75 MojoBeginReadData(h0, &read_pointer, &buffer_size, | |
76 MOJO_READ_DATA_FLAG_NONE)); | |
77 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoEndReadData(h0, 1)); | |
78 | |
79 // Shared buffer: | |
80 h1 = MOJO_HANDLE_INVALID; | |
81 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
82 MojoDuplicateBufferHandle(h0, NULL, &h1)); | |
83 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
84 MojoMapBuffer(h0, 0, 1, &write_pointer, MOJO_MAP_BUFFER_FLAG_NONE)); | |
85 } | |
86 | |
87 TEST(CoreTest, BasicMessagePipe) { | |
88 MojoHandle h0, h1; | |
89 MojoHandleSignals sig; | |
90 char buffer[10] = {0}; | |
91 uint32_t buffer_size; | |
92 | |
93 h0 = MOJO_HANDLE_INVALID; | |
94 h1 = MOJO_HANDLE_INVALID; | |
95 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(NULL, &h0, &h1)); | |
96 EXPECT_NE(h0, MOJO_HANDLE_INVALID); | |
97 EXPECT_NE(h1, MOJO_HANDLE_INVALID); | |
98 | |
99 // Shouldn't be readable, we haven't written anything. | |
100 MojoHandleSignalsState state; | |
101 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
102 MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE, 0, &state)); | |
103 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals); | |
104 EXPECT_EQ(kSignalAll, state.satisfiable_signals); | |
105 | |
106 // Should be writable. | |
107 EXPECT_EQ(MOJO_RESULT_OK, | |
108 MojoWait(h0, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &state)); | |
109 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals); | |
110 EXPECT_EQ(kSignalAll, state.satisfiable_signals); | |
111 | |
112 // Try to read. | |
113 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
114 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
115 MojoReadMessage(h0, buffer, &buffer_size, NULL, NULL, | |
116 MOJO_READ_MESSAGE_FLAG_NONE)); | |
117 | |
118 // Write to |h1|. | |
119 static const char kHello[] = "hello"; | |
120 buffer_size = static_cast<uint32_t>(sizeof(kHello)); | |
121 EXPECT_EQ(MOJO_RESULT_OK, MojoWriteMessage(h1, kHello, buffer_size, NULL, 0, | |
122 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
123 | |
124 // |h0| should be readable. | |
125 uint32_t result_index = 1; | |
126 MojoHandleSignalsState states[1]; | |
127 sig = MOJO_HANDLE_SIGNAL_READABLE; | |
128 EXPECT_EQ(MOJO_RESULT_OK, MojoWaitMany(&h0, &sig, 1, MOJO_DEADLINE_INDEFINITE, | |
129 &result_index, states)); | |
130 | |
131 EXPECT_EQ(0u, result_index); | |
132 EXPECT_EQ(kSignalReadadableWritable, states[0].satisfied_signals); | |
133 EXPECT_EQ(kSignalAll, states[0].satisfiable_signals); | |
134 | |
135 // Read from |h0|. | |
136 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
137 EXPECT_EQ(MOJO_RESULT_OK, MojoReadMessage(h0, buffer, &buffer_size, NULL, | |
138 NULL, MOJO_READ_MESSAGE_FLAG_NONE)); | |
139 EXPECT_EQ(static_cast<uint32_t>(sizeof(kHello)), buffer_size); | |
140 EXPECT_STREQ(kHello, buffer); | |
141 | |
142 // |h0| should no longer be readable. | |
143 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
144 MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE, 10, &state)); | |
145 | |
146 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals); | |
147 EXPECT_EQ(kSignalAll, state.satisfiable_signals); | |
148 | |
149 // Close |h0|. | |
150 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0)); | |
151 | |
152 // |h1| should no longer be readable or writable. | |
153 EXPECT_EQ( | |
154 MOJO_RESULT_FAILED_PRECONDITION, | |
155 MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
156 1000, &state)); | |
157 | |
158 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals); | |
159 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals); | |
160 | |
161 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1)); | |
162 } | |
163 | |
164 // TODO(ncbray): enable these tests once NaCl supports the corresponding APIs. | |
165 #ifdef __native_client__ | |
166 #define MAYBE_BasicDataPipe DISABLED_BasicDataPipe | |
167 #define MAYBE_BasicSharedBuffer DISABLED_BasicSharedBuffer | |
168 #else | |
169 #define MAYBE_BasicDataPipe BasicDataPipe | |
170 #define MAYBE_BasicSharedBuffer BasicSharedBuffer | |
171 #endif | |
172 | |
173 TEST(CoreTest, MAYBE_BasicDataPipe) { | |
174 MojoHandle hp, hc; | |
175 MojoHandleSignals sig; | |
176 char buffer[20] = {0}; | |
177 uint32_t buffer_size; | |
178 void* write_pointer; | |
179 const void* read_pointer; | |
180 | |
181 hp = MOJO_HANDLE_INVALID; | |
182 hc = MOJO_HANDLE_INVALID; | |
183 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateDataPipe(NULL, &hp, &hc)); | |
184 EXPECT_NE(hp, MOJO_HANDLE_INVALID); | |
185 EXPECT_NE(hc, MOJO_HANDLE_INVALID); | |
186 | |
187 // The consumer |hc| shouldn't be readable. | |
188 MojoHandleSignalsState state; | |
189 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
190 MojoWait(hc, MOJO_HANDLE_SIGNAL_READABLE, 0, &state)); | |
191 | |
192 EXPECT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfied_signals); | |
193 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
194 state.satisfiable_signals); | |
195 | |
196 // The producer |hp| should be writable. | |
197 EXPECT_EQ(MOJO_RESULT_OK, | |
198 MojoWait(hp, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &state)); | |
199 | |
200 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals); | |
201 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
202 state.satisfiable_signals); | |
203 | |
204 // Try to read from |hc|. | |
205 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
206 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
207 MojoReadData(hc, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE)); | |
208 | |
209 // Try to begin a two-phase read from |hc|. | |
210 read_pointer = NULL; | |
211 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
212 MojoBeginReadData(hc, &read_pointer, &buffer_size, | |
213 MOJO_READ_DATA_FLAG_NONE)); | |
214 | |
215 // Write to |hp|. | |
216 static const char kHello[] = "hello "; | |
217 // Don't include terminating null. | |
218 buffer_size = static_cast<uint32_t>(strlen(kHello)); | |
219 EXPECT_EQ(MOJO_RESULT_OK, MojoWriteData(hp, kHello, &buffer_size, | |
220 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
221 | |
222 // |hc| should be(come) readable. | |
223 uint32_t result_index = 1; | |
224 MojoHandleSignalsState states[1]; | |
225 sig = MOJO_HANDLE_SIGNAL_READABLE; | |
226 EXPECT_EQ(MOJO_RESULT_OK, MojoWaitMany(&hc, &sig, 1, MOJO_DEADLINE_INDEFINITE, | |
227 &result_index, states)); | |
228 | |
229 EXPECT_EQ(0u, result_index); | |
230 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, states[0].satisfied_signals); | |
231 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
232 states[0].satisfiable_signals); | |
233 | |
234 // Do a two-phase write to |hp|. | |
235 EXPECT_EQ(MOJO_RESULT_OK, MojoBeginWriteData(hp, &write_pointer, &buffer_size, | |
236 MOJO_WRITE_DATA_FLAG_NONE)); | |
237 static const char kWorld[] = "world"; | |
238 ASSERT_GE(buffer_size, sizeof(kWorld)); | |
239 // Include the terminating null. | |
240 memcpy(write_pointer, kWorld, sizeof(kWorld)); | |
241 EXPECT_EQ(MOJO_RESULT_OK, | |
242 MojoEndWriteData(hp, static_cast<uint32_t>(sizeof(kWorld)))); | |
243 | |
244 // Read one character from |hc|. | |
245 memset(buffer, 0, sizeof(buffer)); | |
246 buffer_size = 1; | |
247 EXPECT_EQ(MOJO_RESULT_OK, | |
248 MojoReadData(hc, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE)); | |
249 | |
250 // Close |hp|. | |
251 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(hp)); | |
252 | |
253 // |hc| should still be readable. | |
254 EXPECT_EQ(MOJO_RESULT_OK, | |
255 MojoWait(hc, MOJO_HANDLE_SIGNAL_READABLE, 0, &state)); | |
256 | |
257 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
258 state.satisfied_signals); | |
259 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
260 state.satisfiable_signals); | |
261 | |
262 // Do a two-phase read from |hc|. | |
263 read_pointer = NULL; | |
264 EXPECT_EQ(MOJO_RESULT_OK, MojoBeginReadData(hc, &read_pointer, &buffer_size, | |
265 MOJO_READ_DATA_FLAG_NONE)); | |
266 ASSERT_LE(buffer_size, sizeof(buffer) - 1); | |
267 memcpy(&buffer[1], read_pointer, buffer_size); | |
268 EXPECT_EQ(MOJO_RESULT_OK, MojoEndReadData(hc, buffer_size)); | |
269 EXPECT_STREQ("hello world", buffer); | |
270 | |
271 // |hc| should no longer be readable. | |
272 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
273 MojoWait(hc, MOJO_HANDLE_SIGNAL_READABLE, 1000, &state)); | |
274 | |
275 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals); | |
276 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals); | |
277 | |
278 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(hc)); | |
279 | |
280 // TODO(vtl): Test the other way around -- closing the consumer should make | |
281 // the producer never-writable? | |
282 } | |
283 | |
284 TEST(CoreTest, MAYBE_BasicSharedBuffer) { | |
285 MojoHandle h0, h1; | |
286 void* pointer; | |
287 | |
288 // Create a shared buffer (|h0|). | |
289 h0 = MOJO_HANDLE_INVALID; | |
290 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateSharedBuffer(NULL, 100, &h0)); | |
291 EXPECT_NE(h0, MOJO_HANDLE_INVALID); | |
292 | |
293 // Map everything. | |
294 pointer = NULL; | |
295 EXPECT_EQ(MOJO_RESULT_OK, | |
296 MojoMapBuffer(h0, 0, 100, &pointer, MOJO_MAP_BUFFER_FLAG_NONE)); | |
297 ASSERT_TRUE(pointer); | |
298 static_cast<char*>(pointer)[50] = 'x'; | |
299 | |
300 // Duplicate |h0| to |h1|. | |
301 h1 = MOJO_HANDLE_INVALID; | |
302 EXPECT_EQ(MOJO_RESULT_OK, MojoDuplicateBufferHandle(h0, NULL, &h1)); | |
303 EXPECT_NE(h1, MOJO_HANDLE_INVALID); | |
304 | |
305 // Close |h0|. | |
306 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0)); | |
307 | |
308 // The mapping should still be good. | |
309 static_cast<char*>(pointer)[51] = 'y'; | |
310 | |
311 // Unmap it. | |
312 EXPECT_EQ(MOJO_RESULT_OK, MojoUnmapBuffer(pointer)); | |
313 | |
314 // Map half of |h1|. | |
315 pointer = NULL; | |
316 EXPECT_EQ(MOJO_RESULT_OK, | |
317 MojoMapBuffer(h1, 50, 50, &pointer, MOJO_MAP_BUFFER_FLAG_NONE)); | |
318 ASSERT_TRUE(pointer); | |
319 | |
320 // It should have what we wrote. | |
321 EXPECT_EQ('x', static_cast<char*>(pointer)[0]); | |
322 EXPECT_EQ('y', static_cast<char*>(pointer)[1]); | |
323 | |
324 // Unmap it. | |
325 EXPECT_EQ(MOJO_RESULT_OK, MojoUnmapBuffer(pointer)); | |
326 | |
327 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1)); | |
328 } | |
329 | |
330 // Defined in core_unittest_pure_c.c. | |
331 extern "C" const char* MinimalCTest(void); | |
332 | |
333 // This checks that things actually work in C (not C++). | |
334 TEST(CoreTest, MinimalCTest) { | |
335 const char* failure = MinimalCTest(); | |
336 EXPECT_TRUE(failure == NULL) << failure; | |
337 } | |
338 | |
339 // TODO(vtl): Add multi-threaded tests. | |
340 | |
341 } // namespace | |
342 } // namespace mojo | |
OLD | NEW |