1 // Copyright 2016 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 #include "mojo/core/test/mojo_test_base.h" 6 7 #include "base/memory/ptr_util.h" 8 #include "base/memory/ref_counted.h" 9 #include "base/run_loop.h" 10 #include "base/synchronization/waitable_event.h" 11 #include "build/build_config.h" 12 #include "mojo/core/embedder/embedder.h" 13 #include "mojo/public/c/system/buffer.h" 14 #include "mojo/public/c/system/data_pipe.h" 15 #include "mojo/public/c/system/functions.h" 16 #include "mojo/public/c/system/trap.h" 17 #include "mojo/public/cpp/system/handle.h" 18 #include "mojo/public/cpp/system/message_pipe.h" 19 #include "mojo/public/cpp/system/wait.h" 20 #include "testing/gtest/include/gtest/gtest.h" 21 22 #if defined(OS_MACOSX) && !defined(OS_IOS) 23 #include "base/mac/mach_port_broker.h" 24 #endif 25 26 namespace mojo { 27 namespace core { 28 namespace test { 29 30 #if defined(OS_MACOSX) && !defined(OS_IOS) 31 namespace { 32 base::MachPortBroker* g_mach_broker = nullptr; 33 } 34 #endif 35 36 MojoTestBase::MojoTestBase() { 37 #if defined(OS_MACOSX) && !defined(OS_IOS) 38 if (!g_mach_broker) { 39 g_mach_broker = new base::MachPortBroker("mojo_test"); 40 CHECK(g_mach_broker->Init()); 41 SetMachPortProvider(g_mach_broker); 42 } 43 #endif 44 } 45 46 MojoTestBase::~MojoTestBase() {} 47 48 MojoTestBase::ClientController& MojoTestBase::StartClient( 49 const std::string& client_name) { 50 clients_.push_back( 51 std::make_unique<ClientController>(client_name, this, launch_type_)); 52 return *clients_.back(); 53 } 54 55 MojoTestBase::ClientController::ClientController(const std::string& client_name, 56 MojoTestBase* test, 57 LaunchType launch_type) { 58 #if !defined(OS_IOS) 59 #if defined(OS_MACOSX) 60 // This lock needs to be held while launching the child because the Mach port 61 // broker only allows task ports to be received from known child processes. 62 // However, it can only know the child process's pid after the child has 63 // launched. To prevent a race where the child process sends its task port 64 // before the pid has been registered, the lock needs to be held over both 65 // launch and child pid registration. 66 base::AutoLock lock(g_mach_broker->GetLock()); 67 #endif 68 pipe_ = helper_.StartChild(client_name, launch_type); 69 #if defined(OS_MACOSX) 70 g_mach_broker->AddPlaceholderForPid(helper_.test_child().Handle()); 71 #endif 72 #endif 73 } 74 75 MojoTestBase::ClientController::~ClientController() { 76 CHECK(was_shutdown_) 77 << "Test clients should be waited on explicitly with WaitForShutdown()."; 78 } 79 80 int MojoTestBase::ClientController::WaitForShutdown() { 81 was_shutdown_ = true; 82 #if !defined(OS_IOS) 83 int retval = helper_.WaitForChildShutdown(); 84 #if defined(OS_MACOSX) 85 base::AutoLock lock(g_mach_broker->GetLock()); 86 g_mach_broker->InvalidatePid(helper_.test_child().Handle()); 87 #endif 88 return retval; 89 #else 90 NOTREACHED(); 91 return 1; 92 #endif 93 } 94 95 // static 96 void MojoTestBase::CloseHandle(MojoHandle h) { 97 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h)); 98 } 99 100 // static 101 void MojoTestBase::CreateMessagePipe(MojoHandle* p0, MojoHandle* p1) { 102 MojoCreateMessagePipe(nullptr, p0, p1); 103 CHECK_NE(*p0, MOJO_HANDLE_INVALID); 104 CHECK_NE(*p1, MOJO_HANDLE_INVALID); 105 } 106 107 // static 108 void MojoTestBase::WriteMessageWithHandles(MojoHandle mp, 109 const std::string& message, 110 const MojoHandle* handles, 111 uint32_t num_handles) { 112 CHECK_EQ(WriteMessageRaw(MessagePipeHandle(mp), message.data(), 113 static_cast<uint32_t>(message.size()), handles, 114 num_handles, MOJO_WRITE_MESSAGE_FLAG_NONE), 115 MOJO_RESULT_OK); 116 } 117 118 // static 119 void MojoTestBase::WriteMessage(MojoHandle mp, const std::string& message) { 120 WriteMessageWithHandles(mp, message, nullptr, 0); 121 } 122 123 // static 124 std::string MojoTestBase::ReadMessageWithHandles( 125 MojoHandle mp, 126 MojoHandle* out_handles, 127 uint32_t expected_num_handles) { 128 CHECK_EQ(WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE), MOJO_RESULT_OK); 129 130 std::vector<uint8_t> bytes; 131 std::vector<ScopedHandle> handles; 132 CHECK_EQ(MOJO_RESULT_OK, 133 ReadMessageRaw(MessagePipeHandle(mp), &bytes, &handles, 134 MOJO_READ_MESSAGE_FLAG_NONE)); 135 CHECK_EQ(expected_num_handles, handles.size()); 136 for (size_t i = 0; i < handles.size(); ++i) 137 out_handles[i] = handles[i].release().value(); 138 139 return std::string(bytes.begin(), bytes.end()); 140 } 141 142 // static 143 std::string MojoTestBase::ReadMessageWithOptionalHandle(MojoHandle mp, 144 MojoHandle* handle) { 145 CHECK_EQ(WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE), MOJO_RESULT_OK); 146 147 std::vector<uint8_t> bytes; 148 std::vector<ScopedHandle> handles; 149 CHECK_EQ(MOJO_RESULT_OK, 150 ReadMessageRaw(MessagePipeHandle(mp), &bytes, &handles, 151 MOJO_READ_MESSAGE_FLAG_NONE)); 152 CHECK(handles.size() == 0 || handles.size() == 1); 153 CHECK(handle); 154 155 if (handles.size() == 1) 156 *handle = handles[0].release().value(); 157 else 158 *handle = MOJO_HANDLE_INVALID; 159 160 return std::string(bytes.begin(), bytes.end()); 161 } 162 163 // static 164 std::string MojoTestBase::ReadMessage(MojoHandle mp) { 165 return ReadMessageWithHandles(mp, nullptr, 0); 166 } 167 168 // static 169 void MojoTestBase::ReadMessage(MojoHandle mp, char* data, size_t num_bytes) { 170 CHECK_EQ(WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE), MOJO_RESULT_OK); 171 172 std::vector<uint8_t> bytes; 173 std::vector<ScopedHandle> handles; 174 CHECK_EQ(MOJO_RESULT_OK, 175 ReadMessageRaw(MessagePipeHandle(mp), &bytes, &handles, 176 MOJO_READ_MESSAGE_FLAG_NONE)); 177 CHECK_EQ(0u, handles.size()); 178 CHECK_EQ(num_bytes, bytes.size()); 179 memcpy(data, bytes.data(), bytes.size()); 180 } 181 182 // static 183 void MojoTestBase::VerifyTransmission(MojoHandle source, 184 MojoHandle dest, 185 const std::string& message) { 186 WriteMessage(source, message); 187 188 // We don't use EXPECT_EQ; failures on really long messages make life hard. 189 EXPECT_TRUE(message == ReadMessage(dest)); 190 } 191 192 // static 193 void MojoTestBase::VerifyEcho(MojoHandle mp, const std::string& message) { 194 VerifyTransmission(mp, mp, message); 195 } 196 197 // static 198 MojoHandle MojoTestBase::CreateBuffer(uint64_t size) { 199 MojoHandle h; 200 EXPECT_EQ(MojoCreateSharedBuffer(size, nullptr, &h), MOJO_RESULT_OK); 201 return h; 202 } 203 204 // static 205 MojoHandle MojoTestBase::DuplicateBuffer(MojoHandle h, bool read_only) { 206 MojoHandle new_handle; 207 MojoDuplicateBufferHandleOptions options = { 208 sizeof(MojoDuplicateBufferHandleOptions), 209 MOJO_DUPLICATE_BUFFER_HANDLE_FLAG_NONE}; 210 if (read_only) 211 options.flags |= MOJO_DUPLICATE_BUFFER_HANDLE_FLAG_READ_ONLY; 212 EXPECT_EQ(MOJO_RESULT_OK, 213 MojoDuplicateBufferHandle(h, &options, &new_handle)); 214 return new_handle; 215 } 216 217 // static 218 void MojoTestBase::WriteToBuffer(MojoHandle h, 219 size_t offset, 220 const base::StringPiece& s) { 221 char* data; 222 EXPECT_EQ(MOJO_RESULT_OK, MojoMapBuffer(h, offset, s.size(), nullptr, 223 reinterpret_cast<void**>(&data))); 224 memcpy(data, s.data(), s.size()); 225 EXPECT_EQ(MOJO_RESULT_OK, MojoUnmapBuffer(static_cast<void*>(data))); 226 } 227 228 // static 229 void MojoTestBase::ExpectBufferContents(MojoHandle h, 230 size_t offset, 231 const base::StringPiece& s) { 232 char* data; 233 EXPECT_EQ(MOJO_RESULT_OK, MojoMapBuffer(h, offset, s.size(), nullptr, 234 reinterpret_cast<void**>(&data))); 235 EXPECT_EQ(s, base::StringPiece(data, s.size())); 236 EXPECT_EQ(MOJO_RESULT_OK, MojoUnmapBuffer(static_cast<void*>(data))); 237 } 238 239 // static 240 void MojoTestBase::CreateDataPipe(MojoHandle* p0, 241 MojoHandle* p1, 242 size_t capacity) { 243 MojoCreateDataPipeOptions options; 244 options.struct_size = static_cast<uint32_t>(sizeof(options)); 245 options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE; 246 options.element_num_bytes = 1; 247 options.capacity_num_bytes = static_cast<uint32_t>(capacity); 248 249 MojoCreateDataPipe(&options, p0, p1); 250 CHECK_NE(*p0, MOJO_HANDLE_INVALID); 251 CHECK_NE(*p1, MOJO_HANDLE_INVALID); 252 } 253 254 // static 255 void MojoTestBase::WriteData(MojoHandle producer, const std::string& data) { 256 CHECK_EQ(WaitForSignals(producer, MOJO_HANDLE_SIGNAL_WRITABLE), 257 MOJO_RESULT_OK); 258 uint32_t num_bytes = static_cast<uint32_t>(data.size()); 259 MojoWriteDataOptions options; 260 options.struct_size = sizeof(options); 261 options.flags = MOJO_WRITE_DATA_FLAG_ALL_OR_NONE; 262 CHECK_EQ(MojoWriteData(producer, data.data(), &num_bytes, &options), 263 MOJO_RESULT_OK); 264 CHECK_EQ(num_bytes, static_cast<uint32_t>(data.size())); 265 } 266 267 // static 268 std::string MojoTestBase::ReadData(MojoHandle consumer, size_t size) { 269 CHECK_EQ(WaitForSignals(consumer, MOJO_HANDLE_SIGNAL_READABLE), 270 MOJO_RESULT_OK); 271 std::vector<char> buffer(size); 272 uint32_t num_bytes = static_cast<uint32_t>(size); 273 MojoReadDataOptions options; 274 options.struct_size = sizeof(options); 275 options.flags = MOJO_READ_DATA_FLAG_ALL_OR_NONE; 276 CHECK_EQ(MojoReadData(consumer, &options, buffer.data(), &num_bytes), 277 MOJO_RESULT_OK); 278 CHECK_EQ(num_bytes, static_cast<uint32_t>(size)); 279 280 return std::string(buffer.begin(), buffer.end()); 281 } 282 283 // static 284 MojoHandleSignalsState MojoTestBase::GetSignalsState(MojoHandle handle) { 285 MojoHandleSignalsState signals_state; 286 CHECK_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(handle, &signals_state)); 287 return signals_state; 288 } 289 290 // static 291 MojoResult MojoTestBase::WaitForSignals(MojoHandle handle, 292 MojoHandleSignals signals, 293 MojoTriggerCondition condition, 294 MojoHandleSignalsState* state) { 295 return Wait(Handle(handle), signals, condition, state); 296 } 297 298 // static 299 MojoResult MojoTestBase::WaitForSignals(MojoHandle handle, 300 MojoHandleSignals signals, 301 MojoHandleSignalsState* state) { 302 return Wait(Handle(handle), signals, MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED, 303 state); 304 } 305 306 } // namespace test 307 } // namespace core 308 } // namespace mojo 309