1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/public/bindings/lib/remote_ptr.h"
6 #include "mojo/public/tests/simple_bindings_support.h"
7 #include "mojo/public/tests/test_support.h"
8 #include "mojom/sample_factory.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace mojo {
12 namespace test {
13 namespace {
14
15 const char kText1[] = "hello";
16 const char kText2[] = "world";
17
18 class SampleFactoryImpl : public sample::FactoryStub {
19 public:
SampleFactoryImpl(ScopedMessagePipeHandle pipe)20 explicit SampleFactoryImpl(ScopedMessagePipeHandle pipe)
21 : client_(pipe.Pass()) {
22 client_.SetPeer(this);
23 }
24
DoStuff(const sample::Request & request,ScopedMessagePipeHandle pipe)25 virtual void DoStuff(const sample::Request& request,
26 ScopedMessagePipeHandle pipe) MOJO_OVERRIDE {
27 std::string text1;
28 if (pipe.is_valid())
29 EXPECT_TRUE(ReadTextMessage(pipe.get(), &text1));
30
31 std::string text2;
32 if (request.pipe().is_valid()) {
33 EXPECT_TRUE(ReadTextMessage(request.pipe().get(), &text2));
34
35 // Ensure that simply accessing request.pipe() does not close it.
36 EXPECT_TRUE(request.pipe().is_valid());
37 }
38
39 ScopedMessagePipeHandle pipe0;
40 if (!text2.empty()) {
41 CreateMessagePipe(&pipe0, &pipe1_);
42 EXPECT_TRUE(WriteTextMessage(pipe1_.get(), text2));
43 }
44
45 AllocationScope scope;
46 sample::Response::Builder response;
47 response.set_x(2);
48 response.set_pipe(pipe0.Pass());
49 client_->DidStuff(response.Finish(), text1);
50 }
51
52 private:
53 RemotePtr<sample::FactoryClient> client_;
54 ScopedMessagePipeHandle pipe1_;
55 };
56
57 class SampleFactoryClientImpl : public sample::FactoryClientStub {
58 public:
SampleFactoryClientImpl(ScopedMessagePipeHandle pipe)59 explicit SampleFactoryClientImpl(ScopedMessagePipeHandle pipe)
60 : factory_(pipe.Pass()),
61 got_response_(false) {
62 factory_.SetPeer(this);
63 }
64
Start()65 void Start() {
66 expected_text_reply_ = kText1;
67
68 ScopedMessagePipeHandle pipe0;
69 CreateMessagePipe(&pipe0, &pipe1_);
70
71 EXPECT_TRUE(WriteTextMessage(pipe1_.get(), kText1));
72
73 ScopedMessagePipeHandle pipe2;
74 CreateMessagePipe(&pipe2, &pipe3_);
75
76 EXPECT_TRUE(WriteTextMessage(pipe3_.get(), kText2));
77
78 AllocationScope scope;
79 sample::Request::Builder request;
80 request.set_x(1);
81 request.set_pipe(pipe2.Pass());
82 factory_->DoStuff(request.Finish(), pipe0.Pass());
83 }
84
StartNoPipes()85 void StartNoPipes() {
86 expected_text_reply_.clear();
87
88 AllocationScope scope;
89 sample::Request::Builder request;
90 request.set_x(1);
91 factory_->DoStuff(request.Finish(), ScopedMessagePipeHandle().Pass());
92 }
93
got_response() const94 bool got_response() const {
95 return got_response_;
96 }
97
DidStuff(const sample::Response & response,const String & text_reply)98 virtual void DidStuff(const sample::Response& response,
99 const String& text_reply) MOJO_OVERRIDE {
100 EXPECT_EQ(expected_text_reply_, text_reply.To<std::string>());
101
102 if (response.pipe().is_valid()) {
103 std::string text2;
104 EXPECT_TRUE(ReadTextMessage(response.pipe().get(), &text2));
105
106 // Ensure that simply accessing response.pipe() does not close it.
107 EXPECT_TRUE(response.pipe().is_valid());
108
109 EXPECT_EQ(std::string(kText2), text2);
110
111 // Do some more tests of handle passing:
112 ScopedMessagePipeHandle p = response.pipe().Pass();
113 EXPECT_TRUE(p.is_valid());
114 EXPECT_FALSE(response.pipe().is_valid());
115 }
116
117 got_response_ = true;
118 }
119
120 private:
121 RemotePtr<sample::Factory> factory_;
122 ScopedMessagePipeHandle pipe1_;
123 ScopedMessagePipeHandle pipe3_;
124 std::string expected_text_reply_;
125 bool got_response_;
126 };
127
128 } // namespace
129
130 class BindingsHandlePassingTest : public testing::Test {
131 public:
PumpMessages()132 void PumpMessages() {
133 bindings_support_.Process();
134 }
135
136 private:
137 SimpleBindingsSupport bindings_support_;
138 };
139
TEST_F(BindingsHandlePassingTest,Basic)140 TEST_F(BindingsHandlePassingTest, Basic) {
141 ScopedMessagePipeHandle pipe0;
142 ScopedMessagePipeHandle pipe1;
143 CreateMessagePipe(&pipe0, &pipe1);
144
145 SampleFactoryImpl factory(pipe0.Pass());
146 SampleFactoryClientImpl factory_client(pipe1.Pass());
147
148 factory_client.Start();
149
150 EXPECT_FALSE(factory_client.got_response());
151
152 PumpMessages();
153
154 EXPECT_TRUE(factory_client.got_response());
155 }
156
TEST_F(BindingsHandlePassingTest,PassInvalid)157 TEST_F(BindingsHandlePassingTest, PassInvalid) {
158 ScopedMessagePipeHandle pipe0;
159 ScopedMessagePipeHandle pipe1;
160 CreateMessagePipe(&pipe0, &pipe1);
161
162 SampleFactoryImpl factory(pipe0.Pass());
163 SampleFactoryClientImpl factory_client(pipe1.Pass());
164
165 factory_client.StartNoPipes();
166
167 EXPECT_FALSE(factory_client.got_response());
168
169 PumpMessages();
170
171 EXPECT_TRUE(factory_client.got_response());
172 }
173
174 } // namespace test
175 } // namespace mojo
176