1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2013 The Chromium Authors. All rights reserved.
2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be
3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file.
4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/core.h"
6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stdint.h>
8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <limits>
10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/bind.h"
12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/embedder/embedder_internal.h"
13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/awakable.h"
14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/core_test_base.h"
15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/test_utils.h"
16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#if defined(OS_WIN)
18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/win/windows_version.h"
19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif
20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo {
22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace edk {
23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace {
24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezconst MojoHandleSignalsState kEmptyMojoHandleSignalsState = {0u, 0u};
26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezconst MojoHandleSignalsState kFullMojoHandleSignalsState = {~0u, ~0u};
27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezconst MojoHandleSignals kAllSignals = MOJO_HANDLE_SIGNAL_READABLE |
28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      MOJO_HANDLE_SIGNAL_WRITABLE |
29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      MOJO_HANDLE_SIGNAL_PEER_CLOSED;
30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezusing CoreTest = test::CoreTestBase;
32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(CoreTest, GetTimeTicksNow) {
34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const MojoTimeTicks start = core()->GetTimeTicksNow();
35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(static_cast<MojoTimeTicks>(0), start)
36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      << "GetTimeTicksNow should return nonzero value";
37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  test::Sleep(test::DeadlineFromMilliseconds(15));
38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const MojoTimeTicks finish = core()->GetTimeTicksNow();
39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Allow for some fuzz in sleep.
40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_GE((finish - start), static_cast<MojoTimeTicks>(8000))
41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      << "Sleeping should result in increasing time ticks";
42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(CoreTest, Basic) {
45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MockHandleInfo info;
46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, info.GetCtorCallCount());
48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle h = CreateMockHandle(&info);
49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, info.GetCtorCallCount());
50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(h, MOJO_HANDLE_INVALID);
51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, info.GetWriteMessageCallCount());
53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteMessage(h, nullptr, 0, nullptr, 0,
55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, info.GetWriteMessageCallCount());
57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, info.GetReadMessageCallCount());
59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t num_bytes = 0;
60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_OK,
62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->ReadMessage(h, nullptr, &num_bytes, nullptr, nullptr,
63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                          MOJO_READ_MESSAGE_FLAG_NONE));
64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, info.GetReadMessageCallCount());
65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadMessage(h, nullptr, nullptr, nullptr, nullptr,
67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                MOJO_READ_MESSAGE_FLAG_NONE));
68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(2u, info.GetReadMessageCallCount());
69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, info.GetWriteDataCallCount());
71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteData(h, nullptr, nullptr, MOJO_WRITE_DATA_FLAG_NONE));
73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, info.GetWriteDataCallCount());
74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, info.GetBeginWriteDataCallCount());
76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->BeginWriteData(h, nullptr, nullptr,
78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                   MOJO_WRITE_DATA_FLAG_NONE));
79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, info.GetBeginWriteDataCallCount());
80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, info.GetEndWriteDataCallCount());
82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndWriteData(h, 0));
83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, info.GetEndWriteDataCallCount());
84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, info.GetReadDataCallCount());
86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadData(h, nullptr, nullptr, MOJO_READ_DATA_FLAG_NONE));
88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, info.GetReadDataCallCount());
89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, info.GetBeginReadDataCallCount());
91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->BeginReadData(h, nullptr, nullptr,
93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  MOJO_READ_DATA_FLAG_NONE));
94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, info.GetBeginReadDataCallCount());
95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, info.GetEndReadDataCallCount());
97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndReadData(h, 0));
98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, info.GetEndReadDataCallCount());
99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, info.GetAddAwakableCallCount());
101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE,
103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         nullptr));
104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, info.GetAddAwakableCallCount());
105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 0, nullptr));
107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(2u, info.GetAddAwakableCallCount());
108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandleSignalsState hss = kFullMojoHandleSignalsState;
109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE,
111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         &hss));
112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(3u, info.GetAddAwakableCallCount());
113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, hss.satisfied_signals);
114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, hss.satisfiable_signals);
115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_FAILED_PRECONDITION,
117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 10 * 1000, nullptr));
118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(4u, info.GetAddAwakableCallCount());
119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kFullMojoHandleSignalsState;
120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 10 * 1000, &hss));
122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(5u, info.GetAddAwakableCallCount());
123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, hss.satisfied_signals);
124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, hss.satisfiable_signals);
125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandleSignals handle_signals = ~MOJO_HANDLE_SIGNAL_NONE;
127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
128645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_FAILED_PRECONDITION,
129645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->WaitMany(&h, &handle_signals, 1, MOJO_DEADLINE_INDEFINITE,
130645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                       nullptr, nullptr));
131645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(6u, info.GetAddAwakableCallCount());
132645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t result_index = static_cast<uint32_t>(-1);
133645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
134645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_FAILED_PRECONDITION,
135645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->WaitMany(&h, &handle_signals, 1, MOJO_DEADLINE_INDEFINITE,
136645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                       &result_index, nullptr));
137645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(7u, info.GetAddAwakableCallCount());
138645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, result_index);
139645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kFullMojoHandleSignalsState;
140645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
141645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_FAILED_PRECONDITION,
142645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->WaitMany(&h, &handle_signals, 1, MOJO_DEADLINE_INDEFINITE,
143645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                       nullptr, &hss));
144645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(8u, info.GetAddAwakableCallCount());
145645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, hss.satisfied_signals);
146645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, hss.satisfiable_signals);
147645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  result_index = static_cast<uint32_t>(-1);
148645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kFullMojoHandleSignalsState;
149645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
150645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_FAILED_PRECONDITION,
151645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->WaitMany(&h, &handle_signals, 1, MOJO_DEADLINE_INDEFINITE,
152645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                       &result_index, &hss));
153645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(9u, info.GetAddAwakableCallCount());
154645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, result_index);
155645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, hss.satisfied_signals);
156645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, hss.satisfiable_signals);
157645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
158645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, info.GetDtorCallCount());
159645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, info.GetCloseCallCount());
160645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
161645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, info.GetCloseCallCount());
162645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, info.GetDtorCallCount());
163645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
164645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // No awakables should ever have ever been added.
165645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, info.GetRemoveAwakableCallCount());
166645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
167645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
168645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(CoreTest, InvalidArguments) {
169645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |Close()|:
170645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  {
171645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(MOJO_HANDLE_INVALID));
172645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(10));
173645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(1000000000));
174645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
175645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Test a double-close.
176645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MockHandleInfo info;
177645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle h = CreateMockHandle(&info);
178645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
179645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(1u, info.GetCloseCallCount());
180645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h));
181645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(1u, info.GetCloseCallCount());
182645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
183645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
184645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |Wait()|:
185645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  {
186645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
187645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->Wait(MOJO_HANDLE_INVALID, ~MOJO_HANDLE_SIGNAL_NONE,
188645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                           MOJO_DEADLINE_INDEFINITE, nullptr));
189645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
190645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->Wait(10, ~MOJO_HANDLE_SIGNAL_NONE,
191645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                           MOJO_DEADLINE_INDEFINITE, nullptr));
192645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
193645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandleSignalsState hss = kFullMojoHandleSignalsState;
194645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
195645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->Wait(MOJO_HANDLE_INVALID, ~MOJO_HANDLE_SIGNAL_NONE,
196645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                           MOJO_DEADLINE_INDEFINITE, &hss));
197645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // On invalid argument, it shouldn't modify the handle signals state.
198645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
199645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              hss.satisfied_signals);
200645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals,
201645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              hss.satisfiable_signals);
202645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    hss = kFullMojoHandleSignalsState;
203645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
204645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->Wait(10, ~MOJO_HANDLE_SIGNAL_NONE,
205645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                           MOJO_DEADLINE_INDEFINITE, &hss));
206645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // On invalid argument, it shouldn't modify the handle signals state.
207645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
208645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              hss.satisfied_signals);
209645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals,
210645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              hss.satisfiable_signals);
211645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
212645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
213645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |WaitMany()|:
214645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  {
215645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle handles[2] = {MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID};
216645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandleSignals signals[2] = {~MOJO_HANDLE_SIGNAL_NONE,
217645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                    ~MOJO_HANDLE_SIGNAL_NONE};
218645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(
219645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        MOJO_RESULT_INVALID_ARGUMENT,
220645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WaitMany(handles, signals, 0, MOJO_DEADLINE_INDEFINITE,
221645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         nullptr, nullptr));
222645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
223645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->WaitMany(nullptr, signals, 0, MOJO_DEADLINE_INDEFINITE,
224645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                               nullptr, nullptr));
225645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // If |num_handles| is invalid, it should leave |result_index| and
226645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // |signals_states| alone.
227645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // (We use -1 internally; make sure that doesn't leak.)
228645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    uint32_t result_index = 123;
229645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandleSignalsState hss = kFullMojoHandleSignalsState;
230645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
231645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->WaitMany(nullptr, signals, 0, MOJO_DEADLINE_INDEFINITE,
232645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                               &result_index, &hss));
233645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(123u, result_index);
234645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
235645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              hss.satisfied_signals);
236645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals,
237645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              hss.satisfiable_signals);
238645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
239645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
240645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->WaitMany(handles, nullptr, 0, MOJO_DEADLINE_INDEFINITE,
241645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                               nullptr, nullptr));
242645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(
243645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        MOJO_RESULT_INVALID_ARGUMENT,
244645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WaitMany(handles, signals, 1, MOJO_DEADLINE_INDEFINITE, nullptr,
245645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         nullptr));
246645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // But if a handle is bad, then it should set |result_index| but still leave
247645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // |signals_states| alone.
248645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    result_index = static_cast<uint32_t>(-1);
249645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    hss = kFullMojoHandleSignalsState;
250645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
251645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->WaitMany(
252645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  handles, signals, 1, MOJO_DEADLINE_INDEFINITE, &result_index,
253645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  &hss));
254645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(0u, result_index);
255645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
256645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              hss.satisfied_signals);
257645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals,
258645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              hss.satisfiable_signals);
259645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
260645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MockHandleInfo info[2];
261645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    handles[0] = CreateMockHandle(&info[0]);
262645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
263645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    result_index = static_cast<uint32_t>(-1);
264645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    hss = kFullMojoHandleSignalsState;
265645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
266645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->WaitMany(
267645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  handles, signals, 1, MOJO_DEADLINE_INDEFINITE, &result_index,
268645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  &hss));
269645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(0u, result_index);
270645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(0u, hss.satisfied_signals);
271645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(0u, hss.satisfiable_signals);
272645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
273645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // On invalid argument, it'll leave |signals_states| alone.
274645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    result_index = static_cast<uint32_t>(-1);
275645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    hss = kFullMojoHandleSignalsState;
276645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
277645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->WaitMany(
278645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  handles, signals, 2, MOJO_DEADLINE_INDEFINITE, &result_index,
279645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  &hss));
280645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(1u, result_index);
281645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
282645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              hss.satisfied_signals);
283645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals,
284645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              hss.satisfiable_signals);
285645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    handles[1] = handles[0] + 1;  // Invalid handle.
286645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(
287645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        MOJO_RESULT_INVALID_ARGUMENT,
288645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WaitMany(handles, signals, 2, MOJO_DEADLINE_INDEFINITE, nullptr,
289645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         nullptr));
290645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    handles[1] = CreateMockHandle(&info[1]);
291645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(
292645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        MOJO_RESULT_FAILED_PRECONDITION,
293645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WaitMany(handles, signals, 2, MOJO_DEADLINE_INDEFINITE, nullptr,
294645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         nullptr));
295645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
296645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // TODO(vtl): Test one where we get "failed precondition" only for the
297645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // second handle (and the first one is valid to wait on).
298645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
299645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_OK, core()->Close(handles[0]));
300645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_OK, core()->Close(handles[1]));
301645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
302645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
303645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |CreateMessagePipe()|: Nothing to check (apart from things that cause
304645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // death).
305645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
306645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |WriteMessage()|:
307645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Only check arguments checked by |Core|, namely |handle|, |handles|, and
308645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |num_handles|.
309645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  {
310645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
311645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->WriteMessage(MOJO_HANDLE_INVALID, nullptr, 0,
312645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                   nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
313645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
314645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MockHandleInfo info;
315645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle h = CreateMockHandle(&info);
316645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle handles[2] = {MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID};
317645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
318645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Huge handle count (implausibly big on some systems -- more than can be
319645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // stored in a 32-bit address space).
320645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Note: This may return either |MOJO_RESULT_INVALID_ARGUMENT| or
321645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // |MOJO_RESULT_RESOURCE_EXHAUSTED|, depending on whether it's plausible or
322645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // not.
323645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_NE(
324645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        MOJO_RESULT_OK,
325645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WriteMessage(h, nullptr, 0, handles,
326645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             std::numeric_limits<uint32_t>::max(),
327645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             MOJO_WRITE_MESSAGE_FLAG_NONE));
328645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(0u, info.GetWriteMessageCallCount());
329645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
330645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Null |bytes| with non-zero message size.
331645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
332645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->WriteMessage(h, nullptr, 1, nullptr, 0,
333645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
334645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(0u, info.GetWriteMessageCallCount());
335645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
336645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Null |handles| with non-zero handle count.
337645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
338645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->WriteMessage(h, nullptr, 0, nullptr, 1,
339645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
340645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(0u, info.GetWriteMessageCallCount());
341645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
342645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Huge handle count (plausibly big).
343645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
344645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->WriteMessage(
345645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  h, nullptr, 0, handles,
346645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  std::numeric_limits<uint32_t>::max() / sizeof(handles[0]),
347645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  MOJO_WRITE_MESSAGE_FLAG_NONE));
348645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(0u, info.GetWriteMessageCallCount());
349645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
350645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Invalid handle in |handles|.
351645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(
352645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        MOJO_RESULT_INVALID_ARGUMENT,
353645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WriteMessage(h, nullptr, 0, handles, 1,
354645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             MOJO_WRITE_MESSAGE_FLAG_NONE));
355645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(0u, info.GetWriteMessageCallCount());
356645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
357645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Two invalid handles in |handles|.
358645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(
359645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        MOJO_RESULT_INVALID_ARGUMENT,
360645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WriteMessage(h, nullptr, 0, handles, 2,
361645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             MOJO_WRITE_MESSAGE_FLAG_NONE));
362645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(0u, info.GetWriteMessageCallCount());
363645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
364645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Can't send a handle over itself. Note that this will also cause |h| to be
365645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // closed.
366645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    handles[0] = h;
367645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(
368645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        MOJO_RESULT_INVALID_ARGUMENT,
369645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WriteMessage(h, nullptr, 0, handles, 1,
370645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             MOJO_WRITE_MESSAGE_FLAG_NONE));
371645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(0u, info.GetWriteMessageCallCount());
372645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
373645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    h = CreateMockHandle(&info);
374645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
375645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MockHandleInfo info2;
376645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
377645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // This is "okay", but |MockDispatcher| doesn't implement it.
378645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    handles[0] = CreateMockHandle(&info2);
379645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(
380645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        MOJO_RESULT_UNIMPLEMENTED,
381645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WriteMessage(h, nullptr, 0, handles, 1,
382645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             MOJO_WRITE_MESSAGE_FLAG_NONE));
383645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(1u, info.GetWriteMessageCallCount());
384645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
385645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // One of the |handles| is still invalid.
386645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    handles[0] = CreateMockHandle(&info2);
387645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(
388645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        MOJO_RESULT_INVALID_ARGUMENT,
389645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WriteMessage(h, nullptr, 0, handles, 2,
390645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             MOJO_WRITE_MESSAGE_FLAG_NONE));
391645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(1u, info.GetWriteMessageCallCount());
392645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
393645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // One of the |handles| is the same as |h|. Both handles are closed.
394645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    handles[0] = CreateMockHandle(&info2);
395645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    handles[1] = h;
396645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(
397645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        MOJO_RESULT_INVALID_ARGUMENT,
398645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WriteMessage(h, nullptr, 0, handles, 2,
399645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             MOJO_WRITE_MESSAGE_FLAG_NONE));
400645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(1u, info.GetWriteMessageCallCount());
401645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
402645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    h = CreateMockHandle(&info);
403645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
404645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Can't send a handle twice in the same message.
405645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    handles[0] = CreateMockHandle(&info2);
406645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    handles[1] = handles[0];
407645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(
408645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        MOJO_RESULT_BUSY,
409645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WriteMessage(h, nullptr, 0, handles, 2,
410645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             MOJO_WRITE_MESSAGE_FLAG_NONE));
411645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(1u, info.GetWriteMessageCallCount());
412645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
413645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
414645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
415645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
416645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |ReadMessage()|:
417645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Only check arguments checked by |Core|, namely |handle|, |handles|, and
418645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |num_handles|.
419645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  {
420645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(
421645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        MOJO_RESULT_INVALID_ARGUMENT,
422645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->ReadMessage(MOJO_HANDLE_INVALID, nullptr, nullptr, nullptr,
423645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                            nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
424645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
425645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MockHandleInfo info;
426645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle h = CreateMockHandle(&info);
427645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
428645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Okay.
429645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    uint32_t handle_count = 0;
430645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_OK,
431645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              core()->ReadMessage(
432645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  h, nullptr, nullptr, nullptr, &handle_count,
433645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  MOJO_READ_MESSAGE_FLAG_NONE));
434645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Checked by |Core|, shouldn't go through to the dispatcher.
435645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(1u, info.GetReadMessageCallCount());
436645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
437645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
438645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
439645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
440645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
441645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// These test invalid arguments that should cause death if we're being paranoid
442645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// about checking arguments (which we would want to do if, e.g., we were in a
443645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// true "kernel" situation, but we might not want to do otherwise for
444645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// performance reasons). Probably blatant errors like passing in null pointers
445645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// (for required pointer arguments) will still cause death, but perhaps not
446645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// predictably.
447645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(CoreTest, InvalidArgumentsDeath) {
448645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#if defined(OFFICIAL_BUILD)
449645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const char kMemoryCheckFailedRegex[] = "";
450645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#else
451645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const char kMemoryCheckFailedRegex[] = "Check failed";
452645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif
453645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
454645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |WaitMany()|:
455645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  {
456645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle handle = MOJO_HANDLE_INVALID;
457645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandleSignals signals = ~MOJO_HANDLE_SIGNAL_NONE;
458645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_DEATH_IF_SUPPORTED(
459645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WaitMany(nullptr, &signals, 1, MOJO_DEADLINE_INDEFINITE,
460645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         nullptr, nullptr),
461645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        kMemoryCheckFailedRegex);
462645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_DEATH_IF_SUPPORTED(
463645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->WaitMany(&handle, nullptr, 1, MOJO_DEADLINE_INDEFINITE, nullptr,
464645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         nullptr),
465645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        kMemoryCheckFailedRegex);
466645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // TODO(vtl): |result_index| and |signals_states| are optional. Test them
467645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // with non-null invalid pointers?
468645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
469645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
470645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |CreateMessagePipe()|:
471645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  {
472645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle h;
473645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_DEATH_IF_SUPPORTED(
474645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->CreateMessagePipe(nullptr, nullptr, nullptr),
475645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        kMemoryCheckFailedRegex);
476645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_DEATH_IF_SUPPORTED(
477645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->CreateMessagePipe(nullptr, &h, nullptr),
478645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        kMemoryCheckFailedRegex);
479645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_DEATH_IF_SUPPORTED(
480645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->CreateMessagePipe(nullptr, nullptr, &h),
481645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        kMemoryCheckFailedRegex);
482645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
483645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
484645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |ReadMessage()|:
485645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Only check arguments checked by |Core|, namely |handle|, |handles|, and
486645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |num_handles|.
487645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  {
488645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MockHandleInfo info;
489645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle h = CreateMockHandle(&info);
490645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
491645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    uint32_t handle_count = 1;
492645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_DEATH_IF_SUPPORTED(
493645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        core()->ReadMessage(h, nullptr, nullptr, nullptr, &handle_count,
494645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                            MOJO_READ_MESSAGE_FLAG_NONE),
495645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        kMemoryCheckFailedRegex);
496645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
497645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
498645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
499645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
500645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
501645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// TODO(vtl): test |Wait()| and |WaitMany()| properly
502645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez//  - including |WaitMany()| with the same handle more than once (with
503645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez//    same/different signals)
504645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
505645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(CoreTest, MessagePipe) {
506645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle h[2];
507645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandleSignalsState hss[2];
508645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t result_index;
509645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
510645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessagePipe(nullptr, &h[0], &h[1]));
511645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Should get two distinct, valid handles.
512645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(h[0], MOJO_HANDLE_INVALID);
513645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(h[1], MOJO_HANDLE_INVALID);
514645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(h[0], h[1]);
515645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
516645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Neither should be readable.
517645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandleSignals signals[2] = {MOJO_HANDLE_SIGNAL_READABLE,
518645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  MOJO_HANDLE_SIGNAL_READABLE};
519645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  result_index = static_cast<uint32_t>(-1);
520645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss[0] = kEmptyMojoHandleSignalsState;
521645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss[1] = kEmptyMojoHandleSignalsState;
522645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
523645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_DEADLINE_EXCEEDED,
524645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->WaitMany(h, signals, 2, 0, &result_index, hss));
525645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(static_cast<uint32_t>(-1), result_index);
526645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
527645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
528645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals);
529645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss[1].satisfiable_signals);
530645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
531645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Try to read anyway.
532645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  char buffer[1] = {'a'};
533645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t buffer_size = 1;
534645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
535645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_SHOULD_WAIT,
536645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->ReadMessage(h[0], buffer, &buffer_size, nullptr, nullptr,
537645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                          MOJO_READ_MESSAGE_FLAG_NONE));
538645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Check that it left its inputs alone.
539645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ('a', buffer[0]);
540645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, buffer_size);
541645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
542645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Both should be writable.
543645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss[0] = kEmptyMojoHandleSignalsState;
544645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h[0], MOJO_HANDLE_SIGNAL_WRITABLE,
545645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                         1000000000, &hss[0]));
546645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
547645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
548645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss[0] = kEmptyMojoHandleSignalsState;
549645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h[1], MOJO_HANDLE_SIGNAL_WRITABLE,
550645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                         1000000000, &hss[0]));
551645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
552645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
553645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
554645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Also check that |h[1]| is writable using |WaitMany()|.
555645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  signals[0] = MOJO_HANDLE_SIGNAL_READABLE;
556645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  signals[1] = MOJO_HANDLE_SIGNAL_WRITABLE;
557645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  result_index = static_cast<uint32_t>(-1);
558645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss[0] = kEmptyMojoHandleSignalsState;
559645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss[1] = kEmptyMojoHandleSignalsState;
560645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
561645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_OK,
562645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->WaitMany(h, signals, 2, MOJO_DEADLINE_INDEFINITE, &result_index,
563645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                       hss));
564645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, result_index);
565645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
566645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
567645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals);
568645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss[1].satisfiable_signals);
569645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
570645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Write to |h[1]|.
571645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  buffer[0] = 'b';
572645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
573645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_OK,
574645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->WriteMessage(h[1], buffer, 1, nullptr, 0,
575645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                           MOJO_WRITE_MESSAGE_FLAG_NONE));
576645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
577645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Check that |h[0]| is now readable.
578645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  signals[0] = MOJO_HANDLE_SIGNAL_READABLE;
579645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  signals[1] = MOJO_HANDLE_SIGNAL_READABLE;
580645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  result_index = static_cast<uint32_t>(-1);
581645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss[0] = kEmptyMojoHandleSignalsState;
582645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss[1] = kEmptyMojoHandleSignalsState;
583645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
584645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_OK,
585645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->WaitMany(h, signals, 2, MOJO_DEADLINE_INDEFINITE, &result_index,
586645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                       hss));
587645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, result_index);
588645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
589645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss[0].satisfied_signals);
590645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
591645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals);
592645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss[1].satisfiable_signals);
593645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
594645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Read from |h[0]|.
595645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // First, get only the size.
596645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  buffer_size = 0;
597645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
598645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_RESOURCE_EXHAUSTED,
599645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->ReadMessage(h[0], nullptr, &buffer_size, nullptr, nullptr,
600645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                          MOJO_READ_MESSAGE_FLAG_NONE));
601645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, buffer_size);
602645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Then actually read it.
603645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  buffer[0] = 'c';
604645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  buffer_size = 1;
605645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
606645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_OK,
607645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->ReadMessage(h[0], buffer, &buffer_size, nullptr, nullptr,
608645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                          MOJO_READ_MESSAGE_FLAG_NONE));
609645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ('b', buffer[0]);
610645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, buffer_size);
611645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
612645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |h[0]| should no longer be readable.
613645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss[0] = kEmptyMojoHandleSignalsState;
614645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
615645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h[0], MOJO_HANDLE_SIGNAL_READABLE, 0, &hss[0]));
616645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
617645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
618645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
619645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Write to |h[0]|.
620645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  buffer[0] = 'd';
621645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
622645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_OK,
623645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->WriteMessage(h[0], buffer, 1, nullptr, 0,
624645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                           MOJO_WRITE_MESSAGE_FLAG_NONE));
625645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
626645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Close |h[0]|.
627645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h[0]));
628645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
629645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Wait for |h[1]| to learn about the other end's closure.
630645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
631645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h[1], MOJO_HANDLE_SIGNAL_PEER_CLOSED, 1000000000,
632645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         &hss[0]));
633645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
634645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Check that |h[1]| is no longer writable (and will never be).
635645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss[0] = kEmptyMojoHandleSignalsState;
636645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
637645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h[1], MOJO_HANDLE_SIGNAL_WRITABLE, 1000000000,
638645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         &hss[0]));
639645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
640645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss[0].satisfied_signals);
641645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
642645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss[0].satisfiable_signals);
643645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
644645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Check that |h[1]| is still readable (for the moment).
645645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss[0] = kEmptyMojoHandleSignalsState;
646645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h[1], MOJO_HANDLE_SIGNAL_READABLE,
647645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                         1000000000, &hss[0]));
648645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
649645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss[0].satisfied_signals);
650645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
651645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss[0].satisfiable_signals);
652645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
653645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Discard a message from |h[1]|.
654645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
655645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadMessage(h[1], nullptr, nullptr, nullptr, nullptr,
656645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
657645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
658645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |h[1]| is no longer readable (and will never be).
659645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss[0] = kFullMojoHandleSignalsState;
660645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
661645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
662645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         &hss[0]));
663645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[0].satisfied_signals);
664645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[0].satisfiable_signals);
665645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
666645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Try writing to |h[1]|.
667645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  buffer[0] = 'e';
668645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
669645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_FAILED_PRECONDITION,
670645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->WriteMessage(h[1], buffer, 1, nullptr, 0,
671645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                           MOJO_WRITE_MESSAGE_FLAG_NONE));
672645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
673645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h[1]));
674645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
675645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
676645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Tests passing a message pipe handle.
677645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(CoreTest, MessagePipeBasicLocalHandlePassing1) {
678645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const char kHello[] = "hello";
679645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello));
680645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const char kWorld[] = "world!!!";
681645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld));
682645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  char buffer[100];
683645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
684645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t num_bytes;
685645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle handles[10];
686645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t num_handles;
687645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandleSignalsState hss;
688645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle h_received;
689645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
690645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle h_passing[2];
691645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
692645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->CreateMessagePipe(nullptr, &h_passing[0], &h_passing[1]));
693645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
694645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Make sure that |h_passing[]| work properly.
695645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
696645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteMessage(h_passing[0], kHello, kHelloSize, nullptr, 0,
697645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
698645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kEmptyMojoHandleSignalsState;
699645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
700645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
701645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         &hss));
702645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
703645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfied_signals);
704645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
705645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = kBufferSize;
706645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_handles = arraysize(handles);
707645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
708645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadMessage(
709645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                h_passing[1], buffer, &num_bytes, handles, &num_handles,
710645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                MOJO_READ_MESSAGE_FLAG_NONE));
711645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kHelloSize, num_bytes);
712645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_STREQ(kHello, buffer);
713645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, num_handles);
714645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
715645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Make sure that you can't pass either of the message pipe's handles over
716645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // itself.
717645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
718645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteMessage(h_passing[0], kHello, kHelloSize,
719645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 &h_passing[0], 1,
720645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
721645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
722645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->CreateMessagePipe(nullptr, &h_passing[0], &h_passing[1]));
723645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
724645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
725645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteMessage(h_passing[0], kHello, kHelloSize,
726645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 &h_passing[1], 1,
727645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
728645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
729645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->CreateMessagePipe(nullptr, &h_passing[0], &h_passing[1]));
730645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
731645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle h_passed[2];
732645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
733645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->CreateMessagePipe(nullptr, &h_passed[0], &h_passed[1]));
734645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
735645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Make sure that |h_passed[]| work properly.
736645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
737645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteMessage(h_passed[0], kHello, kHelloSize, nullptr, 0,
738645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
739645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kEmptyMojoHandleSignalsState;
740645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
741645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h_passed[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
742645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         &hss));
743645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
744645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfied_signals);
745645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
746645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = kBufferSize;
747645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_handles = arraysize(handles);
748645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
749645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadMessage(
750645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                h_passed[1], buffer, &num_bytes, handles, &num_handles,
751645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                MOJO_READ_MESSAGE_FLAG_NONE));
752645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kHelloSize, num_bytes);
753645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_STREQ(kHello, buffer);
754645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, num_handles);
755645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
756645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Send |h_passed[1]| from |h_passing[0]| to |h_passing[1]|.
757645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
758645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteMessage(h_passing[0], kWorld, kWorldSize,
759645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 &h_passed[1], 1,
760645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
761645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kEmptyMojoHandleSignalsState;
762645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
763645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
764645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         &hss));
765645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
766645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfied_signals);
767645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
768645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = kBufferSize;
769645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_handles = arraysize(handles);
770645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
771645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadMessage(
772645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                h_passing[1], buffer, &num_bytes, handles, &num_handles,
773645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                MOJO_READ_MESSAGE_FLAG_NONE));
774645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kWorldSize, num_bytes);
775645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_STREQ(kWorld, buffer);
776645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, num_handles);
777645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  h_received = handles[0];
778645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(h_received, MOJO_HANDLE_INVALID);
779645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(h_received, h_passing[0]);
780645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(h_received, h_passing[1]);
781645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(h_received, h_passed[0]);
782645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
783645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Note: We rely on the Mojo system not re-using handle values very often.
784645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(h_received, h_passed[1]);
785645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
786645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |h_passed[1]| should no longer be valid; check that trying to close it
787645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // fails. See above note.
788645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h_passed[1]));
789645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
790645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Write to |h_passed[0]|. Should receive on |h_received|.
791645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
792645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteMessage(h_passed[0], kHello, kHelloSize, nullptr, 0,
793645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
794645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kEmptyMojoHandleSignalsState;
795645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
796645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h_received, MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
797645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         &hss));
798645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
799645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfied_signals);
800645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
801645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = kBufferSize;
802645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_handles = arraysize(handles);
803645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
804645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadMessage(
805645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                h_received, buffer, &num_bytes, handles, &num_handles,
806645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                MOJO_READ_MESSAGE_FLAG_NONE));
807645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kHelloSize, num_bytes);
808645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_STREQ(kHello, buffer);
809645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, num_handles);
810645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
811645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0]));
812645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1]));
813645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passed[0]));
814645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_received));
815645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
816645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
817645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(CoreTest, DataPipe) {
818645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle ph, ch;  // p is for producer and c is for consumer.
819645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandleSignalsState hss;
820645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
821645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
822645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->CreateDataPipe(nullptr, &ph, &ch));
823645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Should get two distinct, valid handles.
824645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ph, MOJO_HANDLE_INVALID);
825645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ch, MOJO_HANDLE_INVALID);
826645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ph, ch);
827645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
828645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Producer should be never-readable, but already writable.
829645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kEmptyMojoHandleSignalsState;
830645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
831645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_FAILED_PRECONDITION,
832645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->Wait(ph, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
833645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
834645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
835645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfiable_signals);
836645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kEmptyMojoHandleSignalsState;
837645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ph, MOJO_HANDLE_SIGNAL_WRITABLE, 0,
838645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                         &hss));
839645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
840645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
841645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfiable_signals);
842645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
843645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Consumer should be never-writable, and not yet readable.
844645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kFullMojoHandleSignalsState;
845645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
846645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_FAILED_PRECONDITION,
847645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->Wait(ch, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
848645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, hss.satisfied_signals);
849645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
850645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfiable_signals);
851645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kFullMojoHandleSignalsState;
852645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
853645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_DEADLINE_EXCEEDED,
854645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
855645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, hss.satisfied_signals);
856645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
857645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfiable_signals);
858645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
859645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Write.
860645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  signed char elements[2] = {'A', 'B'};
861645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t num_bytes = 2u;
862645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
863645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteData(ph, elements, &num_bytes,
864645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                              MOJO_WRITE_DATA_FLAG_NONE));
865645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(2u, num_bytes);
866645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
867645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Wait for the data to arrive to the consumer.
868645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
869645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss));
870645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
871645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Consumer should now be readable.
872645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kEmptyMojoHandleSignalsState;
873645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0,
874645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                         &hss));
875645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
876645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
877645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfiable_signals);
878645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
879645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Peek one character.
880645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  elements[0] = -1;
881645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  elements[1] = -1;
882645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 1u;
883645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
884645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadData(
885645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                ch, elements, &num_bytes,
886645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                MOJO_READ_DATA_FLAG_NONE | MOJO_READ_DATA_FLAG_PEEK));
887645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ('A', elements[0]);
888645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(-1, elements[1]);
889645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
890645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Read one character.
891645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  elements[0] = -1;
892645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  elements[1] = -1;
893645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 1u;
894645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->ReadData(ch, elements, &num_bytes,
895645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                             MOJO_READ_DATA_FLAG_NONE));
896645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ('A', elements[0]);
897645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(-1, elements[1]);
898645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
899645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Two-phase write.
900645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void* write_ptr = nullptr;
901645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 0u;
902645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
903645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->BeginWriteData(ph, &write_ptr, &num_bytes,
904645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                   MOJO_WRITE_DATA_FLAG_NONE));
905645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // We count on the default options providing a decent buffer size.
906645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_GE(num_bytes, 3u);
907645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
908645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Trying to do a normal write during a two-phase write should fail.
909645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  elements[0] = 'X';
910645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 1u;
911645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_BUSY,
912645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteData(ph, elements, &num_bytes,
913645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                              MOJO_WRITE_DATA_FLAG_NONE));
914645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
915645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Actually write the data, and complete it now.
916645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  static_cast<char*>(write_ptr)[0] = 'C';
917645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  static_cast<char*>(write_ptr)[1] = 'D';
918645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  static_cast<char*>(write_ptr)[2] = 'E';
919645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 3u));
920645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
921645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Wait for the data to arrive to the consumer.
922645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
923645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss));
924645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
925645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Query how much data we have.
926645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 0;
927645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
928645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadData(ch, nullptr, &num_bytes,
929645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             MOJO_READ_DATA_FLAG_QUERY));
930645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_GE(num_bytes, 1u);
931645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
932645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Try to query with peek. Should fail.
933645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 0;
934645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
935645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_INVALID_ARGUMENT,
936645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->ReadData(ch, nullptr, &num_bytes,
937645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                       MOJO_READ_DATA_FLAG_QUERY | MOJO_READ_DATA_FLAG_PEEK));
938645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, num_bytes);
939645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
940645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Try to discard ten characters, in all-or-none mode. Should fail.
941645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 10;
942645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OUT_OF_RANGE,
943645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadData(
944645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                ch, nullptr, &num_bytes,
945645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE));
946645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
947645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Try to discard two characters, in peek mode. Should fail.
948645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 2;
949645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
950645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_INVALID_ARGUMENT,
951645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->ReadData(ch, nullptr, &num_bytes,
952645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                       MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_PEEK));
953645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
954645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Discard a character.
955645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 1;
956645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
957645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadData(
958645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                ch, nullptr, &num_bytes,
959645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE));
960645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
961645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Ensure the 3 bytes were read.
962645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
963645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss));
964645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
965645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Try a two-phase read of the remaining three bytes with peek. Should fail.
966645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const void* read_ptr = nullptr;
967645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 3;
968645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
969645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->BeginReadData(ch, &read_ptr, &num_bytes,
970645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  MOJO_READ_DATA_FLAG_PEEK));
971645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
972645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Read the remaining two characters, in two-phase mode (all-or-none).
973645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 3;
974645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
975645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->BeginReadData(ch, &read_ptr, &num_bytes,
976645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  MOJO_READ_DATA_FLAG_ALL_OR_NONE));
977645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Note: Count on still being able to do the contiguous read here.
978645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(3u, num_bytes);
979645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
980645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Discarding right now should fail.
981645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 1;
982645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_BUSY,
983645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadData(ch, nullptr, &num_bytes,
984645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             MOJO_READ_DATA_FLAG_DISCARD));
985645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
986645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Actually check our data and end the two-phase read.
987645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ('C', static_cast<const char*>(read_ptr)[0]);
988645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ('D', static_cast<const char*>(read_ptr)[1]);
989645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ('E', static_cast<const char*>(read_ptr)[2]);
990645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 3u));
991645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
992645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Consumer should now be no longer readable.
993645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kFullMojoHandleSignalsState;
994645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
995645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_DEADLINE_EXCEEDED,
996645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
997645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(0u, hss.satisfied_signals);
998645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
999645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfiable_signals);
1000645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1001645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // TODO(vtl): More.
1002645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1003645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Close the producer.
1004645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ph));
1005645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1006645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Wait for this to get to the consumer.
1007645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1008645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(ch, MOJO_HANDLE_SIGNAL_PEER_CLOSED, 1000000000, &hss));
1009645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1010645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // The consumer should now be never-readable.
1011645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kFullMojoHandleSignalsState;
1012645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(
1013645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MOJO_RESULT_FAILED_PRECONDITION,
1014645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
1015645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
1016645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
1017645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1018645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ch));
1019645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
1020645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1021645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Tests passing data pipe producer and consumer handles.
1022645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(CoreTest, MessagePipeBasicLocalHandlePassing2) {
1023645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const char kHello[] = "hello";
1024645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello));
1025645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const char kWorld[] = "world!!!";
1026645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld));
1027645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  char buffer[100];
1028645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
1029645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t num_bytes;
1030645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle handles[10];
1031645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t num_handles;
1032645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandleSignalsState hss;
1033645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1034645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle h_passing[2];
1035645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1036645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->CreateMessagePipe(nullptr, &h_passing[0], &h_passing[1]));
1037645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1038645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle ph, ch;
1039645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1040645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->CreateDataPipe(nullptr, &ph, &ch));
1041645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1042645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Send |ch| from |h_passing[0]| to |h_passing[1]|.
1043645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1044645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteMessage(h_passing[0], kHello, kHelloSize, &ch, 1,
1045645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
1046645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kEmptyMojoHandleSignalsState;
1047645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1048645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
1049645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         &hss));
1050645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
1051645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfied_signals);
1052645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
1053645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = kBufferSize;
1054645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_handles = arraysize(handles);
1055645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1056645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadMessage(
1057645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                h_passing[1], buffer, &num_bytes, handles, &num_handles,
1058645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                MOJO_READ_MESSAGE_FLAG_NONE));
1059645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kHelloSize, num_bytes);
1060645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_STREQ(kHello, buffer);
1061645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, num_handles);
1062645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle ch_received = handles[0];
1063645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ch_received, MOJO_HANDLE_INVALID);
1064645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ch_received, h_passing[0]);
1065645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ch_received, h_passing[1]);
1066645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ch_received, ph);
1067645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1068645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Note: We rely on the Mojo system not re-using handle values very often.
1069645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ch_received, ch);
1070645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1071645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |ch| should no longer be valid; check that trying to close it fails. See
1072645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // above note.
1073645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(ch));
1074645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1075645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Write to |ph|. Should receive on |ch_received|.
1076645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = kWorldSize;
1077645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1078645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteData(ph, kWorld, &num_bytes,
1079645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                              MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
1080645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kEmptyMojoHandleSignalsState;
1081645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1082645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(ch_received, MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
1083645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         &hss));
1084645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
1085645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
1086645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfiable_signals);
1087645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = kBufferSize;
1088645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1089645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadData(ch_received, buffer, &num_bytes,
1090645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             MOJO_READ_MESSAGE_FLAG_NONE));
1091645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kWorldSize, num_bytes);
1092645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_STREQ(kWorld, buffer);
1093645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1094645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Now pass |ph| in the same direction.
1095645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1096645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteMessage(h_passing[0], kWorld, kWorldSize, &ph, 1,
1097645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
1098645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kEmptyMojoHandleSignalsState;
1099645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
1101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         &hss));
1102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
1103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfied_signals);
1104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
1105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = kBufferSize;
1106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_handles = arraysize(handles);
1107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadMessage(
1109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                h_passing[1], buffer, &num_bytes, handles, &num_handles,
1110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                MOJO_READ_MESSAGE_FLAG_NONE));
1111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kWorldSize, num_bytes);
1112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_STREQ(kWorld, buffer);
1113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, num_handles);
1114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle ph_received = handles[0];
1115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ph_received, MOJO_HANDLE_INVALID);
1116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ph_received, h_passing[0]);
1117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ph_received, h_passing[1]);
1118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ph_received, ch_received);
1119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Again, rely on the Mojo system not re-using handle values very often.
1121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ph_received, ph);
1122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |ph| should no longer be valid; check that trying to close it fails. See
1124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // above note.
1125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(ph));
1126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Write to |ph_received|. Should receive on |ch_received|.
1128645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = kHelloSize;
1129645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1130645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteData(ph_received, kHello, &num_bytes,
1131645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                              MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
1132645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kEmptyMojoHandleSignalsState;
1133645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1134645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(ch_received, MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
1135645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         &hss));
1136645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
1137645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
1138645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfiable_signals);
1139645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = kBufferSize;
1140645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1141645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadData(ch_received, buffer, &num_bytes,
1142645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             MOJO_READ_MESSAGE_FLAG_NONE));
1143645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kHelloSize, num_bytes);
1144645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_STREQ(kHello, buffer);
1145645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1146645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ph = ph_received;
1147645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ph_received = MOJO_HANDLE_INVALID;
1148645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ch = ch_received;
1149645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ch_received = MOJO_HANDLE_INVALID;
1150645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1151645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Make sure that |ph| can't be sent if it's in a two-phase write.
1152645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void* write_ptr = nullptr;
1153645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 0;
1154645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1155645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->BeginWriteData(ph, &write_ptr, &num_bytes,
1156645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                   MOJO_WRITE_DATA_FLAG_NONE));
1157645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_GE(num_bytes, 1u);
1158645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_BUSY,
1159645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteMessage(h_passing[0], kHello, kHelloSize, &ph, 1,
1160645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
1161645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1162645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // But |ch| can, even if |ph| is in a two-phase write.
1163645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1164645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteMessage(h_passing[0], kHello, kHelloSize, &ch, 1,
1165645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
1166645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ch = MOJO_HANDLE_INVALID;
1167645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1168645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
1169645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         nullptr));
1170645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = kBufferSize;
1171645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_handles = arraysize(handles);
1172645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1173645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadMessage(
1174645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                h_passing[1], buffer, &num_bytes, handles, &num_handles,
1175645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                MOJO_READ_MESSAGE_FLAG_NONE));
1176645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kHelloSize, num_bytes);
1177645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_STREQ(kHello, buffer);
1178645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, num_handles);
1179645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ch = handles[0];
1180645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ch, MOJO_HANDLE_INVALID);
1181645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1182645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Complete the two-phase write.
1183645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  static_cast<char*>(write_ptr)[0] = 'x';
1184645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 1));
1185645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1186645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Wait for |ch| to be readable.
1187645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kEmptyMojoHandleSignalsState;
1188645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE,
1189645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                         1000000000, &hss));
1190645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
1191645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
1192645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfiable_signals);
1193645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1194645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Make sure that |ch| can't be sent if it's in a two-phase read.
1195645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const void* read_ptr = nullptr;
1196645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = 1;
1197645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1198645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->BeginReadData(ch, &read_ptr, &num_bytes,
1199645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  MOJO_READ_DATA_FLAG_ALL_OR_NONE));
1200645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_BUSY,
1201645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteMessage(h_passing[0], kHello, kHelloSize, &ch, 1,
1202645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
1203645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1204645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // But |ph| can, even if |ch| is in a two-phase read.
1205645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1206645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->WriteMessage(h_passing[0], kWorld, kWorldSize, &ph, 1,
1207645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
1208645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ph = MOJO_HANDLE_INVALID;
1209645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  hss = kEmptyMojoHandleSignalsState;
1210645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1211645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
1212645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         &hss));
1213645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
1214645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            hss.satisfied_signals);
1215645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
1216645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_bytes = kBufferSize;
1217645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  num_handles = arraysize(handles);
1218645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
1219645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            core()->ReadMessage(
1220645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                h_passing[1], buffer, &num_bytes, handles, &num_handles,
1221645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                MOJO_READ_MESSAGE_FLAG_NONE));
1222645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(kWorldSize, num_bytes);
1223645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_STREQ(kWorld, buffer);
1224645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(1u, num_handles);
1225645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ph = handles[0];
1226645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_NE(ph, MOJO_HANDLE_INVALID);
1227645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1228645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Complete the two-phase read.
1229645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ('x', static_cast<const char*>(read_ptr)[0]);
1230645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 1));
1231645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1232645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0]));
1233645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1]));
1234645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ph));
1235645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ch));
1236645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
1237645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1238645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezstruct TestAsyncWaiter {
1239645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  TestAsyncWaiter() : result(MOJO_RESULT_UNKNOWN) {}
1240645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1241645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void Awake(MojoResult r) { result = r; }
1242645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1243645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult result;
1244645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
1245645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1246645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// TODO(vtl): Test |DuplicateBufferHandle()| and |MapBuffer()|.
1247645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
1248645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace
1249645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace edk
1250645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace mojo
1251