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