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