1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file.
4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This file tests the C API.
6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/c/system/core.h"
8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <string.h>
10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace mojo {
14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace {
15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
16effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST(CoreTest, GetTimeTicksNow) {
17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const MojoTimeTicks start = MojoGetTimeTicksNow();
18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_NE(static_cast<MojoTimeTicks>(0), start)
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      << "MojoGetTimeTicksNow should return nonzero value";
20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// The only handle that's guaranteed to be invalid is |MOJO_HANDLE_INVALID|.
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Tests that everything that takes a handle properly recognizes it.
24effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST(CoreTest, InvalidHandle) {
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MojoHandle h0, h1;
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  MojoHandleSignals sig;
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  char buffer[10] = {0};
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  uint32_t buffer_size;
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void* write_pointer;
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const void* read_pointer;
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Close:
33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(MOJO_HANDLE_INVALID));
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Wait:
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            MojoWait(MOJO_HANDLE_INVALID, ~MOJO_HANDLE_SIGNAL_NONE, 1000000));
38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  h0 = MOJO_HANDLE_INVALID;
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sig = ~MOJO_HANDLE_SIGNAL_NONE;
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            MojoWaitMany(&h0, &sig, 1, MOJO_DEADLINE_INDEFINITE));
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Message pipe:
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MOJO_RESULT_INVALID_ARGUMENT,
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MojoWriteMessage(h0, buffer, 3, NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  buffer_size = static_cast<uint32_t>(sizeof(buffer));
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MOJO_RESULT_INVALID_ARGUMENT,
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MojoReadMessage(
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          h0, buffer, &buffer_size, NULL, NULL, MOJO_READ_MESSAGE_FLAG_NONE));
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Data pipe:
54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  buffer_size = static_cast<uint32_t>(sizeof(buffer));
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            MojoWriteData(h0, buffer, &buffer_size, MOJO_WRITE_DATA_FLAG_NONE));
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  write_pointer = NULL;
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            MojoBeginWriteData(
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                h0, &write_pointer, &buffer_size, MOJO_WRITE_DATA_FLAG_NONE));
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoEndWriteData(h0, 1));
62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  buffer_size = static_cast<uint32_t>(sizeof(buffer));
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            MojoReadData(h0, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE));
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  read_pointer = NULL;
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            MojoBeginReadData(
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                h0, &read_pointer, &buffer_size, MOJO_READ_DATA_FLAG_NONE));
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoEndReadData(h0, 1));
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Shared buffer:
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  h1 = MOJO_HANDLE_INVALID;
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            MojoDuplicateBufferHandle(h0, NULL, &h1));
75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            MojoMapBuffer(h0, 0, 1, &write_pointer, MOJO_MAP_BUFFER_FLAG_NONE));
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
79effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST(CoreTest, BasicMessagePipe) {
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MojoHandle h0, h1;
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  MojoHandleSignals sig;
826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  char buffer[10] = {0};
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  uint32_t buffer_size;
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  h0 = MOJO_HANDLE_INVALID;
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  h1 = MOJO_HANDLE_INVALID;
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(NULL, &h0, &h1));
88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_NE(h0, MOJO_HANDLE_INVALID);
89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_NE(h1, MOJO_HANDLE_INVALID);
90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Shouldn't be readable.
92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE, 0));
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Should be writable.
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h0, MOJO_HANDLE_SIGNAL_WRITABLE, 0));
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Try to read.
99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  buffer_size = static_cast<uint32_t>(sizeof(buffer));
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MOJO_RESULT_SHOULD_WAIT,
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MojoReadMessage(
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          h0, buffer, &buffer_size, NULL, NULL, MOJO_READ_MESSAGE_FLAG_NONE));
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Write to |h1|.
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static const char kHello[] = "hello";
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  buffer_size = static_cast<uint32_t>(sizeof(kHello));
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(
1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MOJO_RESULT_OK,
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MojoWriteMessage(
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          h1, kHello, buffer_size, NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // |h0| should be readable.
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sig = MOJO_HANDLE_SIGNAL_READABLE;
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK,
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            MojoWaitMany(&h0, &sig, 1, MOJO_DEADLINE_INDEFINITE));
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Read from |h0|.
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  buffer_size = static_cast<uint32_t>(sizeof(buffer));
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MOJO_RESULT_OK,
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MojoReadMessage(
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          h0, buffer, &buffer_size, NULL, NULL, MOJO_READ_MESSAGE_FLAG_NONE));
124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(static_cast<uint32_t>(sizeof(kHello)), buffer_size);
125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_STREQ(kHello, buffer);
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // |h0| should no longer be readable.
128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE, 10));
130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Close |h0|.
132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0));
133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // |h1| should no longer be readable or writable.
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MOJO_RESULT_FAILED_PRECONDITION,
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MojoWait(
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          h1, MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 1000));
139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1));
141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// TODO(ncbray): enable these tests once NaCl supports the corresponding APIs.
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#ifdef __native_client__
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define MAYBE_BasicDataPipe DISABLED_BasicDataPipe
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define MAYBE_BasicSharedBuffer DISABLED_BasicSharedBuffer
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define MAYBE_BasicDataPipe BasicDataPipe
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define MAYBE_BasicSharedBuffer BasicSharedBuffer
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(CoreTest, MAYBE_BasicDataPipe) {
153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MojoHandle hp, hc;
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  MojoHandleSignals sig;
1556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  char buffer[20] = {0};
156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  uint32_t buffer_size;
157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void* write_pointer;
158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const void* read_pointer;
159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  hp = MOJO_HANDLE_INVALID;
161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  hc = MOJO_HANDLE_INVALID;
162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK, MojoCreateDataPipe(NULL, &hp, &hc));
163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_NE(hp, MOJO_HANDLE_INVALID);
164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_NE(hc, MOJO_HANDLE_INVALID);
165effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
166effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // The consumer |hc| shouldn't be readable.
167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            MojoWait(hc, MOJO_HANDLE_SIGNAL_READABLE, 0));
169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // The producer |hp| should be writable.
171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK, MojoWait(hp, MOJO_HANDLE_SIGNAL_WRITABLE, 0));
172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Try to read from |hc|.
174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  buffer_size = static_cast<uint32_t>(sizeof(buffer));
175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            MojoReadData(hc, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE));
177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
178effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Try to begin a two-phase read from |hc|.
179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  read_pointer = NULL;
180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
1816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            MojoBeginReadData(
1826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                hc, &read_pointer, &buffer_size, MOJO_READ_DATA_FLAG_NONE));
183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Write to |hp|.
185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static const char kHello[] = "hello ";
186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Don't include terminating null.
187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  buffer_size = static_cast<uint32_t>(strlen(kHello));
1886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(
1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MOJO_RESULT_OK,
1906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MojoWriteData(hp, kHello, &buffer_size, MOJO_WRITE_MESSAGE_FLAG_NONE));
191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // |hc| should be(come) readable.
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sig = MOJO_HANDLE_SIGNAL_READABLE;
194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK,
195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            MojoWaitMany(&hc, &sig, 1, MOJO_DEADLINE_INDEFINITE));
196effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
197effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Do a two-phase write to |hp|.
198effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK,
1996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            MojoBeginWriteData(
2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                hp, &write_pointer, &buffer_size, MOJO_WRITE_DATA_FLAG_NONE));
201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static const char kWorld[] = "world";
202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_GE(buffer_size, sizeof(kWorld));
203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Include the terminating null.
204effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  memcpy(write_pointer, kWorld, sizeof(kWorld));
205effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK,
206effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            MojoEndWriteData(hp, static_cast<uint32_t>(sizeof(kWorld))));
207effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
208effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Read one character from |hc|.
209effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  memset(buffer, 0, sizeof(buffer));
210effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  buffer_size = 1;
211effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK,
212effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            MojoReadData(hc, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE));
213effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
214effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Close |hp|.
215effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK, MojoClose(hp));
216effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
217effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // |hc| should still be readable.
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK, MojoWait(hc, MOJO_HANDLE_SIGNAL_READABLE, 0));
219effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
220effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Do a two-phase read from |hc|.
221effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  read_pointer = NULL;
222effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK,
2236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            MojoBeginReadData(
2246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                hc, &read_pointer, &buffer_size, MOJO_READ_DATA_FLAG_NONE));
225effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_LE(buffer_size, sizeof(buffer) - 1);
226effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  memcpy(&buffer[1], read_pointer, buffer_size);
227effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK, MojoEndReadData(hc, buffer_size));
228effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_STREQ("hello world", buffer);
229effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
230effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // |hc| should no longer be readable.
231effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            MojoWait(hc, MOJO_HANDLE_SIGNAL_READABLE, 1000));
233effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
234effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK, MojoClose(hc));
235effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
236effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // TODO(vtl): Test the other way around -- closing the consumer should make
237effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // the producer never-writable?
238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
239effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(CoreTest, MAYBE_BasicSharedBuffer) {
241effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MojoHandle h0, h1;
242effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void* pointer;
243effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
244effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Create a shared buffer (|h0|).
245effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  h0 = MOJO_HANDLE_INVALID;
246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK, MojoCreateSharedBuffer(NULL, 100, &h0));
247effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_NE(h0, MOJO_HANDLE_INVALID);
248effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
249effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Map everything.
250effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  pointer = NULL;
251effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK,
252effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            MojoMapBuffer(h0, 0, 100, &pointer, MOJO_MAP_BUFFER_FLAG_NONE));
253effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_TRUE(pointer);
254effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static_cast<char*>(pointer)[50] = 'x';
255effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
256effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Duplicate |h0| to |h1|.
257effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  h1 = MOJO_HANDLE_INVALID;
258effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK, MojoDuplicateBufferHandle(h0, NULL, &h1));
259effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_NE(h1, MOJO_HANDLE_INVALID);
260effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
261effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Close |h0|.
262effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0));
263effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
264effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // The mapping should still be good.
265effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static_cast<char*>(pointer)[51] = 'y';
266effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
267effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Unmap it.
268e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK, MojoUnmapBuffer(pointer));
269effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
270effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Map half of |h1|.
271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  pointer = NULL;
272effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK,
273effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            MojoMapBuffer(h1, 50, 50, &pointer, MOJO_MAP_BUFFER_FLAG_NONE));
274effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_TRUE(pointer);
275effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
276effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // It should have what we wrote.
277effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ('x', static_cast<char*>(pointer)[0]);
278effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ('y', static_cast<char*>(pointer)[1]);
279effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
280effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Unmap it.
281e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK, MojoUnmapBuffer(pointer));
282effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
283effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1));
284effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
285effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
286effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Defined in core_unittest_pure_c.c.
287effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochextern "C" const char* MinimalCTest(void);
288effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
289effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This checks that things actually work in C (not C++).
290effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST(CoreTest, MinimalCTest) {
291effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const char* failure = MinimalCTest();
292effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_TRUE(failure == NULL) << failure;
293effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
294effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
295effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// TODO(vtl): Add multi-threaded tests.
296effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
297effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}  // namespace
298effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}  // namespace mojo
299