Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "ipc/mojo/ipc_channel_mojo.h" | 5 #include "ipc/mojo/ipc_channel_mojo.h" |
| 6 | 6 |
| 7 #include "base/base_paths.h" | 7 #include "base/base_paths.h" |
| 8 #include "base/files/file.h" | 8 #include "base/files/file.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| 11 #include "base/pickle.h" | 11 #include "base/pickle.h" |
| 12 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
| 13 #include "ipc/ipc_message.h" | 13 #include "ipc/ipc_message.h" |
| 14 #include "ipc/ipc_test_base.h" | 14 #include "ipc/ipc_test_base.h" |
| 15 #include "ipc/ipc_test_channel_listener.h" | 15 #include "ipc/ipc_test_channel_listener.h" |
| 16 #include "ipc/mojo/ipc_channel_mojo_readers.h" | |
| 16 | 17 |
| 17 #if defined(OS_POSIX) | 18 #if defined(OS_POSIX) |
| 18 #include "base/file_descriptor_posix.h" | 19 #include "base/file_descriptor_posix.h" |
| 19 #endif | 20 #endif |
| 20 | 21 |
| 21 namespace { | 22 namespace { |
| 22 | 23 |
| 23 class ListenerThatExpectsOK : public IPC::Listener { | 24 class ListenerThatExpectsOK : public IPC::Listener { |
| 24 public: | 25 public: |
| 25 ListenerThatExpectsOK() | 26 ListenerThatExpectsOK() |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 | 139 |
| 139 IPC::TestChannelListener::SendOneMessage( | 140 IPC::TestChannelListener::SendOneMessage( |
| 140 client.channel(), "hello from child"); | 141 client.channel(), "hello from child"); |
| 141 base::MessageLoop::current()->Run(); | 142 base::MessageLoop::current()->Run(); |
| 142 EXPECT_TRUE(listener.is_connected_called()); | 143 EXPECT_TRUE(listener.is_connected_called()); |
| 143 EXPECT_TRUE(listener.HasSentAll()); | 144 EXPECT_TRUE(listener.HasSentAll()); |
| 144 | 145 |
| 145 return 0; | 146 return 0; |
| 146 } | 147 } |
| 147 | 148 |
| 149 | |
| 150 // To make WriteMessageToPipe() fail. | |
| 151 class ErraticMessageReader : public IPC::internal::MessageReader { | |
| 152 public: | |
| 153 ErraticMessageReader(mojo::ScopedMessagePipeHandle pipe, | |
| 154 IPC::ChannelMojo* owner) | |
| 155 : IPC::internal::MessageReader(pipe.Pass(), owner) { | |
| 156 } | |
| 157 | |
| 158 virtual MojoResult WriteMessageToPipe( | |
| 159 const void* bytes, | |
| 160 uint32_t num_bytes, | |
| 161 const MojoHandle* handles, | |
| 162 uint32_t num_handles, | |
| 163 MojoWriteMessageFlags flags) OVERRIDE { | |
| 164 return MOJO_RESULT_UNKNOWN; | |
| 165 } | |
| 166 | |
|
yzshen1
2014/09/15 17:26:08
unnecessary empty line
Hajime Morrita
2014/09/15 18:16:53
Done.
| |
| 167 }; | |
| 168 | |
| 169 // Exists to create ErraticMessageReader | |
|
yzshen1
2014/09/15 17:26:08
nit: trailing '.', please. (and line 188, 259)
Hajime Morrita
2014/09/15 18:16:53
Done.
| |
| 170 class ErraticChannelMojo : public IPC::ChannelMojo { | |
| 171 public: | |
| 172 ErraticChannelMojo( | |
| 173 const IPC::ChannelHandle &channel_handle, | |
| 174 IPC::Channel::Mode mode, | |
| 175 IPC::Listener* listener, | |
| 176 scoped_refptr<base::TaskRunner> runner) | |
| 177 : ChannelMojo(channel_handle, mode, listener, runner) { | |
| 178 } | |
| 179 | |
| 180 virtual scoped_ptr<IPC::internal::MessageReader> CreateMessageReader( | |
| 181 mojo::ScopedMessagePipeHandle pipe) OVERRIDE { | |
| 182 return scoped_ptr<IPC::internal::MessageReader>( | |
| 183 new ErraticMessageReader(pipe.Pass(), this)); | |
| 184 } | |
| 185 | |
| 186 }; | |
| 187 | |
| 188 // Exists to create ErraticChannelMojo | |
| 189 class ErraticChannelFactory : public IPC::ChannelFactory { | |
| 190 public: | |
| 191 explicit ErraticChannelFactory( | |
| 192 const IPC::ChannelHandle& handle, | |
| 193 base::TaskRunner* runner) | |
| 194 : handle_(handle), runner_(runner) { | |
| 195 } | |
| 196 | |
| 197 virtual std::string GetName() const OVERRIDE { | |
| 198 return ""; | |
| 199 } | |
| 200 | |
| 201 virtual scoped_ptr<IPC::Channel> BuildChannel( | |
| 202 IPC::Listener* listener) OVERRIDE { | |
| 203 return scoped_ptr<IPC::Channel>( | |
| 204 new ErraticChannelMojo( | |
| 205 handle_, IPC::Channel::MODE_SERVER, listener, runner_)); | |
| 206 } | |
| 207 | |
| 208 private: | |
| 209 IPC::ChannelHandle handle_; | |
| 210 scoped_refptr<base::TaskRunner> runner_; | |
| 211 }; | |
| 212 | |
| 213 class ListenerExpectingErrors : public IPC::Listener { | |
| 214 public: | |
| 215 ListenerExpectingErrors() | |
| 216 : has_error_(false) { | |
| 217 } | |
| 218 | |
| 219 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | |
| 220 return true; | |
| 221 } | |
| 222 | |
| 223 virtual void OnChannelError() OVERRIDE { | |
| 224 has_error_ = true; | |
| 225 base::MessageLoop::current()->Quit(); | |
| 226 } | |
| 227 | |
| 228 bool has_error() const { return has_error_; } | |
| 229 | |
| 230 private: | |
| 231 bool has_error_; | |
| 232 }; | |
| 233 | |
| 234 | |
| 235 class IPCChannelMojoErrorTest : public IPCTestBase { | |
| 236 protected: | |
| 237 virtual scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( | |
| 238 const IPC::ChannelHandle& handle, | |
| 239 base::TaskRunner* runner) OVERRIDE { | |
| 240 return scoped_ptr<IPC::ChannelFactory>( | |
| 241 new ErraticChannelFactory(handle, runner)); | |
| 242 } | |
| 243 }; | |
| 244 | |
| 245 class ListenerThatQuits : public IPC::Listener { | |
| 246 public: | |
| 247 ListenerThatQuits() { | |
| 248 } | |
| 249 | |
| 250 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | |
| 251 return true; | |
| 252 } | |
| 253 | |
| 254 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE { | |
| 255 base::MessageLoop::current()->Quit(); | |
| 256 } | |
| 257 }; | |
| 258 | |
| 259 // A long running process that connects to us | |
| 260 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoErraticTestClient) { | |
| 261 ListenerThatQuits listener; | |
| 262 ChannelClient client(&listener, "IPCChannelMojoErraticTestClient"); | |
| 263 client.Connect(); | |
| 264 | |
| 265 base::MessageLoop::current()->Run(); | |
| 266 | |
| 267 return 0; | |
| 268 } | |
| 269 | |
| 270 TEST_F(IPCChannelMojoErrorTest, SendFailWithPendingMessages) { | |
| 271 Init("IPCChannelMojoErraticTestClient"); | |
| 272 | |
| 273 // Set up IPC channel and start client. | |
| 274 ListenerExpectingErrors listener; | |
| 275 CreateChannel(&listener); | |
| 276 ASSERT_TRUE(ConnectChannel()); | |
| 277 | |
| 278 // This messages are queued as pending. | |
|
yzshen1
2014/09/15 17:26:07
This -> These
| |
| 279 for (size_t i = 0; i < 2; ++i) { | |
| 280 IPC::TestChannelListener::SendOneMessage( | |
| 281 sender(), "hello from parent"); | |
| 282 } | |
| 283 | |
| 284 // This triggers ChannelMojo::OnConnected(), which hits | |
| 285 // crbug.com/410813 | |
| 286 ASSERT_TRUE(StartClient()); | |
| 287 base::MessageLoop::current()->Run(); | |
| 288 | |
| 289 this->channel()->Close(); | |
| 290 | |
| 291 EXPECT_TRUE(WaitForClientShutdown()); | |
| 292 EXPECT_TRUE(listener.has_error()); | |
| 293 | |
| 294 DestroyChannel(); | |
| 295 } | |
| 296 | |
| 297 | |
| 148 #if defined(OS_POSIX) | 298 #if defined(OS_POSIX) |
| 149 class ListenerThatExpectsFile : public IPC::Listener { | 299 class ListenerThatExpectsFile : public IPC::Listener { |
| 150 public: | 300 public: |
| 151 ListenerThatExpectsFile() | 301 ListenerThatExpectsFile() |
| 152 : sender_(NULL) {} | 302 : sender_(NULL) {} |
| 153 | 303 |
| 154 virtual ~ListenerThatExpectsFile() {} | 304 virtual ~ListenerThatExpectsFile() {} |
| 155 | 305 |
| 156 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | 306 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
| 157 PickleIterator iter(message); | 307 PickleIterator iter(message); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 client.Connect(); | 376 client.Connect(); |
| 227 listener.set_sender(client.channel()); | 377 listener.set_sender(client.channel()); |
| 228 | 378 |
| 229 base::MessageLoop::current()->Run(); | 379 base::MessageLoop::current()->Run(); |
| 230 | 380 |
| 231 return 0; | 381 return 0; |
| 232 } | 382 } |
| 233 #endif | 383 #endif |
| 234 | 384 |
| 235 } // namespace | 385 } // namespace |
| OLD | NEW |