Chromium Code Reviews| Index: net/socket_stream/socket_stream_unittest.cc |
| diff --git a/net/socket_stream/socket_stream_unittest.cc b/net/socket_stream/socket_stream_unittest.cc |
| index b0734fc5fb5b0bd7d98e04fca93560e40458993e..9014066e784aa86b5fa78eb0b52bad47f4113adf 100644 |
| --- a/net/socket_stream/socket_stream_unittest.cc |
| +++ b/net/socket_stream/socket_stream_unittest.cc |
| @@ -181,6 +181,53 @@ class SocketStreamEventRecorder : public SocketStream::Delegate { |
| DISALLOW_COPY_AND_ASSIGN(SocketStreamEventRecorder); |
| }; |
| +// This is used for the test OnErrorDetachDelegate. |
| +class SelfDeletingDelegate : public SocketStream::Delegate { |
| + public: |
| + explicit SelfDeletingDelegate(scoped_ptr<SelfDeletingDelegate>* self, |
| + const CompletionCallback& callback) |
|
tyoshino (SeeGerritForStatus)
2013/05/27 05:55:36
two arg constructor. it's ok but you don't to spec
Adam Rice
2013/05/27 07:16:33
I changed it to a one arg constructor.
|
| + : self_(self), socket_stream_(), callback_(callback) {} |
| + |
| + virtual ~SelfDeletingDelegate() {} |
| + |
| + // Call DetachDelegate() and then delete |this|. The callback is called first, |
| + // to provide a way for the test to complete (the test won't complete |
| + // synchronously, it will return to the message loop first). |
| + virtual void OnError(const SocketStream* socket, int error) OVERRIDE { |
| + callback_.Run(error); |
|
tyoshino (SeeGerritForStatus)
2013/05/27 05:55:36
let's copy callback_ and run at the end of this me
Adam Rice
2013/05/27 07:16:33
Done.
|
| + socket_stream_->DetachDelegate(); |
| + CHECK_EQ(self_->get(), this); |
|
tyoshino (SeeGerritForStatus)
2013/05/27 05:55:36
this should go to the constructor?
basically we d
Adam Rice
2013/05/27 07:16:33
I used a CHECK here because I was verifying that t
tyoshino (SeeGerritForStatus)
2013/05/27 08:09:13
Great!
|
| + self_->reset(); |
| + } |
| + |
| + // This can't be passed in the constructor because this object needs to be |
| + // created before SocketStream. |
| + void set_socket_stream(const scoped_refptr<SocketStream>& socket_stream) { |
| + socket_stream_ = socket_stream; |
| + CHECK_EQ(socket_stream_->delegate(), this); |
|
tyoshino (SeeGerritForStatus)
2013/05/27 05:55:36
ditto
Adam Rice
2013/05/27 07:16:33
Done.
|
| + } |
| + |
| + virtual void OnConnected(SocketStream* socket, int max_pending_send_allowed) |
| + OVERRIDE { |
| + NOTREACHED(); |
|
tyoshino (SeeGerritForStatus)
2013/05/27 05:55:36
ditto. if you can't use ADD_FAILURE, use CHECK ins
Adam Rice
2013/05/27 07:16:33
Done.
|
| + } |
| + virtual void OnSentData(SocketStream* socket, int amount_sent) OVERRIDE { |
| + NOTREACHED(); |
|
tyoshino (SeeGerritForStatus)
2013/05/27 05:55:36
ditto
Adam Rice
2013/05/27 07:16:33
Done.
|
| + } |
| + virtual void OnReceivedData(SocketStream* socket, const char* data, int len) |
| + OVERRIDE { |
| + NOTREACHED(); |
|
tyoshino (SeeGerritForStatus)
2013/05/27 05:55:36
ditto
Adam Rice
2013/05/27 07:16:33
Done.
|
| + } |
| + virtual void OnClose(SocketStream* socket) OVERRIDE { NOTREACHED(); } |
|
tyoshino (SeeGerritForStatus)
2013/05/27 05:55:36
ditto
Adam Rice
2013/05/27 07:16:33
Done.
|
| + |
| + private: |
| + scoped_ptr<SelfDeletingDelegate>* const self_; |
| + scoped_refptr<SocketStream> socket_stream_; |
| + const CompletionCallback callback_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(SelfDeletingDelegate); |
| +}; |
| + |
| class TestURLRequestContextWithProxy : public TestURLRequestContext { |
| public: |
| explicit TestURLRequestContextWithProxy(const std::string& proxy) |
| @@ -846,4 +893,30 @@ TEST_F(SocketStreamTest, BeforeConnectFailed) { |
| EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[1].event_type); |
| } |
| +// Check that a connect failure, followed by the delegate calling DetachDelegate |
| +// and deleting itself in the OnError callback, is handled correctly. |
| +TEST_F(SocketStreamTest, OnErrorDetachDelegate) { |
| + MockClientSocketFactory mock_socket_factory; |
| + TestCompletionCallback test_callback; |
| + |
| + scoped_ptr<SelfDeletingDelegate> delegate; |
| + delegate.reset(new SelfDeletingDelegate(&delegate, test_callback.callback())); |
| + MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); |
| + StaticSocketDataProvider data; |
| + data.set_connect_data(mock_connect); |
| + mock_socket_factory.AddSocketDataProvider(&data); |
| + |
| + TestURLRequestContext context; |
| + scoped_refptr<SocketStream> socket_stream( |
| + new SocketStream(GURL("ws://localhost:9998/echo"), delegate.get())); |
| + socket_stream->set_context(&context); |
| + socket_stream->SetClientSocketFactory(&mock_socket_factory); |
| + delegate->set_socket_stream(socket_stream); |
| + |
| + socket_stream->Connect(); |
| + |
| + test_callback.WaitForResult(); |
| + EXPECT_TRUE(!delegate); |
| +} |
| + |
| } // namespace net |