| 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 |