1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2015 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 <string.h>
6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <string>
8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <utility>
9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/logging.h"
11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/memory/shared_memory.h"
12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/strings/string_piece.h"
13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/test/mojo_test_base.h"
14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/c/system/types.h"
15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "testing/gtest/include/gtest/gtest.h"
16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo {
18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace edk {
19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace {
20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezusing SharedBufferTest = test::MojoTestBase;
22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(SharedBufferTest, CreateSharedBuffer) {
24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const std::string message = "hello";
25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle h = CreateBuffer(message.size());
26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteToBuffer(h, 0, message);
27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ExpectBufferContents(h, 0, message);
28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(SharedBufferTest, DuplicateSharedBuffer) {
31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const std::string message = "hello";
32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle h = CreateBuffer(message.size());
33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteToBuffer(h, 0, message);
34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle dupe = DuplicateBuffer(h, false);
36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ExpectBufferContents(dupe, 0, message);
37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(SharedBufferTest, PassSharedBufferLocal) {
40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const std::string message = "hello";
41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle h = CreateBuffer(message.size());
42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteToBuffer(h, 0, message);
43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle dupe = DuplicateBuffer(h, false);
45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle p0, p1;
46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  CreateMessagePipe(&p0, &p1);
47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteMessageWithHandles(p0, "...", &dupe, 1);
49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ("...", ReadMessageWithHandles(p1, &dupe, 1));
50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ExpectBufferContents(dupe, 0, message);
52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#if !defined(OS_IOS)
55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Reads a single message with a shared buffer handle, maps the buffer, copies
57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// the message contents into it, then exits.
58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezDEFINE_TEST_CLIENT_TEST_WITH_PIPE(CopyToBufferClient, SharedBufferTest, h) {
59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle b;
60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::string message = ReadMessageWithHandles(h, &b, 1);
61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteToBuffer(b, 0, message);
62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ("quit", ReadMessage(h));
64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(SharedBufferTest, PassSharedBufferCrossProcess) {
67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const std::string message = "hello";
68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle b = CreateBuffer(message.size());
69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  RUN_CHILD_ON_PIPE(CopyToBufferClient, h)
71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle dupe = DuplicateBuffer(b, false);
72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessageWithHandles(h, message, &dupe, 1);
73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessage(h, "quit");
74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  END_CHILD()
75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ExpectBufferContents(b, 0, message);
77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Creates a new buffer, maps it, writes a message contents to it, unmaps it,
80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// and finally passes it back to the parent.
81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezDEFINE_TEST_CLIENT_TEST_WITH_PIPE(CreateBufferClient, SharedBufferTest, h) {
82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::string message = ReadMessage(h);
83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle b = CreateBuffer(message.size());
84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteToBuffer(b, 0, message);
85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteMessageWithHandles(h, "have a buffer", &b, 1);
86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ("quit", ReadMessage(h));
88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(SharedBufferTest, PassSharedBufferFromChild) {
91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const std::string message = "hello";
92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle b;
93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  RUN_CHILD_ON_PIPE(CreateBufferClient, h)
94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessage(h, message);
95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ReadMessageWithHandles(h, &b, 1);
96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessage(h, "quit");
97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  END_CHILD()
98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ExpectBufferContents(b, 0, message);
100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezDEFINE_TEST_CLIENT_TEST_WITH_PIPE(CreateAndPassBuffer, SharedBufferTest, h) {
103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Receive a pipe handle over the primordial pipe. This will be connected to
104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // another child process.
105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle other_child;
106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::string message = ReadMessageWithHandles(h, &other_child, 1);
107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Create a new shared buffer.
109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle b = CreateBuffer(message.size());
110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Send a copy of the buffer to the parent and the other child.
112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle dupe = DuplicateBuffer(b, false);
113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteMessageWithHandles(h, "", &b, 1);
114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteMessageWithHandles(other_child, "", &dupe, 1);
115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ("quit", ReadMessage(h));
117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezDEFINE_TEST_CLIENT_TEST_WITH_PIPE(ReceiveAndEditBuffer, SharedBufferTest, h) {
120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Receive a pipe handle over the primordial pipe. This will be connected to
121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // another child process (running CreateAndPassBuffer).
122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle other_child;
123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::string message = ReadMessageWithHandles(h, &other_child, 1);
124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Receive a shared buffer from the other child.
126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle b;
127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ReadMessageWithHandles(other_child, &b, 1);
128645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
129645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Write the message from the parent into the buffer and exit.
130645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteToBuffer(b, 0, message);
131645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ(MOJO_RESULT_OK, MojoClose(b));
132645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ("quit", ReadMessage(h));
133645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
134645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
135645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(SharedBufferTest, PassSharedBufferFromChildToChild) {
136645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const std::string message = "hello";
137645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle p0, p1;
138645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  CreateMessagePipe(&p0, &p1);
139645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
140645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle b;
141645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  RUN_CHILD_ON_PIPE(CreateAndPassBuffer, h0)
142645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    RUN_CHILD_ON_PIPE(ReceiveAndEditBuffer, h1)
143645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      // Send one end of the pipe to each child. The first child will create
144645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      // and pass a buffer to the second child and back to us. The second child
145645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      // will write our message into the buffer.
146645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      WriteMessageWithHandles(h0, message, &p0, 1);
147645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      WriteMessageWithHandles(h1, message, &p1, 1);
148645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
149645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      // Receive the buffer back from the first child.
150645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      ReadMessageWithHandles(h0, &b, 1);
151645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
152645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      WriteMessage(h1, "quit");
153645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    END_CHILD()
154645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessage(h0, "quit");
155645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  END_CHILD()
156645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
157645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // The second child should have written this message.
158645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ExpectBufferContents(b, 0, message);
159645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
160645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
161645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezDEFINE_TEST_CLIENT_TEST_WITH_PIPE(CreateAndPassBufferParent, SharedBufferTest,
162645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  parent) {
163645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  RUN_CHILD_ON_PIPE(CreateAndPassBuffer, child)
164645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Read a pipe from the parent and forward it to our child.
165645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle pipe;
166645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    std::string message = ReadMessageWithHandles(parent, &pipe, 1);
167645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
168645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessageWithHandles(child, message, &pipe, 1);
169645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
170645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Read a buffer handle from the child and pass it back to the parent.
171645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle buffer;
172645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ("", ReadMessageWithHandles(child, &buffer, 1));
173645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessageWithHandles(parent, "", &buffer, 1);
174645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
175645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ("quit", ReadMessage(parent));
176645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessage(child, "quit");
177645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  END_CHILD()
178645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
179645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
180645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezDEFINE_TEST_CLIENT_TEST_WITH_PIPE(ReceiveAndEditBufferParent, SharedBufferTest,
181645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  parent) {
182645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  RUN_CHILD_ON_PIPE(ReceiveAndEditBuffer, child)
183645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Read a pipe from the parent and forward it to our child.
184645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle pipe;
185645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    std::string message = ReadMessageWithHandles(parent, &pipe, 1);
186645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessageWithHandles(child, message, &pipe, 1);
187645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
188645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ("quit", ReadMessage(parent));
189645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessage(child, "quit");
190645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  END_CHILD()
191645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
192645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
193645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#if defined(OS_ANDROID) || defined(OS_MACOSX)
194645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Android multi-process tests are not executing the new process. This is flaky.
195645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Passing shared memory handles between cousins is not currently supported on
196645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// OSX.
197645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MAYBE_PassHandleBetweenCousins DISABLED_PassHandleBetweenCousins
198645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#else
199645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MAYBE_PassHandleBetweenCousins PassHandleBetweenCousins
200645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif
201645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(SharedBufferTest, MAYBE_PassHandleBetweenCousins) {
202645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const std::string message = "hello";
203645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle p0, p1;
204645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  CreateMessagePipe(&p0, &p1);
205645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
206645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Spawn two children who will each spawn their own child. Make sure the
207645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // grandchildren (cousins to each other) can pass platform handles.
208645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle b;
209645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  RUN_CHILD_ON_PIPE(CreateAndPassBufferParent, child1)
210645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    RUN_CHILD_ON_PIPE(ReceiveAndEditBufferParent, child2)
211645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      MojoHandle pipe[2];
212645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      CreateMessagePipe(&pipe[0], &pipe[1]);
213645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
214645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      WriteMessageWithHandles(child1, message, &pipe[0], 1);
215645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      WriteMessageWithHandles(child2, message, &pipe[1], 1);
216645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
217645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      // Receive the buffer back from the first child.
218645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      ReadMessageWithHandles(child1, &b, 1);
219645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
220645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      WriteMessage(child2, "quit");
221645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    END_CHILD()
222645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessage(child1, "quit");
223645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  END_CHILD()
224645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
225645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // The second grandchild should have written this message.
226645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ExpectBufferContents(b, 0, message);
227645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
228645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
229645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezDEFINE_TEST_CLIENT_TEST_WITH_PIPE(ReadAndMapWriteSharedBuffer,
230645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  SharedBufferTest, h) {
231645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Receive the shared buffer.
232645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle b;
233645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ("hello", ReadMessageWithHandles(h, &b, 1));
234645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
235645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Read from the bufer.
236645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ExpectBufferContents(b, 0, "hello");
237645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
238645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Extract the shared memory handle and try to map it writable.
239645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  base::SharedMemoryHandle shm_handle;
240645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool read_only = false;
241645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ASSERT_EQ(MOJO_RESULT_OK,
242645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            PassSharedMemoryHandle(b, &shm_handle, nullptr, &read_only));
243645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  base::SharedMemory shared_memory(shm_handle, false);
244645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_TRUE(read_only);
245645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_FALSE(shared_memory.Map(1234));
246645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
247645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ("quit", ReadMessage(h));
248645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteMessage(h, "ok");
249645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
250645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
251645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#if defined(OS_ANDROID)
252645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Android multi-process tests are not executing the new process. This is flaky.
253645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MAYBE_CreateAndPassReadOnlyBuffer DISABLED_CreateAndPassReadOnlyBuffer
254645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#else
255645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MAYBE_CreateAndPassReadOnlyBuffer CreateAndPassReadOnlyBuffer
256645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif
257645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(SharedBufferTest, MAYBE_CreateAndPassReadOnlyBuffer) {
258645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  RUN_CHILD_ON_PIPE(ReadAndMapWriteSharedBuffer, h)
259645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Create a new shared buffer.
260645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle b = CreateBuffer(1234);
261645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteToBuffer(b, 0, "hello");
262645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
263645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Send a read-only copy of the buffer to the child.
264645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle dupe = DuplicateBuffer(b, true /* read_only */);
265645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessageWithHandles(h, "hello", &dupe, 1);
266645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
267645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessage(h, "quit");
268645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ("ok", ReadMessage(h));
269645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  END_CHILD()
270645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
271645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
272645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezDEFINE_TEST_CLIENT_TEST_WITH_PIPE(CreateAndPassReadOnlyBuffer,
273645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  SharedBufferTest, h) {
274645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Create a new shared buffer.
275645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle b = CreateBuffer(1234);
276645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteToBuffer(b, 0, "hello");
277645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
278645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Send a read-only copy of the buffer to the parent.
279645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoHandle dupe = DuplicateBuffer(b, true /* read_only */);
280645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteMessageWithHandles(h, "", &dupe, 1);
281645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
282645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  EXPECT_EQ("quit", ReadMessage(h));
283645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  WriteMessage(h, "ok");
284645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
285645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
286645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#if defined(OS_ANDROID)
287645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Android multi-process tests are not executing the new process. This is flaky.
288645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MAYBE_CreateAndPassFromChildReadOnlyBuffer \
289645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DISABLED_CreateAndPassFromChildReadOnlyBuffer
290645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#else
291645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MAYBE_CreateAndPassFromChildReadOnlyBuffer \
292645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    CreateAndPassFromChildReadOnlyBuffer
293645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif
294645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezTEST_F(SharedBufferTest, MAYBE_CreateAndPassFromChildReadOnlyBuffer) {
295645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  RUN_CHILD_ON_PIPE(CreateAndPassReadOnlyBuffer, h)
296645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    MojoHandle b;
297645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ("", ReadMessageWithHandles(h, &b, 1));
298645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ExpectBufferContents(b, 0, "hello");
299645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
300645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Extract the shared memory handle and try to map it writable.
301645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    base::SharedMemoryHandle shm_handle;
302645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    bool read_only = false;
303645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ASSERT_EQ(MOJO_RESULT_OK,
304645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              PassSharedMemoryHandle(b, &shm_handle, nullptr, &read_only));
305645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    base::SharedMemory shared_memory(shm_handle, false);
306645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_TRUE(read_only);
307645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_FALSE(shared_memory.Map(1234));
308645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
309645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    WriteMessage(h, "quit");
310645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    EXPECT_EQ("ok", ReadMessage(h));
311645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  END_CHILD()
312645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
313645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
314645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif  // !defined(OS_IOS)
315645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
316645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace
317645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace edk
318645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace mojo
319