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: 20 explicit SampleFactoryImpl(ScopedMessagePipeHandle pipe) 21 : client_(pipe.Pass()) { 22 client_.SetPeer(this); 23 } 24 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: 59 explicit SampleFactoryClientImpl(ScopedMessagePipeHandle pipe) 60 : factory_(pipe.Pass()), 61 got_response_(false) { 62 factory_.SetPeer(this); 63 } 64 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 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 94 bool got_response() const { 95 return got_response_; 96 } 97 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: 132 void PumpMessages() { 133 bindings_support_.Process(); 134 } 135 136 private: 137 SimpleBindingsSupport bindings_support_; 138 }; 139 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 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