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 { |