Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(793)

Unified Diff: net/socket/ssl_client_socket_unittest.cc

Issue 353713005: Implements new, more robust design for communicating between SSLConnectJobs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updated SSLClientSocket tests & fixed bug in SSLSessionCacheOpenSSL Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 {

Powered by Google App Engine
This is Rietveld 408576698