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 TEST(CoreTest, GetTimeTicksNow) { | |
17 const MojoTimeTicks start = MojoGetTimeTicksNow(); | |
18 EXPECT_NE(static_cast<MojoTimeTicks>(0), start) | |
19 << "MojoGetTimeTicksNow should return nonzero value"; | |
20 } | |
21 | |
22 // The only handle that's guaranteed to be invalid is |MOJO_HANDLE_INVALID|. | |
23 // Tests that everything that takes a handle properly recognizes it. | |
24 TEST(CoreTest, InvalidHandle) { | |
25 MojoHandle h0, h1; | |
26 MojoWaitFlags wf; | |
27 char buffer[10] = { 0 }; | |
28 uint32_t buffer_size; | |
29 void* write_pointer; | |
30 const void* read_pointer; | |
31 | |
32 // Close: | |
33 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(MOJO_HANDLE_INVALID)); | |
34 | |
35 // Wait: | |
36 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
37 MojoWait(MOJO_HANDLE_INVALID, MOJO_WAIT_FLAG_EVERYTHING, 1000000)); | |
38 h0 = MOJO_HANDLE_INVALID; | |
39 wf = MOJO_WAIT_FLAG_EVERYTHING; | |
40 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
41 MojoWaitMany(&h0, &wf, 1, MOJO_DEADLINE_INDEFINITE)); | |
42 | |
43 // Message pipe: | |
44 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
45 MojoWriteMessage(h0, buffer, 3, NULL, 0, | |
46 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
47 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
48 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
49 MojoReadMessage(h0, buffer, &buffer_size, NULL, NULL, | |
50 MOJO_READ_MESSAGE_FLAG_NONE)); | |
51 | |
52 // Data pipe: | |
53 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
54 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
55 MojoWriteData(h0, buffer, &buffer_size, MOJO_WRITE_DATA_FLAG_NONE)); | |
56 write_pointer = NULL; | |
57 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
58 MojoBeginWriteData(h0, &write_pointer, &buffer_size, | |
59 MOJO_WRITE_DATA_FLAG_NONE)); | |
60 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoEndWriteData(h0, 1)); | |
61 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
62 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
63 MojoReadData(h0, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE)); | |
64 read_pointer = NULL; | |
65 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
66 MojoBeginReadData(h0, &read_pointer, &buffer_size, | |
67 MOJO_READ_DATA_FLAG_NONE)); | |
68 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoEndReadData(h0, 1)); | |
69 | |
70 // Shared buffer: | |
71 h1 = MOJO_HANDLE_INVALID; | |
72 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
73 MojoDuplicateBufferHandle(h0, NULL, &h1)); | |
74 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
75 MojoMapBuffer(h0, 0, 1, &write_pointer, MOJO_MAP_BUFFER_FLAG_NONE)); | |
76 } | |
77 | |
78 TEST(CoreTest, BasicMessagePipe) { | |
79 MojoHandle h0, h1; | |
80 MojoWaitFlags wf; | |
81 char buffer[10] = { 0 }; | |
82 uint32_t buffer_size; | |
83 | |
84 h0 = MOJO_HANDLE_INVALID; | |
85 h1 = MOJO_HANDLE_INVALID; | |
86 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(&h0, &h1)); | |
87 EXPECT_NE(h0, MOJO_HANDLE_INVALID); | |
88 EXPECT_NE(h1, MOJO_HANDLE_INVALID); | |
89 | |
90 // Shouldn't be readable. | |
91 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
92 MojoWait(h0, MOJO_WAIT_FLAG_READABLE, 0)); | |
93 | |
94 // Should be writable. | |
95 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h0, MOJO_WAIT_FLAG_WRITABLE, 0)); | |
96 | |
97 // Try to read. | |
98 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
99 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
100 MojoReadMessage(h0, buffer, &buffer_size, NULL, NULL, | |
101 MOJO_READ_MESSAGE_FLAG_NONE)); | |
102 | |
103 // Write to |h1|. | |
104 static const char kHello[] = "hello"; | |
105 buffer_size = static_cast<uint32_t>(sizeof(kHello)); | |
106 EXPECT_EQ(MOJO_RESULT_OK, | |
107 MojoWriteMessage(h1, kHello, buffer_size, NULL, 0, | |
108 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
109 | |
110 // |h0| should be readable. | |
111 wf = MOJO_WAIT_FLAG_READABLE; | |
112 EXPECT_EQ(MOJO_RESULT_OK, | |
113 MojoWaitMany(&h0, &wf, 1, MOJO_DEADLINE_INDEFINITE)); | |
114 | |
115 // Read from |h0|. | |
116 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
117 EXPECT_EQ(MOJO_RESULT_OK, | |
118 MojoReadMessage(h0, buffer, &buffer_size, NULL, NULL, | |
119 MOJO_READ_MESSAGE_FLAG_NONE)); | |
120 EXPECT_EQ(static_cast<uint32_t>(sizeof(kHello)), buffer_size); | |
121 EXPECT_STREQ(kHello, buffer); | |
122 | |
123 // |h0| should no longer be readable. | |
124 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
125 MojoWait(h0, MOJO_WAIT_FLAG_READABLE, 10)); | |
126 | |
127 // Close |h0|. | |
128 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0)); | |
129 | |
130 // |h1| should no longer be readable or writable. | |
131 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
132 MojoWait(h1, MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE, | |
133 1000)); | |
134 | |
135 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1)); | |
136 } | |
137 | |
138 TEST(CoreTest, BasicDataPipe) { | |
139 MojoHandle hp, hc; | |
140 MojoWaitFlags wf; | |
141 char buffer[20] = { 0 }; | |
142 uint32_t buffer_size; | |
143 void* write_pointer; | |
144 const void* read_pointer; | |
145 | |
146 hp = MOJO_HANDLE_INVALID; | |
147 hc = MOJO_HANDLE_INVALID; | |
148 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateDataPipe(NULL, &hp, &hc)); | |
149 EXPECT_NE(hp, MOJO_HANDLE_INVALID); | |
150 EXPECT_NE(hc, MOJO_HANDLE_INVALID); | |
151 | |
152 // The consumer |hc| shouldn't be readable. | |
153 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
154 MojoWait(hc, MOJO_WAIT_FLAG_READABLE, 0)); | |
155 | |
156 // The producer |hp| should be writable. | |
157 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(hp, MOJO_WAIT_FLAG_WRITABLE, 0)); | |
158 | |
159 // Try to read from |hc|. | |
160 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
161 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
162 MojoReadData(hc, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE)); | |
163 | |
164 // Try to begin a two-phase read from |hc|. | |
165 read_pointer = NULL; | |
166 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
167 MojoBeginReadData(hc, &read_pointer, &buffer_size, | |
168 MOJO_READ_DATA_FLAG_NONE)); | |
169 | |
170 // Write to |hp|. | |
171 static const char kHello[] = "hello "; | |
172 // Don't include terminating null. | |
173 buffer_size = static_cast<uint32_t>(strlen(kHello)); | |
174 EXPECT_EQ(MOJO_RESULT_OK, | |
175 MojoWriteData(hp, kHello, &buffer_size, | |
176 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
177 | |
178 // |hc| should be(come) readable. | |
179 wf = MOJO_WAIT_FLAG_READABLE; | |
180 EXPECT_EQ(MOJO_RESULT_OK, | |
181 MojoWaitMany(&hc, &wf, 1, MOJO_DEADLINE_INDEFINITE)); | |
182 | |
183 // Do a two-phase write to |hp|. | |
184 EXPECT_EQ(MOJO_RESULT_OK, | |
185 MojoBeginWriteData(hp, &write_pointer, &buffer_size, | |
186 MOJO_WRITE_DATA_FLAG_NONE)); | |
187 static const char kWorld[] = "world"; | |
188 ASSERT_GE(buffer_size, sizeof(kWorld)); | |
189 // Include the terminating null. | |
190 memcpy(write_pointer, kWorld, sizeof(kWorld)); | |
191 EXPECT_EQ(MOJO_RESULT_OK, | |
192 MojoEndWriteData(hp, static_cast<uint32_t>(sizeof(kWorld)))); | |
193 | |
194 // Read one character from |hc|. | |
195 memset(buffer, 0, sizeof(buffer)); | |
196 buffer_size = 1; | |
197 EXPECT_EQ(MOJO_RESULT_OK, | |
198 MojoReadData(hc, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE)); | |
199 | |
200 // Close |hp|. | |
201 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(hp)); | |
202 | |
203 // |hc| should still be readable. | |
204 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(hc, MOJO_WAIT_FLAG_READABLE, 0)); | |
205 | |
206 // Do a two-phase read from |hc|. | |
207 read_pointer = NULL; | |
208 EXPECT_EQ(MOJO_RESULT_OK, | |
209 MojoBeginReadData(hc, &read_pointer, &buffer_size, | |
210 MOJO_READ_DATA_FLAG_NONE)); | |
211 ASSERT_LE(buffer_size, sizeof(buffer) - 1); | |
212 memcpy(&buffer[1], read_pointer, buffer_size); | |
213 EXPECT_EQ(MOJO_RESULT_OK, MojoEndReadData(hc, buffer_size)); | |
214 EXPECT_STREQ("hello world", buffer); | |
215 | |
216 // |hc| should no longer be readable. | |
217 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
218 MojoWait(hc, MOJO_WAIT_FLAG_READABLE, 1000)); | |
219 | |
220 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(hc)); | |
221 | |
222 // TODO(vtl): Test the other way around -- closing the consumer should make | |
223 // the producer never-writable? | |
224 } | |
225 | |
226 TEST(CoreTest, BasicSharedBuffer) { | |
227 MojoHandle h0, h1; | |
228 void* pointer; | |
229 | |
230 // Create a shared buffer (|h0|). | |
231 h0 = MOJO_HANDLE_INVALID; | |
232 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateSharedBuffer(NULL, 100, &h0)); | |
233 EXPECT_NE(h0, MOJO_HANDLE_INVALID); | |
234 | |
235 // Map everything. | |
236 pointer = NULL; | |
237 EXPECT_EQ(MOJO_RESULT_OK, | |
238 MojoMapBuffer(h0, 0, 100, &pointer, MOJO_MAP_BUFFER_FLAG_NONE)); | |
239 ASSERT_TRUE(pointer); | |
240 static_cast<char*>(pointer)[50] = 'x'; | |
241 | |
242 // Duplicate |h0| to |h1|. | |
243 h1 = MOJO_HANDLE_INVALID; | |
244 EXPECT_EQ(MOJO_RESULT_OK, MojoDuplicateBufferHandle(h0, NULL, &h1)); | |
245 EXPECT_NE(h1, MOJO_HANDLE_INVALID); | |
246 | |
247 // Close |h0|. | |
248 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0)); | |
249 | |
250 // The mapping should still be good. | |
251 static_cast<char*>(pointer)[51] = 'y'; | |
252 | |
253 // Unmap it. | |
254 // TODO(vtl): Not yet implemented. | |
255 EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, MojoUnmapBuffer(pointer)); | |
256 | |
257 // Map half of |h1|. | |
258 pointer = NULL; | |
259 EXPECT_EQ(MOJO_RESULT_OK, | |
260 MojoMapBuffer(h1, 50, 50, &pointer, MOJO_MAP_BUFFER_FLAG_NONE)); | |
261 ASSERT_TRUE(pointer); | |
262 | |
263 // It should have what we wrote. | |
264 EXPECT_EQ('x', static_cast<char*>(pointer)[0]); | |
265 EXPECT_EQ('y', static_cast<char*>(pointer)[1]); | |
266 | |
267 // Unmap it. | |
268 // TODO(vtl): Not yet implemented. | |
269 EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, MojoUnmapBuffer(pointer)); | |
270 | |
271 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1)); | |
272 } | |
273 | |
274 // Defined in core_unittest_pure_c.c. | |
275 extern "C" const char* MinimalCTest(void); | |
276 | |
277 // This checks that things actually work in C (not C++). | |
278 TEST(CoreTest, MinimalCTest) { | |
279 const char* failure = MinimalCTest(); | |
280 EXPECT_TRUE(failure == NULL) << failure; | |
281 } | |
282 | |
283 // TODO(vtl): Add multi-threaded tests. | |
284 | |
285 } // namespace | |
286 } // namespace mojo | |
OLD | NEW |