Home | History | Annotate | Download | only in test
      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