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