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 // Close given handle before use to simulate an error. |
| 150 class ErraticChannelMojo : public IPC::ChannelMojo { |
| 151 public: |
| 152 ErraticChannelMojo( |
| 153 const IPC::ChannelHandle& channel_handle, |
| 154 IPC::Channel::Mode mode, |
| 155 IPC::Listener* listener, |
| 156 scoped_refptr<base::TaskRunner> runner) |
| 157 : ChannelMojo(channel_handle, mode, listener, runner) { |
| 158 } |
| 159 |
| 160 virtual void OnConnected(mojo::ScopedMessagePipeHandle pipe) { |
| 161 MojoClose(pipe.get().value()); |
| 162 OnConnected(pipe.Pass()); |
| 163 } |
| 164 }; |
| 165 |
| 166 // Exists to create ErraticChannelMojo. |
| 167 class ErraticChannelFactory : public IPC::ChannelFactory { |
| 168 public: |
| 169 explicit ErraticChannelFactory( |
| 170 const IPC::ChannelHandle& handle, |
| 171 base::TaskRunner* runner) |
| 172 : handle_(handle), runner_(runner) { |
| 173 } |
| 174 |
| 175 virtual std::string GetName() const OVERRIDE { |
| 176 return ""; |
| 177 } |
| 178 |
| 179 virtual scoped_ptr<IPC::Channel> BuildChannel( |
| 180 IPC::Listener* listener) OVERRIDE { |
| 181 return scoped_ptr<IPC::Channel>( |
| 182 new ErraticChannelMojo( |
| 183 handle_, IPC::Channel::MODE_SERVER, listener, runner_)); |
| 184 } |
| 185 |
| 186 private: |
| 187 IPC::ChannelHandle handle_; |
| 188 scoped_refptr<base::TaskRunner> runner_; |
| 189 }; |
| 190 |
| 191 class ListenerExpectingErrors : public IPC::Listener { |
| 192 public: |
| 193 ListenerExpectingErrors() |
| 194 : has_error_(false) { |
| 195 } |
| 196 |
| 197 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
| 198 return true; |
| 199 } |
| 200 |
| 201 virtual void OnChannelError() OVERRIDE { |
| 202 has_error_ = true; |
| 203 base::MessageLoop::current()->Quit(); |
| 204 } |
| 205 |
| 206 bool has_error() const { return has_error_; } |
| 207 |
| 208 private: |
| 209 bool has_error_; |
| 210 }; |
| 211 |
| 212 |
| 213 class IPCChannelMojoErrorTest : public IPCTestBase { |
| 214 protected: |
| 215 virtual scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( |
| 216 const IPC::ChannelHandle& handle, |
| 217 base::TaskRunner* runner) OVERRIDE { |
| 218 return scoped_ptr<IPC::ChannelFactory>( |
| 219 new ErraticChannelFactory(handle, runner)); |
| 220 } |
| 221 }; |
| 222 |
| 223 class ListenerThatQuits : public IPC::Listener { |
| 224 public: |
| 225 ListenerThatQuits() { |
| 226 } |
| 227 |
| 228 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
| 229 return true; |
| 230 } |
| 231 |
| 232 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE { |
| 233 base::MessageLoop::current()->Quit(); |
| 234 } |
| 235 }; |
| 236 |
| 237 // A long running process that connects to us. |
| 238 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoErraticTestClient) { |
| 239 ListenerThatQuits listener; |
| 240 ChannelClient client(&listener, "IPCChannelMojoErraticTestClient"); |
| 241 client.Connect(); |
| 242 |
| 243 base::MessageLoop::current()->Run(); |
| 244 |
| 245 return 0; |
| 246 } |
| 247 |
| 248 TEST_F(IPCChannelMojoErrorTest, SendFailWithPendingMessages) { |
| 249 Init("IPCChannelMojoErraticTestClient"); |
| 250 |
| 251 // Set up IPC channel and start client. |
| 252 ListenerExpectingErrors listener; |
| 253 CreateChannel(&listener); |
| 254 ASSERT_TRUE(ConnectChannel()); |
| 255 |
| 256 // This messages are queued as pending. |
| 257 for (size_t i = 0; i < 2; ++i) { |
| 258 IPC::TestChannelListener::SendOneMessage( |
| 259 sender(), "hello from parent"); |
| 260 } |
| 261 |
| 262 ASSERT_TRUE(StartClient()); |
| 263 base::MessageLoop::current()->Run(); |
| 264 |
| 265 this->channel()->Close(); |
| 266 |
| 267 EXPECT_TRUE(WaitForClientShutdown()); |
| 268 EXPECT_TRUE(listener.has_error()); |
| 269 |
| 270 DestroyChannel(); |
| 271 } |
| 272 |
| 273 |
148 #if defined(OS_POSIX) | 274 #if defined(OS_POSIX) |
149 class ListenerThatExpectsFile : public IPC::Listener { | 275 class ListenerThatExpectsFile : public IPC::Listener { |
150 public: | 276 public: |
151 ListenerThatExpectsFile() | 277 ListenerThatExpectsFile() |
152 : sender_(NULL) {} | 278 : sender_(NULL) {} |
153 | 279 |
154 virtual ~ListenerThatExpectsFile() {} | 280 virtual ~ListenerThatExpectsFile() {} |
155 | 281 |
156 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | 282 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
157 PickleIterator iter(message); | 283 PickleIterator iter(message); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 client.Connect(); | 352 client.Connect(); |
227 listener.set_sender(client.channel()); | 353 listener.set_sender(client.channel()); |
228 | 354 |
229 base::MessageLoop::current()->Run(); | 355 base::MessageLoop::current()->Run(); |
230 | 356 |
231 return 0; | 357 return 0; |
232 } | 358 } |
233 #endif | 359 #endif |
234 | 360 |
235 } // namespace | 361 } // namespace |
OLD | NEW |