| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/public/cpp/bindings/allocation_scope.h" | 5 #include "mojo/public/cpp/bindings/allocation_scope.h" |
| 6 #include "mojo/public/cpp/bindings/remote_ptr.h" | |
| 7 #include "mojo/public/cpp/environment/environment.h" | 6 #include "mojo/public/cpp/environment/environment.h" |
| 8 #include "mojo/public/cpp/test_support/test_utils.h" | 7 #include "mojo/public/cpp/test_support/test_utils.h" |
| 9 #include "mojo/public/cpp/utility/run_loop.h" | 8 #include "mojo/public/cpp/utility/run_loop.h" |
| 10 #include "mojo/public/interfaces/bindings/tests/sample_factory.mojom.h" | 9 #include "mojo/public/interfaces/bindings/tests/sample_factory.mojom.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
| 12 | 11 |
| 13 namespace mojo { | 12 namespace mojo { |
| 14 namespace test { | 13 namespace test { |
| 15 namespace { | 14 namespace { |
| 16 | 15 |
| 17 const char kText1[] = "hello"; | 16 const char kText1[] = "hello"; |
| 18 const char kText2[] = "world"; | 17 const char kText2[] = "world"; |
| 19 | 18 |
| 20 class SampleFactoryImpl : public sample::Factory { | 19 class SampleFactoryImpl : public InterfaceImpl<sample::Factory> { |
| 21 public: | 20 public: |
| 22 explicit SampleFactoryImpl(sample::ScopedFactoryClientHandle handle) | 21 virtual void OnConnectionError() MOJO_OVERRIDE { |
| 23 : client_(handle.Pass(), this) { | 22 delete this; |
| 23 } |
| 24 |
| 25 virtual void SetClient(sample::FactoryClient* client) MOJO_OVERRIDE { |
| 26 client_ = client; |
| 24 } | 27 } |
| 25 | 28 |
| 26 virtual void DoStuff(const sample::Request& request, | 29 virtual void DoStuff(const sample::Request& request, |
| 27 ScopedMessagePipeHandle pipe) MOJO_OVERRIDE { | 30 ScopedMessagePipeHandle pipe) MOJO_OVERRIDE { |
| 28 std::string text1; | 31 std::string text1; |
| 29 if (pipe.is_valid()) | 32 if (pipe.is_valid()) |
| 30 EXPECT_TRUE(ReadTextMessage(pipe.get(), &text1)); | 33 EXPECT_TRUE(ReadTextMessage(pipe.get(), &text1)); |
| 31 | 34 |
| 32 std::string text2; | 35 std::string text2; |
| 33 if (request.pipe().is_valid()) { | 36 if (request.pipe().is_valid()) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 63 ASSERT_LT(static_cast<int>(data_size), 64); | 66 ASSERT_LT(static_cast<int>(data_size), 64); |
| 64 ASSERT_EQ(MOJO_RESULT_OK, | 67 ASSERT_EQ(MOJO_RESULT_OK, |
| 65 ReadDataRaw(pipe.get(), data, &data_size, | 68 ReadDataRaw(pipe.get(), data, &data_size, |
| 66 MOJO_READ_DATA_FLAG_ALL_OR_NONE)); | 69 MOJO_READ_DATA_FLAG_ALL_OR_NONE)); |
| 67 | 70 |
| 68 AllocationScope scope; | 71 AllocationScope scope; |
| 69 client_->DidStuff2(String(std::string(data))); | 72 client_->DidStuff2(String(std::string(data))); |
| 70 } | 73 } |
| 71 | 74 |
| 72 private: | 75 private: |
| 73 RemotePtr<sample::FactoryClient> client_; | 76 sample::FactoryClient* client_; |
| 74 ScopedMessagePipeHandle pipe1_; | 77 ScopedMessagePipeHandle pipe1_; |
| 75 }; | 78 }; |
| 76 | 79 |
| 77 class SampleFactoryClientImpl : public sample::FactoryClient { | 80 class SampleFactoryClientImpl : public sample::FactoryClient { |
| 78 public: | 81 public: |
| 79 explicit SampleFactoryClientImpl(sample::ScopedFactoryHandle handle) | 82 SampleFactoryClientImpl() : got_response_(false) { |
| 80 : factory_(handle.Pass(), this), | |
| 81 got_response_(false) { | |
| 82 } | 83 } |
| 83 | 84 |
| 84 void Start() { | 85 void set_expected_text_reply(const std::string& expected_text_reply) { |
| 85 expected_text_reply_ = kText1; | 86 expected_text_reply_ = expected_text_reply; |
| 86 | |
| 87 ScopedMessagePipeHandle pipe0; | |
| 88 CreateMessagePipe(&pipe0, &pipe1_); | |
| 89 | |
| 90 EXPECT_TRUE(WriteTextMessage(pipe1_.get(), kText1)); | |
| 91 | |
| 92 ScopedMessagePipeHandle pipe2; | |
| 93 CreateMessagePipe(&pipe2, &pipe3_); | |
| 94 | |
| 95 EXPECT_TRUE(WriteTextMessage(pipe3_.get(), kText2)); | |
| 96 | |
| 97 AllocationScope scope; | |
| 98 sample::Request::Builder request; | |
| 99 request.set_x(1); | |
| 100 request.set_pipe(pipe2.Pass()); | |
| 101 factory_->DoStuff(request.Finish(), pipe0.Pass()); | |
| 102 } | |
| 103 | |
| 104 void StartNoPipes() { | |
| 105 expected_text_reply_.clear(); | |
| 106 | |
| 107 AllocationScope scope; | |
| 108 sample::Request::Builder request; | |
| 109 request.set_x(1); | |
| 110 factory_->DoStuff(request.Finish(), ScopedMessagePipeHandle().Pass()); | |
| 111 } | |
| 112 | |
| 113 // Writes a string to a data pipe and passes the data pipe (consumer) to the | |
| 114 // factory. | |
| 115 void StartDataPipe() { | |
| 116 expected_text_reply_.clear(); | |
| 117 | |
| 118 ScopedDataPipeProducerHandle producer_handle; | |
| 119 ScopedDataPipeConsumerHandle consumer_handle; | |
| 120 MojoCreateDataPipeOptions options = { | |
| 121 sizeof(MojoCreateDataPipeOptions), | |
| 122 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, | |
| 123 1, | |
| 124 1024}; | |
| 125 ASSERT_EQ(MOJO_RESULT_OK, | |
| 126 CreateDataPipe(&options, &producer_handle, &consumer_handle)); | |
| 127 expected_text_reply_ = "got it"; | |
| 128 // +1 for \0. | |
| 129 uint32_t data_size = static_cast<uint32_t>(expected_text_reply_.size() + 1); | |
| 130 ASSERT_EQ(MOJO_RESULT_OK, | |
| 131 WriteDataRaw(producer_handle.get(), expected_text_reply_.c_str(), | |
| 132 &data_size, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); | |
| 133 | |
| 134 AllocationScope scope; | |
| 135 factory_->DoStuff2(consumer_handle.Pass()); | |
| 136 } | 87 } |
| 137 | 88 |
| 138 bool got_response() const { | 89 bool got_response() const { |
| 139 return got_response_; | 90 return got_response_; |
| 140 } | 91 } |
| 141 | 92 |
| 142 virtual void DidStuff(const sample::Response& response, | 93 virtual void DidStuff(const sample::Response& response, |
| 143 const String& text_reply) MOJO_OVERRIDE { | 94 const String& text_reply) MOJO_OVERRIDE { |
| 144 EXPECT_EQ(expected_text_reply_, text_reply.To<std::string>()); | 95 EXPECT_EQ(expected_text_reply_, text_reply.To<std::string>()); |
| 145 | 96 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 160 | 111 |
| 161 got_response_ = true; | 112 got_response_ = true; |
| 162 } | 113 } |
| 163 | 114 |
| 164 virtual void DidStuff2(const String& text_reply) MOJO_OVERRIDE { | 115 virtual void DidStuff2(const String& text_reply) MOJO_OVERRIDE { |
| 165 got_response_ = true; | 116 got_response_ = true; |
| 166 EXPECT_EQ(expected_text_reply_, text_reply.To<std::string>()); | 117 EXPECT_EQ(expected_text_reply_, text_reply.To<std::string>()); |
| 167 } | 118 } |
| 168 | 119 |
| 169 private: | 120 private: |
| 170 RemotePtr<sample::Factory> factory_; | |
| 171 ScopedMessagePipeHandle pipe1_; | 121 ScopedMessagePipeHandle pipe1_; |
| 172 ScopedMessagePipeHandle pipe3_; | 122 ScopedMessagePipeHandle pipe3_; |
| 173 std::string expected_text_reply_; | 123 std::string expected_text_reply_; |
| 174 bool got_response_; | 124 bool got_response_; |
| 175 }; | 125 }; |
| 176 | 126 |
| 177 class HandlePassingTest : public testing::Test { | 127 class HandlePassingTest : public testing::Test { |
| 178 public: | 128 public: |
| 129 virtual void TearDown() { |
| 130 PumpMessages(); |
| 131 } |
| 132 |
| 179 void PumpMessages() { | 133 void PumpMessages() { |
| 180 loop_.RunUntilIdle(); | 134 loop_.RunUntilIdle(); |
| 181 } | 135 } |
| 182 | 136 |
| 183 private: | 137 private: |
| 184 Environment env_; | 138 Environment env_; |
| 185 RunLoop loop_; | 139 RunLoop loop_; |
| 186 }; | 140 }; |
| 187 | 141 |
| 188 TEST_F(HandlePassingTest, Basic) { | 142 TEST_F(HandlePassingTest, Basic) { |
| 189 InterfacePipe<sample::Factory> pipe; | 143 sample::FactoryPtr factory; |
| 144 BindToProxy(new SampleFactoryImpl(), &factory); |
| 190 | 145 |
| 191 SampleFactoryImpl factory(pipe.handle_to_peer.Pass()); | 146 SampleFactoryClientImpl factory_client; |
| 192 SampleFactoryClientImpl factory_client(pipe.handle_to_self.Pass()); | 147 factory_client.set_expected_text_reply(kText1); |
| 193 | 148 |
| 194 factory_client.Start(); | 149 factory->SetClient(&factory_client); |
| 150 |
| 151 ScopedMessagePipeHandle pipe0, pipe1; |
| 152 CreateMessagePipe(&pipe0, &pipe1); |
| 153 |
| 154 EXPECT_TRUE(WriteTextMessage(pipe1.get(), kText1)); |
| 155 |
| 156 ScopedMessagePipeHandle pipe2, pipe3; |
| 157 CreateMessagePipe(&pipe2, &pipe3); |
| 158 |
| 159 EXPECT_TRUE(WriteTextMessage(pipe3.get(), kText2)); |
| 160 |
| 161 { |
| 162 AllocationScope scope; |
| 163 sample::Request::Builder request; |
| 164 request.set_x(1); |
| 165 request.set_pipe(pipe2.Pass()); |
| 166 factory->DoStuff(request.Finish(), pipe0.Pass()); |
| 167 } |
| 195 | 168 |
| 196 EXPECT_FALSE(factory_client.got_response()); | 169 EXPECT_FALSE(factory_client.got_response()); |
| 197 | 170 |
| 198 PumpMessages(); | 171 PumpMessages(); |
| 199 | 172 |
| 200 EXPECT_TRUE(factory_client.got_response()); | 173 EXPECT_TRUE(factory_client.got_response()); |
| 201 } | 174 } |
| 202 | 175 |
| 203 TEST_F(HandlePassingTest, PassInvalid) { | 176 TEST_F(HandlePassingTest, PassInvalid) { |
| 204 InterfacePipe<sample::Factory> pipe; | 177 sample::FactoryPtr factory; |
| 178 BindToProxy(new SampleFactoryImpl(), &factory); |
| 205 | 179 |
| 206 SampleFactoryImpl factory(pipe.handle_to_peer.Pass()); | 180 SampleFactoryClientImpl factory_client; |
| 207 SampleFactoryClientImpl factory_client(pipe.handle_to_self.Pass()); | 181 factory->SetClient(&factory_client); |
| 208 | 182 |
| 209 factory_client.StartNoPipes(); | 183 { |
| 184 AllocationScope scope; |
| 185 sample::Request::Builder request; |
| 186 request.set_x(1); |
| 187 factory->DoStuff(request.Finish(), ScopedMessagePipeHandle().Pass()); |
| 188 } |
| 210 | 189 |
| 211 EXPECT_FALSE(factory_client.got_response()); | 190 EXPECT_FALSE(factory_client.got_response()); |
| 212 | 191 |
| 213 PumpMessages(); | 192 PumpMessages(); |
| 214 | 193 |
| 215 EXPECT_TRUE(factory_client.got_response()); | 194 EXPECT_TRUE(factory_client.got_response()); |
| 216 } | 195 } |
| 217 | 196 |
| 218 // Verifies DataPipeConsumer can be passed and read from. | 197 // Verifies DataPipeConsumer can be passed and read from. |
| 219 TEST_F(HandlePassingTest, DataPipe) { | 198 TEST_F(HandlePassingTest, DataPipe) { |
| 220 InterfacePipe<sample::Factory> pipe; | 199 sample::FactoryPtr factory; |
| 200 BindToProxy(new SampleFactoryImpl(), &factory); |
| 221 | 201 |
| 222 SampleFactoryImpl factory(pipe.handle_to_peer.Pass()); | 202 SampleFactoryClientImpl factory_client; |
| 223 SampleFactoryClientImpl factory_client(pipe.handle_to_self.Pass()); | 203 factory->SetClient(&factory_client); |
| 224 | 204 |
| 225 ASSERT_NO_FATAL_FAILURE(factory_client.StartDataPipe()); | 205 // Writes a string to a data pipe and passes the data pipe (consumer) to the |
| 206 // factory. |
| 207 ScopedDataPipeProducerHandle producer_handle; |
| 208 ScopedDataPipeConsumerHandle consumer_handle; |
| 209 MojoCreateDataPipeOptions options = { |
| 210 sizeof(MojoCreateDataPipeOptions), |
| 211 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, |
| 212 1, |
| 213 1024}; |
| 214 ASSERT_EQ(MOJO_RESULT_OK, |
| 215 CreateDataPipe(&options, &producer_handle, &consumer_handle)); |
| 216 std::string expected_text_reply = "got it"; |
| 217 factory_client.set_expected_text_reply(expected_text_reply); |
| 218 // +1 for \0. |
| 219 uint32_t data_size = static_cast<uint32_t>(expected_text_reply.size() + 1); |
| 220 ASSERT_EQ(MOJO_RESULT_OK, |
| 221 WriteDataRaw(producer_handle.get(), expected_text_reply.c_str(), |
| 222 &data_size, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); |
| 223 |
| 224 { |
| 225 AllocationScope scope; |
| 226 factory->DoStuff2(consumer_handle.Pass()); |
| 227 } |
| 226 | 228 |
| 227 EXPECT_FALSE(factory_client.got_response()); | 229 EXPECT_FALSE(factory_client.got_response()); |
| 228 | 230 |
| 229 PumpMessages(); | 231 PumpMessages(); |
| 230 | 232 |
| 231 EXPECT_TRUE(factory_client.got_response()); | 233 EXPECT_TRUE(factory_client.got_response()); |
| 232 } | 234 } |
| 233 | 235 |
| 234 TEST_F(HandlePassingTest, PipesAreClosed) { | 236 TEST_F(HandlePassingTest, PipesAreClosed) { |
| 235 InterfacePipe<sample::Factory> pipe; | 237 sample::FactoryPtr factory; |
| 236 RemotePtr<sample::Factory> factory(pipe.handle_to_self.Pass(), NULL); | 238 BindToProxy(new SampleFactoryImpl(), &factory); |
| 239 |
| 240 SampleFactoryClientImpl factory_client; |
| 241 factory->SetClient(&factory_client); |
| 237 | 242 |
| 238 MessagePipe extra_pipe; | 243 MessagePipe extra_pipe; |
| 239 | 244 |
| 240 MojoHandle handle0_value = extra_pipe.handle0.get().value(); | 245 MojoHandle handle0_value = extra_pipe.handle0.get().value(); |
| 241 MojoHandle handle1_value = extra_pipe.handle1.get().value(); | 246 MojoHandle handle1_value = extra_pipe.handle1.get().value(); |
| 242 | 247 |
| 243 { | 248 { |
| 244 AllocationScope scope; | 249 AllocationScope scope; |
| 245 | 250 |
| 246 Array<MessagePipeHandle>::Builder pipes(2); | 251 Array<MessagePipeHandle>::Builder pipes(2); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 260 } | 265 } |
| 261 | 266 |
| 262 // We expect the pipes to have been closed. | 267 // We expect the pipes to have been closed. |
| 263 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle0_value)); | 268 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle0_value)); |
| 264 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle1_value)); | 269 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle1_value)); |
| 265 } | 270 } |
| 266 | 271 |
| 267 } // namespace | 272 } // namespace |
| 268 } // namespace test | 273 } // namespace test |
| 269 } // namespace mojo | 274 } // namespace mojo |
| OLD | NEW |