Chromium Code Reviews| Index: net/socket/ssl_client_socket_unittest.cc |
| diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc |
| index 2639870e81f36f4fefef5ad4626ced9bc629da13..63dac3eb608120e467bf8ee7ccaa7e6ccc3c12e6 100644 |
| --- a/net/socket/ssl_client_socket_unittest.cc |
| +++ b/net/socket/ssl_client_socket_unittest.cc |
| @@ -25,6 +25,7 @@ |
| #include "net/ssl/default_server_bound_cert_store.h" |
| #include "net/ssl/ssl_cert_request_info.h" |
| #include "net/ssl/ssl_config_service.h" |
| +#include "net/socket/ssl_client_socket_test_util.cc" |
|
wtc
2014/07/31 02:02:25
Delete this line.
mshelley
2014/07/31 20:11:37
Done.
|
| #include "net/test/cert_test_util.h" |
| #include "net/test/spawned_test_server/spawned_test_server.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| @@ -35,500 +36,8 @@ |
| namespace net { |
| namespace { |
| - |
|
wtc
2014/07/31 02:02:25
Add back this blank line.
|
| const SSLConfig kDefaultSSLConfig; |
| -// WrappedStreamSocket is a base class that wraps an existing StreamSocket, |
|
wtc
2014/07/31 02:02:25
If this big chunk of code is dead code, please del
|
| -// forwarding the Socket and StreamSocket interfaces to the underlying |
| -// transport. |
| -// This is to provide a common base class for subclasses to override specific |
| -// StreamSocket methods for testing, while still communicating with a 'real' |
| -// StreamSocket. |
| -class WrappedStreamSocket : public StreamSocket { |
| - public: |
| - explicit WrappedStreamSocket(scoped_ptr<StreamSocket> transport) |
| - : transport_(transport.Pass()) {} |
| - virtual ~WrappedStreamSocket() {} |
| - |
| - // StreamSocket implementation: |
| - virtual int Connect(const CompletionCallback& callback) OVERRIDE { |
| - return transport_->Connect(callback); |
| - } |
| - virtual void Disconnect() OVERRIDE { transport_->Disconnect(); } |
| - virtual bool IsConnected() const OVERRIDE { |
| - return transport_->IsConnected(); |
| - } |
| - virtual bool IsConnectedAndIdle() const OVERRIDE { |
| - return transport_->IsConnectedAndIdle(); |
| - } |
| - virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE { |
| - return transport_->GetPeerAddress(address); |
| - } |
| - virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE { |
| - return transport_->GetLocalAddress(address); |
| - } |
| - virtual const BoundNetLog& NetLog() const OVERRIDE { |
| - return transport_->NetLog(); |
| - } |
| - virtual void SetSubresourceSpeculation() OVERRIDE { |
| - transport_->SetSubresourceSpeculation(); |
| - } |
| - virtual void SetOmniboxSpeculation() OVERRIDE { |
| - transport_->SetOmniboxSpeculation(); |
| - } |
| - virtual bool WasEverUsed() const OVERRIDE { |
| - return transport_->WasEverUsed(); |
| - } |
| - virtual bool UsingTCPFastOpen() const OVERRIDE { |
| - return transport_->UsingTCPFastOpen(); |
| - } |
| - virtual bool WasNpnNegotiated() const OVERRIDE { |
| - return transport_->WasNpnNegotiated(); |
| - } |
| - virtual NextProto GetNegotiatedProtocol() const OVERRIDE { |
| - return transport_->GetNegotiatedProtocol(); |
| - } |
| - virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE { |
| - return transport_->GetSSLInfo(ssl_info); |
| - } |
| - |
| - // Socket implementation: |
| - virtual int Read(IOBuffer* buf, |
| - int buf_len, |
| - const CompletionCallback& callback) OVERRIDE { |
| - return transport_->Read(buf, buf_len, callback); |
| - } |
| - virtual int Write(IOBuffer* buf, |
| - int buf_len, |
| - const CompletionCallback& callback) OVERRIDE { |
| - return transport_->Write(buf, buf_len, callback); |
| - } |
| - virtual int SetReceiveBufferSize(int32 size) OVERRIDE { |
| - return transport_->SetReceiveBufferSize(size); |
| - } |
| - virtual int SetSendBufferSize(int32 size) OVERRIDE { |
| - return transport_->SetSendBufferSize(size); |
| - } |
| - |
| - protected: |
| - scoped_ptr<StreamSocket> transport_; |
| -}; |
| - |
| -// ReadBufferingStreamSocket is a wrapper for an existing StreamSocket that |
| -// will ensure a certain amount of data is internally buffered before |
| -// satisfying a Read() request. It exists to mimic OS-level internal |
| -// buffering, but in a way to guarantee that X number of bytes will be |
| -// returned to callers of Read(), regardless of how quickly the OS receives |
| -// them from the TestServer. |
| -class ReadBufferingStreamSocket : public WrappedStreamSocket { |
| - public: |
| - explicit ReadBufferingStreamSocket(scoped_ptr<StreamSocket> transport); |
| - virtual ~ReadBufferingStreamSocket() {} |
| - |
| - // Socket implementation: |
| - virtual int Read(IOBuffer* buf, |
| - int buf_len, |
| - const CompletionCallback& callback) OVERRIDE; |
| - |
| - // Sets the internal buffer to |size|. This must not be greater than |
| - // the largest value supplied to Read() - that is, it does not handle |
| - // having "leftovers" at the end of Read(). |
| - // Each call to Read() will be prevented from completion until at least |
| - // |size| data has been read. |
| - // Set to 0 to turn off buffering, causing Read() to transparently |
| - // read via the underlying transport. |
| - void SetBufferSize(int size); |
| - |
| - private: |
| - enum State { |
| - STATE_NONE, |
| - STATE_READ, |
| - STATE_READ_COMPLETE, |
| - }; |
| - |
| - int DoLoop(int result); |
| - int DoRead(); |
| - int DoReadComplete(int result); |
| - void OnReadCompleted(int result); |
| - |
| - State state_; |
| - scoped_refptr<GrowableIOBuffer> read_buffer_; |
| - int buffer_size_; |
| - |
| - scoped_refptr<IOBuffer> user_read_buf_; |
| - CompletionCallback user_read_callback_; |
| -}; |
| - |
| -ReadBufferingStreamSocket::ReadBufferingStreamSocket( |
| - scoped_ptr<StreamSocket> transport) |
| - : WrappedStreamSocket(transport.Pass()), |
| - read_buffer_(new GrowableIOBuffer()), |
| - buffer_size_(0) {} |
| - |
| -void ReadBufferingStreamSocket::SetBufferSize(int size) { |
| - DCHECK(!user_read_buf_.get()); |
| - buffer_size_ = size; |
| - read_buffer_->SetCapacity(size); |
| -} |
| - |
| -int ReadBufferingStreamSocket::Read(IOBuffer* buf, |
| - int buf_len, |
| - const CompletionCallback& callback) { |
| - if (buffer_size_ == 0) |
| - return transport_->Read(buf, buf_len, callback); |
| - |
| - if (buf_len < buffer_size_) |
| - return ERR_UNEXPECTED; |
| - |
| - state_ = STATE_READ; |
| - user_read_buf_ = buf; |
| - int result = DoLoop(OK); |
| - if (result == ERR_IO_PENDING) |
| - user_read_callback_ = callback; |
| - else |
| - user_read_buf_ = NULL; |
| - return result; |
| -} |
| - |
| -int ReadBufferingStreamSocket::DoLoop(int result) { |
| - int rv = result; |
| - do { |
| - State current_state = state_; |
| - state_ = STATE_NONE; |
| - switch (current_state) { |
| - case STATE_READ: |
| - rv = DoRead(); |
| - break; |
| - case STATE_READ_COMPLETE: |
| - rv = DoReadComplete(rv); |
| - break; |
| - case STATE_NONE: |
| - default: |
| - NOTREACHED() << "Unexpected state: " << current_state; |
| - rv = ERR_UNEXPECTED; |
| - break; |
| - } |
| - } while (rv != ERR_IO_PENDING && state_ != STATE_NONE); |
| - return rv; |
| -} |
| - |
| -int ReadBufferingStreamSocket::DoRead() { |
| - state_ = STATE_READ_COMPLETE; |
| - int rv = |
| - transport_->Read(read_buffer_.get(), |
| - read_buffer_->RemainingCapacity(), |
| - base::Bind(&ReadBufferingStreamSocket::OnReadCompleted, |
| - base::Unretained(this))); |
| - return rv; |
| -} |
| - |
| -int ReadBufferingStreamSocket::DoReadComplete(int result) { |
| - state_ = STATE_NONE; |
| - if (result <= 0) |
| - return result; |
| - |
| - read_buffer_->set_offset(read_buffer_->offset() + result); |
| - if (read_buffer_->RemainingCapacity() > 0) { |
| - state_ = STATE_READ; |
| - return OK; |
| - } |
| - |
| - memcpy(user_read_buf_->data(), |
| - read_buffer_->StartOfBuffer(), |
| - read_buffer_->capacity()); |
| - read_buffer_->set_offset(0); |
| - return read_buffer_->capacity(); |
| -} |
| - |
| -void ReadBufferingStreamSocket::OnReadCompleted(int result) { |
| - result = DoLoop(result); |
| - if (result == ERR_IO_PENDING) |
| - return; |
| - |
| - user_read_buf_ = NULL; |
| - base::ResetAndReturn(&user_read_callback_).Run(result); |
| -} |
| - |
| -// Simulates synchronously receiving an error during Read() or Write() |
| -class SynchronousErrorStreamSocket : public WrappedStreamSocket { |
| - public: |
| - explicit SynchronousErrorStreamSocket(scoped_ptr<StreamSocket> transport); |
| - virtual ~SynchronousErrorStreamSocket() {} |
| - |
| - // Socket implementation: |
| - virtual int Read(IOBuffer* buf, |
| - int buf_len, |
| - const CompletionCallback& callback) OVERRIDE; |
| - virtual int Write(IOBuffer* buf, |
| - int buf_len, |
| - const CompletionCallback& callback) OVERRIDE; |
| - |
| - // Sets the next Read() call and all future calls to return |error|. |
| - // If there is already a pending asynchronous read, the configured error |
| - // will not be returned until that asynchronous read has completed and Read() |
| - // is called again. |
| - void SetNextReadError(Error error) { |
| - DCHECK_GE(0, error); |
| - have_read_error_ = true; |
| - pending_read_error_ = error; |
| - } |
| - |
| - // Sets the next Write() call and all future calls to return |error|. |
| - // If there is already a pending asynchronous write, the configured error |
| - // will not be returned until that asynchronous write has completed and |
| - // Write() is called again. |
| - void SetNextWriteError(Error error) { |
| - DCHECK_GE(0, error); |
| - have_write_error_ = true; |
| - pending_write_error_ = error; |
| - } |
| - |
| - private: |
| - bool have_read_error_; |
| - int pending_read_error_; |
| - |
| - bool have_write_error_; |
| - int pending_write_error_; |
| - |
| - DISALLOW_COPY_AND_ASSIGN(SynchronousErrorStreamSocket); |
| -}; |
| - |
| -SynchronousErrorStreamSocket::SynchronousErrorStreamSocket( |
| - scoped_ptr<StreamSocket> transport) |
| - : WrappedStreamSocket(transport.Pass()), |
| - have_read_error_(false), |
| - pending_read_error_(OK), |
| - have_write_error_(false), |
| - pending_write_error_(OK) {} |
| - |
| -int SynchronousErrorStreamSocket::Read(IOBuffer* buf, |
| - int buf_len, |
| - const CompletionCallback& callback) { |
| - if (have_read_error_) |
| - return pending_read_error_; |
| - return transport_->Read(buf, buf_len, callback); |
| -} |
| - |
| -int SynchronousErrorStreamSocket::Write(IOBuffer* buf, |
| - int buf_len, |
| - const CompletionCallback& callback) { |
| - if (have_write_error_) |
| - return pending_write_error_; |
| - return transport_->Write(buf, buf_len, callback); |
| -} |
| - |
| -// FakeBlockingStreamSocket wraps an existing StreamSocket and simulates the |
| -// underlying transport needing to complete things asynchronously in a |
| -// deterministic manner (e.g.: independent of the TestServer and the OS's |
| -// semantics). |
| -class FakeBlockingStreamSocket : public WrappedStreamSocket { |
| - public: |
| - explicit FakeBlockingStreamSocket(scoped_ptr<StreamSocket> transport); |
| - virtual ~FakeBlockingStreamSocket() {} |
| - |
| - // Socket implementation: |
| - virtual int Read(IOBuffer* buf, |
| - int buf_len, |
| - const CompletionCallback& callback) OVERRIDE; |
| - virtual int Write(IOBuffer* buf, |
| - int buf_len, |
| - const CompletionCallback& callback) OVERRIDE; |
| - |
| - // Blocks read results on the socket. Reads will not complete until |
| - // UnblockReadResult() has been called and a result is ready from the |
| - // underlying transport. Note: if BlockReadResult() is called while there is a |
| - // hanging asynchronous Read(), that Read is blocked. |
| - void BlockReadResult(); |
| - void UnblockReadResult(); |
| - |
| - // Waits for the blocked Read() call to be complete at the underlying |
| - // transport. |
| - void WaitForReadResult(); |
| - |
| - // Causes the next call to Write() to return ERR_IO_PENDING, not beginning the |
| - // underlying transport until UnblockWrite() has been called. Note: if there |
| - // is a pending asynchronous write, it is NOT blocked. For purposes of |
| - // blocking writes, data is considered to have reached the underlying |
| - // transport as soon as Write() is called. |
| - void BlockWrite(); |
| - void UnblockWrite(); |
| - |
| - // Waits for the blocked Write() call to be scheduled. |
| - void WaitForWrite(); |
| - |
| - private: |
| - // Handles completion from the underlying transport read. |
| - void OnReadCompleted(int result); |
| - |
| - // True if read callbacks are blocked. |
| - bool should_block_read_; |
| - |
| - // The user callback for the pending read call. |
| - CompletionCallback pending_read_callback_; |
| - |
| - // The result for the blocked read callback, or ERR_IO_PENDING if not |
| - // completed. |
| - int pending_read_result_; |
| - |
| - // WaitForReadResult() wait loop. |
| - scoped_ptr<base::RunLoop> read_loop_; |
| - |
| - // True if write calls are blocked. |
| - bool should_block_write_; |
| - |
| - // The buffer for the pending write, or NULL if not scheduled. |
| - scoped_refptr<IOBuffer> pending_write_buf_; |
| - |
| - // The callback for the pending write call. |
| - CompletionCallback pending_write_callback_; |
| - |
| - // The length for the pending write, or -1 if not scheduled. |
| - int pending_write_len_; |
| - |
| - // WaitForWrite() wait loop. |
| - scoped_ptr<base::RunLoop> write_loop_; |
| -}; |
| - |
| -FakeBlockingStreamSocket::FakeBlockingStreamSocket( |
| - scoped_ptr<StreamSocket> transport) |
| - : WrappedStreamSocket(transport.Pass()), |
| - should_block_read_(false), |
| - pending_read_result_(ERR_IO_PENDING), |
| - should_block_write_(false), |
| - pending_write_len_(-1) {} |
| - |
| -int FakeBlockingStreamSocket::Read(IOBuffer* buf, |
| - int len, |
| - const CompletionCallback& callback) { |
| - DCHECK(pending_read_callback_.is_null()); |
| - DCHECK_EQ(ERR_IO_PENDING, pending_read_result_); |
| - DCHECK(!callback.is_null()); |
| - |
| - int rv = transport_->Read(buf, len, base::Bind( |
| - &FakeBlockingStreamSocket::OnReadCompleted, base::Unretained(this))); |
| - if (rv == ERR_IO_PENDING) { |
| - // Save the callback to be called later. |
| - pending_read_callback_ = callback; |
| - } else if (should_block_read_) { |
| - // Save the callback and read result to be called later. |
| - pending_read_callback_ = callback; |
| - OnReadCompleted(rv); |
| - rv = ERR_IO_PENDING; |
| - } |
| - return rv; |
| -} |
| - |
| -int FakeBlockingStreamSocket::Write(IOBuffer* buf, |
| - int len, |
| - const CompletionCallback& callback) { |
| - DCHECK(buf); |
| - DCHECK_LE(0, len); |
| - |
| - if (!should_block_write_) |
| - return transport_->Write(buf, len, callback); |
| - |
| - // Schedule the write, but do nothing. |
| - DCHECK(!pending_write_buf_); |
| - DCHECK_EQ(-1, pending_write_len_); |
| - DCHECK(pending_write_callback_.is_null()); |
| - DCHECK(!callback.is_null()); |
| - pending_write_buf_ = buf; |
| - pending_write_len_ = len; |
| - pending_write_callback_ = callback; |
| - |
| - // Stop the write loop, if any. |
| - if (write_loop_) |
| - write_loop_->Quit(); |
| - return ERR_IO_PENDING; |
| -} |
| - |
| -void FakeBlockingStreamSocket::BlockReadResult() { |
| - DCHECK(!should_block_read_); |
| - should_block_read_ = true; |
| -} |
| - |
| -void FakeBlockingStreamSocket::UnblockReadResult() { |
| - DCHECK(should_block_read_); |
| - should_block_read_ = false; |
| - |
| - // If the operation is still pending in the underlying transport, immediately |
| - // return - OnReadCompleted() will handle invoking the callback once the |
| - // transport has completed. |
| - if (pending_read_result_ == ERR_IO_PENDING) |
| - return; |
| - int result = pending_read_result_; |
| - pending_read_result_ = ERR_IO_PENDING; |
| - base::ResetAndReturn(&pending_read_callback_).Run(result); |
| -} |
| - |
| -void FakeBlockingStreamSocket::WaitForReadResult() { |
| - DCHECK(should_block_read_); |
| - DCHECK(!read_loop_); |
| - |
| - if (pending_read_result_ != ERR_IO_PENDING) |
| - return; |
| - read_loop_.reset(new base::RunLoop); |
| - read_loop_->Run(); |
| - read_loop_.reset(); |
| - DCHECK_NE(ERR_IO_PENDING, pending_read_result_); |
| -} |
| - |
| -void FakeBlockingStreamSocket::BlockWrite() { |
| - DCHECK(!should_block_write_); |
| - should_block_write_ = true; |
| -} |
| - |
| -void FakeBlockingStreamSocket::UnblockWrite() { |
| - DCHECK(should_block_write_); |
| - should_block_write_ = false; |
| - |
| - // Do nothing if UnblockWrite() was called after BlockWrite(), |
| - // without a Write() in between. |
| - if (!pending_write_buf_) |
| - return; |
| - |
| - int rv = transport_->Write(pending_write_buf_, pending_write_len_, |
| - pending_write_callback_); |
| - pending_write_buf_ = NULL; |
| - pending_write_len_ = -1; |
| - if (rv == ERR_IO_PENDING) { |
| - pending_write_callback_.Reset(); |
| - } else { |
| - base::ResetAndReturn(&pending_write_callback_).Run(rv); |
| - } |
| -} |
| - |
| -void FakeBlockingStreamSocket::WaitForWrite() { |
| - DCHECK(should_block_write_); |
| - DCHECK(!write_loop_); |
| - |
| - if (pending_write_buf_) |
| - return; |
| - write_loop_.reset(new base::RunLoop); |
| - write_loop_->Run(); |
| - write_loop_.reset(); |
| - DCHECK(pending_write_buf_); |
| -} |
| - |
| -void FakeBlockingStreamSocket::OnReadCompleted(int result) { |
| - DCHECK_EQ(ERR_IO_PENDING, pending_read_result_); |
| - DCHECK(!pending_read_callback_.is_null()); |
| - |
| - if (should_block_read_) { |
| - // Store the result so that the callback can be invoked once Unblock() is |
| - // called. |
| - pending_read_result_ = result; |
| - |
| - // Stop the WaitForReadResult() call if any. |
| - if (read_loop_) |
| - read_loop_->Quit(); |
| - } else { |
| - // Either the Read() was never blocked or UnblockReadResult() was called |
| - // before the Read() completed. Either way, run the callback. |
| - base::ResetAndReturn(&pending_read_callback_).Run(result); |
| - } |
| -} |
| - |
| // CompletionCallback that will delete the associated StreamSocket when |
| // the callback is invoked. |
| class DeleteSocketCallback : public TestCompletionCallbackBase { |