1cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson// Copyright 2013 The Chromium Authors. All rights reserved.
2cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson// Use of this source code is governed by a BSD-style license that can be
3cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson// found in the LICENSE file.
4cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
5cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#include "mojo/public/cpp/environment/environment.h"
6cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#include "mojo/public/cpp/test_support/test_utils.h"
7cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#include "mojo/public/cpp/utility/run_loop.h"
8cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#include "mojo/public/interfaces/bindings/tests/sample_factory.mojom.h"
9cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#include "testing/gtest/include/gtest/gtest.h"
10cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
11cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonnamespace mojo {
12cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonnamespace test {
13cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonnamespace {
14cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
15cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonconst char kText1[] = "hello";
16cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonconst char kText2[] = "world";
17cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
18cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonclass StringRecorder {
19cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson public:
20cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  explicit StringRecorder(std::string* buf) : buf_(buf) {
21cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  }
22cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  void Run(const String& a) const {
23cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    *buf_ = a.To<std::string>();
24cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  }
25cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson private:
26cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  std::string* buf_;
27cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson};
28cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
29cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonclass ImportedInterfaceImpl
30cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    : public InterfaceImpl<imported::ImportedInterface> {
31cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson public:
32cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  virtual void DoSomething() MOJO_OVERRIDE {
33cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    do_something_count_++;
34cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  }
35cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
36cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  static int do_something_count() { return do_something_count_; }
37cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
38cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson private:
39cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  static int do_something_count_;
40cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson};
41cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonint ImportedInterfaceImpl::do_something_count_ = 0;
42cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
43cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonclass SampleNamedObjectImpl : public InterfaceImpl<sample::NamedObject> {
44cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson public:
45cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  virtual void SetName(const mojo::String& name) MOJO_OVERRIDE {
46cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    name_ = name;
47cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  }
48cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
49cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  virtual void GetName(const mojo::Callback<void(mojo::String)>& callback)
50cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      MOJO_OVERRIDE {
51cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    callback.Run(name_);
52cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  }
53cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
54cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson private:
55ad919c30df71bc191be6f107385638b456da6a0fAdam Jackson  std::string name_;
56ad919c30df71bc191be6f107385638b456da6a0fAdam Jackson};
57ad919c30df71bc191be6f107385638b456da6a0fAdam Jackson
58cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonclass SampleFactoryImpl : public InterfaceImpl<sample::Factory> {
59cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson public:
60cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  virtual void DoStuff(sample::RequestPtr request,
61cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson                       ScopedMessagePipeHandle pipe) MOJO_OVERRIDE {
624a22ae8d446855d839cc199df8eb1b057045cb88Kristian Høgsberg    std::string text1;
63711555d1e347f0e64e6b1b2d0e402e0ee72ace07Ian Romanick    if (pipe.is_valid())
647adcedcd54f6a436512c172e22e98097bfbdbc50Ian Romanick      EXPECT_TRUE(ReadTextMessage(pipe.get(), &text1));
6502986cb2cc1b1d47b26a653e9ae0fa508365f616Ian Romanick
6602986cb2cc1b1d47b26a653e9ae0fa508365f616Ian Romanick    std::string text2;
67cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    if (request->pipe.is_valid()) {
68cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      EXPECT_TRUE(ReadTextMessage(request->pipe.get(), &text2));
69ec770150edff9a5955f52e538adc4bac94c92cadJeremy Huddleston
70ec770150edff9a5955f52e538adc4bac94c92cadJeremy Huddleston      // Ensure that simply accessing request->pipe does not close it.
71cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      EXPECT_TRUE(request->pipe.is_valid());
72cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    }
73cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
74cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    ScopedMessagePipeHandle pipe0;
75cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    if (!text2.empty()) {
76aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg      CreateMessagePipe(NULL, &pipe0, &pipe1_);
77cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      EXPECT_TRUE(WriteTextMessage(pipe1_.get(), text2));
78aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg    }
79cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
80cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    sample::ResponsePtr response(sample::Response::New());
81cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    response->x = 2;
82cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    response->pipe = pipe0.Pass();
83cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    client()->DidStuff(response.Pass(), text1);
84cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
85cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    if (request->obj)
86aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg      request->obj->DoSomething();
87aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg  }
88aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg
89cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  virtual void DoStuff2(ScopedDataPipeConsumerHandle pipe) MOJO_OVERRIDE {
90cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    // Read the data from the pipe, writing the response (as a string) to
91cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    // DidStuff2().
92cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    ASSERT_TRUE(pipe.is_valid());
93cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    uint32_t data_size = 0;
94cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    ASSERT_EQ(MOJO_RESULT_OK,
95cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson              ReadDataRaw(pipe.get(), NULL, &data_size,
96425f9ed44e576aef27f7ab98968043f7f180d0fdKristian Høgsberg                          MOJO_READ_DATA_FLAG_QUERY));
9792d2a78f8d2d56cfadb4cb5323adec32fe73e353Kristian Høgsberg    ASSERT_NE(0, static_cast<int>(data_size));
9820b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg    char data[64];
99020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg    ASSERT_LT(static_cast<int>(data_size), 64);
10092d2a78f8d2d56cfadb4cb5323adec32fe73e353Kristian Høgsberg    ASSERT_EQ(MOJO_RESULT_OK,
101e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg              ReadDataRaw(pipe.get(), data, &data_size,
102e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg                          MOJO_READ_DATA_FLAG_ALL_OR_NONE));
103425f9ed44e576aef27f7ab98968043f7f180d0fdKristian Høgsberg
104cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    client()->DidStuff2(data);
105cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  }
106cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
107425f9ed44e576aef27f7ab98968043f7f180d0fdKristian Høgsberg  virtual void CreateNamedObject(
108a1ea6f6198d80f716936a308cfab235f18a014e1Kristian Høgsberg      InterfaceRequest<sample::NamedObject> object_request) MOJO_OVERRIDE {
10992d2a78f8d2d56cfadb4cb5323adec32fe73e353Kristian Høgsberg    EXPECT_TRUE(object_request.is_pending());
11092d2a78f8d2d56cfadb4cb5323adec32fe73e353Kristian Høgsberg    BindToRequest(new SampleNamedObjectImpl(), &object_request);
11192d2a78f8d2d56cfadb4cb5323adec32fe73e353Kristian Høgsberg  }
11292d2a78f8d2d56cfadb4cb5323adec32fe73e353Kristian Høgsberg
11392d2a78f8d2d56cfadb4cb5323adec32fe73e353Kristian Høgsberg  // These aren't called or implemented, but exist here to test that the
11492d2a78f8d2d56cfadb4cb5323adec32fe73e353Kristian Høgsberg  // methods are generated with the correct argument types for imported
11592d2a78f8d2d56cfadb4cb5323adec32fe73e353Kristian Høgsberg  // interfaces.
11692d2a78f8d2d56cfadb4cb5323adec32fe73e353Kristian Høgsberg  virtual void RequestImportedInterface(
117020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg      InterfaceRequest<imported::ImportedInterface> imported,
118020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg      const mojo::Callback<void(InterfaceRequest<imported::ImportedInterface>)>&
119020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg          callback) MOJO_OVERRIDE {}
120020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg  virtual void TakeImportedInterface(
121020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg      imported::ImportedInterfacePtr imported,
12220b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg      const mojo::Callback<void(imported::ImportedInterfacePtr)>& callback)
123e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg      MOJO_OVERRIDE {}
124e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
125e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg private:
12620b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg  ScopedMessagePipeHandle pipe1_;
12720b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg};
128020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg
129020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsbergclass SampleFactoryClientImpl : public sample::FactoryClient {
130020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg public:
131020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg  SampleFactoryClientImpl() : got_response_(false) {
132020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg  }
133020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg
134020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg  void set_expected_text_reply(const std::string& expected_text_reply) {
135020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg    expected_text_reply_ = expected_text_reply;
136020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg  }
137020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg
13820b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg  bool got_response() const {
1399110425c72e45f618131b559eba883fd6c5536b4Kristian Høgsberg    return got_response_;
1409110425c72e45f618131b559eba883fd6c5536b4Kristian Høgsberg  }
141e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
14220b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg  virtual void DidStuff(sample::ResponsePtr response,
14320b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg                        const String& text_reply) MOJO_OVERRIDE {
144e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    EXPECT_EQ(expected_text_reply_, text_reply);
145e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
146cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    if (response->pipe.is_valid()) {
147cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      std::string text2;
148cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      EXPECT_TRUE(ReadTextMessage(response->pipe.get(), &text2));
149cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
150cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      // Ensure that simply accessing response.pipe does not close it.
151cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      EXPECT_TRUE(response->pipe.is_valid());
1521087cc61b3776f4cdc991dcd95ee59dbd26307f3George Sapountzis
153425f9ed44e576aef27f7ab98968043f7f180d0fdKristian Høgsberg      EXPECT_EQ(std::string(kText2), text2);
154e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
155cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      // Do some more tests of handle passing:
156cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      ScopedMessagePipeHandle p = response->pipe.Pass();
157cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      EXPECT_TRUE(p.is_valid());
158cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      EXPECT_FALSE(response->pipe.is_valid());
159cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    }
160cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
161cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    got_response_ = true;
162cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  }
163cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
164cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  virtual void DidStuff2(const String& text_reply) MOJO_OVERRIDE {
165cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    got_response_ = true;
166cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    EXPECT_EQ(expected_text_reply_, text_reply);
167cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  }
168cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
169cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson private:
170cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  ScopedMessagePipeHandle pipe1_;
171cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  ScopedMessagePipeHandle pipe3_;
172cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  std::string expected_text_reply_;
173cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  bool got_response_;
174cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson};
175cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
176cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonclass HandlePassingTest : public testing::Test {
177cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson public:
178cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  virtual void TearDown() {
179cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    PumpMessages();
180cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  }
181cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
182cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  void PumpMessages() {
183cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    loop_.RunUntilIdle();
184cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  }
185fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
186fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick private:
187cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  Environment env_;
188cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  RunLoop loop_;
189fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick};
190fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
191fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickTEST_F(HandlePassingTest, Basic) {
192cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  sample::FactoryPtr factory;
193fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick  BindToProxy(new SampleFactoryImpl(), &factory);
194cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
195cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  SampleFactoryClientImpl factory_client;
196fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick  factory_client.set_expected_text_reply(kText1);
197fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
198cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  factory.set_client(&factory_client);
199fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
200fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick  MessagePipe pipe0;
201cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_TRUE(WriteTextMessage(pipe0.handle1.get(), kText1));
202fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
203fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick  MessagePipe pipe1;
204fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick  EXPECT_TRUE(WriteTextMessage(pipe1.handle1.get(), kText2));
205cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
206fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick  imported::ImportedInterfacePtr imported;
207cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  BindToProxy(new ImportedInterfaceImpl(), &imported);
208cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
209cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  sample::RequestPtr request(sample::Request::New());
210cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  request->x = 1;
211cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  request->pipe = pipe1.handle0.Pass();
212cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  request->obj = imported.Pass();
213cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  factory->DoStuff(request.Pass(), pipe0.handle0.Pass());
214cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
215cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_FALSE(factory_client.got_response());
216cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  int count_before = ImportedInterfaceImpl::do_something_count();
217cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
218cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  PumpMessages();
219cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
220cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_TRUE(factory_client.got_response());
221cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_EQ(1, ImportedInterfaceImpl::do_something_count() - count_before);
222cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
223cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
224cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonTEST_F(HandlePassingTest, PassInvalid) {
225cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  sample::FactoryPtr factory;
226cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  BindToProxy(new SampleFactoryImpl(), &factory);
227cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
228cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  SampleFactoryClientImpl factory_client;
229cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  factory.set_client(&factory_client);
230cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
231cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  sample::RequestPtr request(sample::Request::New());
232cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  request->x = 1;
233cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  factory->DoStuff(request.Pass(), ScopedMessagePipeHandle().Pass());
234cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
235cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_FALSE(factory_client.got_response());
236cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
237cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  PumpMessages();
238cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
239cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_TRUE(factory_client.got_response());
240cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
241cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
242cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson// Verifies DataPipeConsumer can be passed and read from.
243cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonTEST_F(HandlePassingTest, DataPipe) {
244cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  sample::FactoryPtr factory;
245cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  BindToProxy(new SampleFactoryImpl(), &factory);
246cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
247cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  SampleFactoryClientImpl factory_client;
248cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  factory.set_client(&factory_client);
249cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
250cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  // Writes a string to a data pipe and passes the data pipe (consumer) to the
251cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  // factory.
252cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  ScopedDataPipeProducerHandle producer_handle;
253cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  ScopedDataPipeConsumerHandle consumer_handle;
254cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  MojoCreateDataPipeOptions options = {
255cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      sizeof(MojoCreateDataPipeOptions),
256cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
257cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      1,
258cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      1024};
259cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  ASSERT_EQ(MOJO_RESULT_OK,
260aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg            CreateDataPipe(&options, &producer_handle, &consumer_handle));
261cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  std::string expected_text_reply = "got it";
262cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  factory_client.set_expected_text_reply(expected_text_reply);
263cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  // +1 for \0.
264cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  uint32_t data_size = static_cast<uint32_t>(expected_text_reply.size() + 1);
265cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  ASSERT_EQ(MOJO_RESULT_OK,
266cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson            WriteDataRaw(producer_handle.get(), expected_text_reply.c_str(),
267cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson                         &data_size, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
268cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
269cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  factory->DoStuff2(consumer_handle.Pass());
270cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
271cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_FALSE(factory_client.got_response());
272cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
273cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  PumpMessages();
274cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
275cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_TRUE(factory_client.got_response());
276cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
277cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
278cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonTEST_F(HandlePassingTest, PipesAreClosed) {
279cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  sample::FactoryPtr factory;
280cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  BindToProxy(new SampleFactoryImpl(), &factory);
281cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
282cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  SampleFactoryClientImpl factory_client;
283cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  factory.set_client(&factory_client);
284cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
285cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  MessagePipe extra_pipe;
286cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
287cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  MojoHandle handle0_value = extra_pipe.handle0.get().value();
288cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  MojoHandle handle1_value = extra_pipe.handle1.get().value();
289cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
290cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  {
291cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    Array<ScopedMessagePipeHandle> pipes(2);
292cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    pipes[0] = extra_pipe.handle0.Pass();
293cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    pipes[1] = extra_pipe.handle1.Pass();
294cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
295cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    sample::RequestPtr request(sample::Request::New());
296cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    request->more_pipes = pipes.Pass();
297cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
298cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson    factory->DoStuff(request.Pass(), ScopedMessagePipeHandle());
299cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  }
300cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
301cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  // We expect the pipes to have been closed.
302cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle0_value));
303cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle1_value));
304cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
305cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
306cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonTEST_F(HandlePassingTest, IsHandle) {
30729206ae569c4c784ec6884084b4bd8631f66b866Ian Romanick  // Validate that mojo::internal::IsHandle<> works as expected since this.
308cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  // template is key to ensuring that we don't leak handles.
309cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_TRUE(internal::IsHandle<Handle>::value);
310cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_TRUE(internal::IsHandle<MessagePipeHandle>::value);
311cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_TRUE(internal::IsHandle<DataPipeConsumerHandle>::value);
312cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_TRUE(internal::IsHandle<DataPipeProducerHandle>::value);
313cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_TRUE(internal::IsHandle<SharedBufferHandle>::value);
314cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
315cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  // Basic sanity checks...
316cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_FALSE(internal::IsHandle<int>::value);
317cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_FALSE(internal::IsHandle<sample::FactoryPtr>::value);
318cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_FALSE(internal::IsHandle<String>::value);
319ae2c31ed669abab66a8c4b68d8d746e94b9ebf28Xiang, Haihao}
320ae2c31ed669abab66a8c4b68d8d746e94b9ebf28Xiang, Haihao
321ae2c31ed669abab66a8c4b68d8d746e94b9ebf28Xiang, HaihaoTEST_F(HandlePassingTest, CreateNamedObject) {
322ae2c31ed669abab66a8c4b68d8d746e94b9ebf28Xiang, Haihao  sample::FactoryPtr factory;
323ae2c31ed669abab66a8c4b68d8d746e94b9ebf28Xiang, Haihao  BindToProxy(new SampleFactoryImpl(), &factory);
324cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
325cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  sample::NamedObjectPtr object1;
326cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_FALSE(object1);
327cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
328cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  InterfaceRequest<sample::NamedObject> object1_request = Get(&object1);
329cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_TRUE(object1_request.is_pending());
330cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  factory->CreateNamedObject(object1_request.Pass());
331cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_FALSE(object1_request.is_pending());  // We've passed the request.
332cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
333cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  ASSERT_TRUE(object1);
334cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  object1->SetName("object1");
335cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
336cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  sample::NamedObjectPtr object2;
337cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  factory->CreateNamedObject(Get(&object2));
338cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  object2->SetName("object2");
339cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
340cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  std::string name1;
341cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  object1->GetName(StringRecorder(&name1));
342cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
343cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  std::string name2;
344cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  object2->GetName(StringRecorder(&name2));
345cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
346cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  PumpMessages();  // Yield for results.
347cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
348cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_EQ(std::string("object1"), name1);
349cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson  EXPECT_EQ(std::string("object2"), name2);
350cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
351cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
352cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}  // namespace
353cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}  // namespace test
354cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}  // namespace mojo
355cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson