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 3b1f266032ea7d1307b8ac91dd57d57f54df8365..626a9fe94ec758bc39bf2e9d22c0e435cf7ce078 100644 |
--- a/net/socket/ssl_client_socket_unittest.cc |
+++ b/net/socket/ssl_client_socket_unittest.cc |
@@ -6,6 +6,7 @@ |
#include <errno.h> |
#include <string.h> |
+#include <algorithm> |
davidben
2017/03/02 20:47:03
Nit: Swap this and the blank line below.
xunjieli
2017/03/02 22:30:20
Done.
|
#include <utility> |
@@ -17,6 +18,8 @@ |
#include "base/message_loop/message_loop.h" |
#include "base/run_loop.h" |
#include "base/single_thread_task_runner.h" |
+#include "base/stl_util.h" |
+#include "base/test/scoped_feature_list.h" |
#include "base/test/scoped_task_scheduler.h" |
#include "base/threading/thread_task_runner_handle.h" |
#include "base/time/time.h" |
@@ -142,6 +145,11 @@ class WrappedStreamSocket : public StreamSocket { |
const CompletionCallback& callback) override { |
return transport_->Read(buf, buf_len, callback); |
} |
+ int ReadIfReady(IOBuffer* buf, |
+ int buf_len, |
+ const CompletionCallback& callback) override { |
+ return transport_->ReadIfReady(buf, buf_len, callback); |
+ } |
int Write(IOBuffer* buf, |
int buf_len, |
const CompletionCallback& callback) override { |
@@ -174,6 +182,10 @@ class ReadBufferingStreamSocket : public WrappedStreamSocket { |
int buf_len, |
const CompletionCallback& callback) override; |
+ int ReadIfReady(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(). |
@@ -210,7 +222,7 @@ ReadBufferingStreamSocket::ReadBufferingStreamSocket( |
buffer_size_(0) {} |
void ReadBufferingStreamSocket::SetBufferSize(int size) { |
- DCHECK(!user_read_buf_.get()); |
+ DCHECK(!user_read_buf_); |
buffer_size_ = size; |
read_buffer_->SetCapacity(size); |
} |
@@ -218,20 +230,36 @@ void ReadBufferingStreamSocket::SetBufferSize(int size) { |
int ReadBufferingStreamSocket::Read(IOBuffer* buf, |
int buf_len, |
const CompletionCallback& callback) { |
+ DCHECK(!user_read_buf_); |
if (buffer_size_ == 0) |
return transport_->Read(buf, buf_len, callback); |
+ int rv = ReadIfReady(buf, buf_len, callback); |
+ if (rv == ERR_IO_PENDING) |
+ user_read_buf_ = buf; |
+ return rv; |
+} |
+ |
+int ReadBufferingStreamSocket::ReadIfReady(IOBuffer* buf, |
+ int buf_len, |
+ const CompletionCallback& callback) { |
+ DCHECK(!user_read_buf_); |
+ if (buffer_size_ == 0) |
+ return transport_->ReadIfReady(buf, buf_len, callback); |
+ |
+ if (read_buffer_->RemainingCapacity() == 0) { |
+ memcpy(buf->data(), read_buffer_->StartOfBuffer(), |
+ read_buffer_->capacity()); |
+ read_buffer_->set_offset(0); |
+ return read_buffer_->capacity(); |
+ } |
if (buf_len < buffer_size_) |
return ERR_UNEXPECTED; |
- |
state_ = STATE_READ; |
- user_read_buf_ = buf; |
- int result = DoLoop(OK); |
- if (result == ERR_IO_PENDING) |
+ int rv = DoLoop(OK); |
+ if (rv == ERR_IO_PENDING) |
user_read_callback_ = callback; |
- else |
- user_read_buf_ = NULL; |
- return result; |
+ return rv; |
} |
int ReadBufferingStreamSocket::DoLoop(int result) { |
@@ -258,16 +286,15 @@ int ReadBufferingStreamSocket::DoLoop(int result) { |
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; |
+ return transport_->Read( |
+ read_buffer_.get(), read_buffer_->RemainingCapacity(), |
+ base::Bind(&ReadBufferingStreamSocket::OnReadCompleted, |
+ base::Unretained(this))); |
} |
int ReadBufferingStreamSocket::DoReadComplete(int result) { |
state_ = STATE_NONE; |
+ |
if (result <= 0) |
return result; |
@@ -277,6 +304,10 @@ int ReadBufferingStreamSocket::DoReadComplete(int result) { |
return OK; |
} |
+ // If ReadIfReady() is used. |
+ if (user_read_buf_ == nullptr) |
+ return OK; |
+ |
memcpy(user_read_buf_->data(), |
read_buffer_->StartOfBuffer(), |
read_buffer_->capacity()); |
@@ -285,11 +316,13 @@ int ReadBufferingStreamSocket::DoReadComplete(int result) { |
} |
void ReadBufferingStreamSocket::OnReadCompleted(int result) { |
+ DCHECK_NE(ERR_IO_PENDING, result); |
+ DCHECK(user_read_callback_); |
+ |
result = DoLoop(result); |
if (result == ERR_IO_PENDING) |
return; |
- |
- user_read_buf_ = NULL; |
+ user_read_buf_ = nullptr; |
base::ResetAndReturn(&user_read_callback_).Run(result); |
} |
@@ -304,6 +337,9 @@ class SynchronousErrorStreamSocket : public WrappedStreamSocket { |
int Read(IOBuffer* buf, |
int buf_len, |
const CompletionCallback& callback) override; |
+ int ReadIfReady(IOBuffer* buf, |
+ int buf_len, |
+ const CompletionCallback& callback) override; |
int Write(IOBuffer* buf, |
int buf_len, |
const CompletionCallback& callback) override; |
@@ -346,6 +382,15 @@ int SynchronousErrorStreamSocket::Read(IOBuffer* buf, |
return transport_->Read(buf, buf_len, callback); |
} |
+int SynchronousErrorStreamSocket::ReadIfReady( |
+ IOBuffer* buf, |
+ int buf_len, |
+ const CompletionCallback& callback) { |
+ if (have_read_error_) |
+ return pending_read_error_; |
+ return transport_->ReadIfReady(buf, buf_len, callback); |
+} |
+ |
int SynchronousErrorStreamSocket::Write(IOBuffer* buf, |
int buf_len, |
const CompletionCallback& callback) { |
@@ -368,6 +413,9 @@ class FakeBlockingStreamSocket : public WrappedStreamSocket { |
int Read(IOBuffer* buf, |
int buf_len, |
const CompletionCallback& callback) override; |
+ int ReadIfReady(IOBuffer* buf, |
+ int buf_len, |
+ const CompletionCallback& callback) override; |
int Write(IOBuffer* buf, |
int buf_len, |
const CompletionCallback& callback) override; |
@@ -405,12 +453,21 @@ class FakeBlockingStreamSocket : public WrappedStreamSocket { |
// Handles completion from the underlying transport read. |
void OnReadCompleted(int result); |
+ // Handles async completion of ReadIfReady(). |
+ void CompleteReadIfReady(scoped_refptr<IOBuffer> buffer, int rv); |
+ |
// Finishes the current read. |
void ReturnReadResult(); |
// True if read callbacks are blocked. |
bool should_block_read_ = false; |
+ // Used to buffer result returned by a completed ReadIfReady(). |
+ std::string read_if_ready_buf_; |
+ |
+ // Non-null if there is a pending ReadIfReady(). |
+ CompletionCallback read_if_ready_callback_; |
+ |
// The buffer for the pending read, or NULL if not consumed. |
scoped_refptr<IOBuffer> pending_read_buf_; |
@@ -451,8 +508,9 @@ int FakeBlockingStreamSocket::Read(IOBuffer* buf, |
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))); |
+ int rv = transport_->Read( |
+ buf, len, base::Bind(&FakeBlockingStreamSocket::OnReadCompleted, |
+ base::Unretained(this))); |
if (rv == ERR_IO_PENDING || should_block_read_) { |
// Save the callback to be called later. |
pending_read_buf_ = buf; |
@@ -467,6 +525,32 @@ int FakeBlockingStreamSocket::Read(IOBuffer* buf, |
return rv; |
} |
+int FakeBlockingStreamSocket::ReadIfReady(IOBuffer* buf, |
+ int len, |
+ const CompletionCallback& callback) { |
+ if (!read_if_ready_buf_.empty()) { |
+ // This is possible if the caller calls ReadIfReady() with a smaller buffer |
+ // size than previously or if BlockReadResult() is called after |
+ // ReadIfReady() reports there is data available but before the data is |
+ // drained. |
davidben
2017/03/02 20:47:03
The comment should probably be clearer that we're
xunjieli
2017/03/02 22:30:21
Done.
|
+ CHECK(!should_block_read_); |
+ CHECK_GE(len, (int)read_if_ready_buf_.size()); |
davidben
2017/03/02 20:47:03
Nit: static_cast<int>(read_if_ready_buf_.size())
xunjieli
2017/03/02 22:30:20
Done.
|
+ int rv = read_if_ready_buf_.size(); |
+ memcpy(buf->data(), read_if_ready_buf_.data(), rv); |
+ read_if_ready_buf_.clear(); |
+ return rv; |
+ } |
+ scoped_refptr<IOBuffer> buf_copy = new IOBuffer(len); |
+ int rv = Read(buf_copy.get(), len, |
+ base::Bind(&FakeBlockingStreamSocket::CompleteReadIfReady, |
+ base::Unretained(this), buf_copy)); |
+ if (rv > 0) |
+ memcpy(buf->data(), buf_copy->data(), rv); |
+ if (rv == ERR_IO_PENDING) |
+ read_if_ready_callback_ = callback; |
+ return rv; |
+} |
+ |
int FakeBlockingStreamSocket::Write(IOBuffer* buf, |
int len, |
const CompletionCallback& callback) { |
@@ -507,13 +591,15 @@ void FakeBlockingStreamSocket::UnblockReadResult() { |
bool FakeBlockingStreamSocket::ReplaceReadResult(const std::string& data) { |
DCHECK(should_block_read_); |
- DCHECK_NE(ERR_IO_PENDING, pending_read_result_); |
DCHECK(pending_read_buf_); |
DCHECK_NE(-1, pending_read_buf_len_); |
if (static_cast<size_t>(pending_read_buf_len_) < data.size()) |
return false; |
+ DCHECK_NE(ERR_IO_PENDING, pending_read_result_); |
+ DCHECK(pending_read_buf_); |
+ DCHECK_NE(-1, pending_read_buf_len_); |
davidben
2017/03/02 20:47:02
601 and 602 are already checked a few lines above.
xunjieli
2017/03/02 22:30:21
Done.
|
memcpy(pending_read_buf_->data(), data.data(), data.size()); |
pending_read_result_ = data.size(); |
return true; |
@@ -584,6 +670,16 @@ void FakeBlockingStreamSocket::OnReadCompleted(int result) { |
ReturnReadResult(); |
} |
+void FakeBlockingStreamSocket::CompleteReadIfReady(scoped_refptr<IOBuffer> buf, |
+ int rv) { |
+ DCHECK(read_if_ready_callback_); |
+ DCHECK(read_if_ready_buf_.empty()); |
+ DCHECK(!should_block_read_); |
+ if (rv > 0) |
+ read_if_ready_buf_ = std::string(buf->data(), buf->data() + rv); |
+ base::ResetAndReturn(&read_if_ready_callback_).Run(rv > 0 ? OK : rv); |
+} |
+ |
void FakeBlockingStreamSocket::ReturnReadResult() { |
int result = pending_read_result_; |
pending_read_result_ = ERR_IO_PENDING; |
@@ -858,6 +954,59 @@ class SSLClientSocketTest : public PlatformTest { |
AddressList addr_; |
}; |
+// If GetParam(), try ReadIfReady() and fall back to Read() if needed. |
+class SSLClientSocketReadTest : public SSLClientSocketTest, |
+ public ::testing::WithParamInterface<bool> { |
+ protected: |
+ void SetUp() override { |
+ if (GetParam()) |
+ scoped_feature_list_.InitAndEnableFeature(Socket::kReadIfReadyExperiment); |
+ } |
+ |
+ // Convienient wrapper to call Read()/ReadIfReady() depending on GetParam(). |
+ int Read(StreamSocket* socket, |
+ IOBuffer* buf, |
+ int buf_len, |
+ const CompletionCallback& callback) { |
+ if (GetParam()) |
+ return socket->ReadIfReady(buf, buf_len, callback); |
+ return socket->Read(buf, buf_len, callback); |
+ } |
+ |
+ // Wait for Read()/ReadIfReady() to complete. |
+ int WaitForReadCompletion(StreamSocket* socket, |
+ IOBuffer* buf, |
+ int buf_len, |
+ TestCompletionCallback* callback, |
+ int rv) { |
+ if (!GetParam()) |
+ return callback->GetResult(rv); |
+ while (rv == ERR_IO_PENDING) { |
+ rv = callback->GetResult(rv); |
+ if (rv != OK) |
+ return rv; |
+ rv = socket->ReadIfReady(buf, buf_len, callback->callback()); |
+ } |
+ return rv; |
+ } |
+ |
+ // Calls Read()/ReadIfReady() and waits for it to return data. |
+ int ReadAndWaitForCompletion(StreamSocket* socket, |
+ IOBuffer* buf, |
+ int buf_len) { |
+ TestCompletionCallback callback; |
+ int rv = Read(socket, buf, buf_len, callback.callback()); |
+ return WaitForReadCompletion(socket, buf, buf_len, &callback, rv); |
+ } |
+ |
+ private: |
+ base::test::ScopedFeatureList scoped_feature_list_; |
+}; |
+ |
+INSTANTIATE_TEST_CASE_P(/* no prefix */, |
+ SSLClientSocketReadTest, |
+ ::testing::Bool()); |
+ |
// Verifies the correctness of GetSSLCertRequestInfo. |
class SSLClientSocketCertRequestInfoTest : public SSLClientSocketTest { |
protected: |
@@ -1206,7 +1355,7 @@ TEST_F(SSLClientSocketTest, ConnectClientAuthSendNullCert) { |
// Tests that the socket can be read from successfully. Also test that a peer's |
// close_notify alert is successfully processed without error. |
-TEST_F(SSLClientSocketTest, Read) { |
+TEST_P(SSLClientSocketReadTest, Read) { |
ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); |
TestCompletionCallback callback; |
@@ -1242,7 +1391,7 @@ TEST_F(SSLClientSocketTest, Read) { |
int64_t unencrypted_bytes_read = 0; |
int64_t network_bytes_read_during_handshake = sock->GetTotalReceivedBytes(); |
do { |
- rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback())); |
+ rv = ReadAndWaitForCompletion(sock.get(), buf.get(), 4096); |
EXPECT_GE(rv, 0); |
if (rv >= 0) { |
unencrypted_bytes_read += rv; |
@@ -1293,7 +1442,7 @@ TEST_F(SSLClientSocketTest, Connect_WithSynchronousError) { |
// synchronously returns an error code - such as if an intermediary terminates |
// the socket connection uncleanly. |
// This is a regression test for http://crbug.com/238536 |
-TEST_F(SSLClientSocketTest, Read_WithSynchronousError) { |
+TEST_P(SSLClientSocketReadTest, Read_WithSynchronousError) { |
ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); |
TestCompletionCallback callback; |
@@ -1335,7 +1484,7 @@ TEST_F(SSLClientSocketTest, Read_WithSynchronousError) { |
// Note: This test will hang if this bug has regressed. Simply checking that |
// rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING is a legitimate |
// result when using a dedicated task runner for NSS. |
- rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback())); |
+ rv = Read(sock.get(), buf.get(), 4096, callback.callback()); |
EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET)); |
davidben
2017/03/02 20:47:03
ReadAndWaitForCompletion?
xunjieli
2017/03/02 22:30:21
Done.
|
} |
@@ -1470,7 +1619,7 @@ TEST_F(SSLClientSocketTest, Write_WithSynchronousErrorNoRead) { |
// Test the full duplex mode, with Read and Write pending at the same time. |
// This test also serves as a regression test for http://crbug.com/29815. |
-TEST_F(SSLClientSocketTest, Read_FullDuplex) { |
+TEST_P(SSLClientSocketReadTest, Read_FullDuplex) { |
ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); |
int rv; |
@@ -1480,7 +1629,7 @@ TEST_F(SSLClientSocketTest, Read_FullDuplex) { |
// Issue a "hanging" Read first. |
TestCompletionCallback callback; |
scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); |
- rv = sock_->Read(buf.get(), 4096, callback.callback()); |
+ rv = Read(sock_.get(), buf.get(), 4096, callback.callback()); |
// We haven't written the request, so there should be no response yet. |
ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); |
@@ -1500,7 +1649,7 @@ TEST_F(SSLClientSocketTest, Read_FullDuplex) { |
EXPECT_EQ(static_cast<int>(request_text.size()), rv); |
// Now get the Read result. |
- rv = callback.WaitForResult(); |
+ rv = WaitForReadCompletion(sock_.get(), buf.get(), 4096, &callback, rv); |
EXPECT_GT(rv, 0); |
} |
@@ -1510,7 +1659,7 @@ TEST_F(SSLClientSocketTest, Read_FullDuplex) { |
// Read() and Write() callbacks. If the socket is deleted by the Read() |
// callback, the Write() callback should not be invoked. |
// Regression test for http://crbug.com/232633 |
-TEST_F(SSLClientSocketTest, Read_DeleteWhilePendingFullDuplex) { |
+TEST_P(SSLClientSocketReadTest, Read_DeleteWhilePendingFullDuplex) { |
ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); |
TestCompletionCallback callback; |
@@ -1559,7 +1708,7 @@ TEST_F(SSLClientSocketTest, Read_DeleteWhilePendingFullDuplex) { |
SSLClientSocket* raw_sock = sock.get(); |
DeleteSocketCallback read_callback(sock.release()); |
scoped_refptr<IOBuffer> read_buf(new IOBuffer(4096)); |
- rv = raw_sock->Read(read_buf.get(), 4096, read_callback.callback()); |
+ rv = Read(raw_sock, read_buf.get(), 4096, read_callback.callback()); |
// Ensure things didn't complete synchronously, otherwise |sock| is invalid. |
ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); |
@@ -1578,8 +1727,14 @@ TEST_F(SSLClientSocketTest, Read_DeleteWhilePendingFullDuplex) { |
// the Write() callback. |
raw_transport->UnblockWrite(); |
+ // |read_callback| deletes |sock| so if ReadIfReady() is used, we will get OK |
+ // asynchronously but can't continue reading because the socket is gone. |
rv = read_callback.WaitForResult(); |
- EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET)); |
+ if (GetParam()) { |
+ EXPECT_THAT(rv, IsOk()); |
+ } else { |
+ EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET)); |
+ } |
// The Write callback should not have been called. |
EXPECT_FALSE(callback.have_result()); |
@@ -1589,7 +1744,7 @@ TEST_F(SSLClientSocketTest, Read_DeleteWhilePendingFullDuplex) { |
// transport socket after a failing write. This can occur if we have a Write |
// error in a SPDY socket. |
// Regression test for http://crbug.com/335557 |
-TEST_F(SSLClientSocketTest, Read_WithWriteError) { |
+TEST_P(SSLClientSocketReadTest, Read_WithWriteError) { |
ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); |
TestCompletionCallback callback; |
@@ -1634,7 +1789,7 @@ TEST_F(SSLClientSocketTest, Read_WithWriteError) { |
TestCompletionCallback read_callback; |
raw_transport->BlockReadResult(); |
scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); |
- rv = sock->Read(buf.get(), 4096, read_callback.callback()); |
+ rv = Read(sock.get(), buf.get(), 4096, read_callback.callback()); |
EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
// Perform another write, but have it fail. Write a request larger than the |
@@ -1666,7 +1821,7 @@ TEST_F(SSLClientSocketTest, Read_WithWriteError) { |
// At this point the Read result is available. Transport write errors are |
// surfaced through Writes. See https://crbug.com/249848. |
- rv = read_callback.WaitForResult(); |
+ rv = WaitForReadCompletion(sock.get(), buf.get(), 4096, &read_callback, rv); |
EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET)); |
// Release the read. This does not cause a crash. |
@@ -1702,7 +1857,7 @@ TEST_F(SSLClientSocketTest, Connect_WithZeroReturn) { |
// Tests that SSLClientSocket returns a Read of size 0 if the underlying socket |
// is cleanly closed, but the peer does not send close_notify. |
// This is a regression test for https://crbug.com/422246 |
-TEST_F(SSLClientSocketTest, Read_WithZeroReturn) { |
+TEST_P(SSLClientSocketReadTest, Read_WithZeroReturn) { |
ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); |
TestCompletionCallback callback; |
@@ -1728,14 +1883,14 @@ TEST_F(SSLClientSocketTest, Read_WithZeroReturn) { |
raw_transport->SetNextReadError(0); |
scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); |
- rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback())); |
+ rv = ReadAndWaitForCompletion(sock.get(), buf.get(), 4096); |
EXPECT_EQ(0, rv); |
} |
// Tests that SSLClientSocket cleanly returns a Read of size 0 if the |
// underlying socket is cleanly closed asynchronously. |
// This is a regression test for https://crbug.com/422246 |
-TEST_F(SSLClientSocketTest, Read_WithAsyncZeroReturn) { |
+TEST_P(SSLClientSocketReadTest, Read_WithAsyncZeroReturn) { |
ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); |
TestCompletionCallback callback; |
@@ -1765,17 +1920,18 @@ TEST_F(SSLClientSocketTest, Read_WithAsyncZeroReturn) { |
raw_error_socket->SetNextReadError(0); |
raw_transport->BlockReadResult(); |
scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); |
- rv = sock->Read(buf.get(), 4096, callback.callback()); |
+ TestCompletionCallback read_callback; |
+ rv = Read(sock.get(), buf.get(), 4096, read_callback.callback()); |
EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
raw_transport->UnblockReadResult(); |
- rv = callback.GetResult(rv); |
+ rv = WaitForReadCompletion(sock.get(), buf.get(), 4096, &read_callback, rv); |
EXPECT_EQ(0, rv); |
} |
// Tests that fatal alerts from the peer are processed. This is a regression |
// test for https://crbug.com/466303. |
-TEST_F(SSLClientSocketTest, Read_WithFatalAlert) { |
+TEST_P(SSLClientSocketReadTest, Read_WithFatalAlert) { |
SpawnedTestServer::SSLOptions ssl_options; |
ssl_options.alert_after_handshake = true; |
ASSERT_TRUE(StartTestServer(ssl_options)); |
@@ -1787,11 +1943,11 @@ TEST_F(SSLClientSocketTest, Read_WithFatalAlert) { |
// Receive the fatal alert. |
TestCompletionCallback callback; |
scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); |
- EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, callback.GetResult(sock_->Read( |
- buf.get(), 4096, callback.callback()))); |
+ EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, |
+ ReadAndWaitForCompletion(sock_.get(), buf.get(), 4096)); |
} |
-TEST_F(SSLClientSocketTest, Read_SmallChunks) { |
+TEST_P(SSLClientSocketReadTest, Read_SmallChunks) { |
ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); |
int rv; |
@@ -1810,12 +1966,12 @@ TEST_F(SSLClientSocketTest, Read_SmallChunks) { |
scoped_refptr<IOBuffer> buf(new IOBuffer(1)); |
do { |
- rv = callback.GetResult(sock_->Read(buf.get(), 1, callback.callback())); |
+ rv = ReadAndWaitForCompletion(sock_.get(), buf.get(), 1); |
EXPECT_GE(rv, 0); |
} while (rv > 0); |
} |
-TEST_F(SSLClientSocketTest, Read_ManySmallRecords) { |
+TEST_P(SSLClientSocketReadTest, Read_ManySmallRecords) { |
ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); |
TestCompletionCallback callback; |
@@ -1858,11 +2014,11 @@ TEST_F(SSLClientSocketTest, Read_ManySmallRecords) { |
raw_transport->SetBufferSize(15000); |
scoped_refptr<IOBuffer> buffer(new IOBuffer(8192)); |
- rv = callback.GetResult(sock->Read(buffer.get(), 8192, callback.callback())); |
+ rv = ReadAndWaitForCompletion(sock.get(), buffer.get(), 8192); |
ASSERT_EQ(rv, 8192); |
} |
-TEST_F(SSLClientSocketTest, Read_Interrupted) { |
+TEST_P(SSLClientSocketReadTest, Read_Interrupted) { |
ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); |
int rv; |
@@ -1881,11 +2037,11 @@ TEST_F(SSLClientSocketTest, Read_Interrupted) { |
// Do a partial read and then exit. This test should not crash! |
scoped_refptr<IOBuffer> buf(new IOBuffer(512)); |
- rv = callback.GetResult(sock_->Read(buf.get(), 512, callback.callback())); |
+ rv = ReadAndWaitForCompletion(sock_.get(), buf.get(), 512); |
EXPECT_GT(rv, 0); |
} |
-TEST_F(SSLClientSocketTest, Read_FullLogging) { |
+TEST_P(SSLClientSocketReadTest, Read_FullLogging) { |
ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); |
TestCompletionCallback callback; |
@@ -1921,7 +2077,7 @@ TEST_F(SSLClientSocketTest, Read_FullLogging) { |
scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); |
for (;;) { |
- rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback())); |
+ rv = ReadAndWaitForCompletion(sock.get(), buf.get(), 4096); |
EXPECT_GE(rv, 0); |
if (rv <= 0) |
break; |
@@ -3593,7 +3749,7 @@ TEST_F(SSLClientSocketTest, AccessDeniedClientCerts) { |
} |
// Basic test for dumping memory stats. |
-TEST_F(SSLClientSocketTest, DumpMemoryStats) { |
+TEST_P(SSLClientSocketReadTest, DumpMemoryStats) { |
ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); |
int rv; |
@@ -3609,16 +3765,29 @@ TEST_F(SSLClientSocketTest, DumpMemoryStats) { |
// Read the response without writing a request, so the read will be pending. |
TestCompletionCallback read_callback; |
scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); |
- rv = sock_->Read(buf.get(), 4096, read_callback.callback()); |
+ rv = Read(sock_.get(), buf.get(), 4096, read_callback.callback()); |
EXPECT_EQ(ERR_IO_PENDING, rv); |
// Dump memory again and check that |buffer_size| contain the read buffer. |
StreamSocket::SocketMemoryStats stats2; |
sock_->DumpMemoryStats(&stats2); |
- EXPECT_EQ(17 * 1024u, stats2.buffer_size); |
+ |
+ bool buffer_released = false; |
+ if (GetParam()) { |
+// TODO(xunjieli): crbug.com/690915. Implement ReadIfReady() for windows. |
+#if defined(OS_POSIX) |
+ buffer_released = true; |
+#endif |
+ } |
+ if (buffer_released) { |
+ EXPECT_EQ(0u, stats2.buffer_size); |
+ EXPECT_EQ(stats.serialized_cert_size, stats2.total_size); |
+ } else { |
+ EXPECT_EQ(17 * 1024u, stats2.buffer_size); |
+ EXPECT_LT(17 * 1024u, stats2.total_size); |
+ } |
EXPECT_EQ(1u, stats2.cert_count); |
EXPECT_LT(0u, stats2.serialized_cert_size); |
- EXPECT_LT(17 * 1024u, stats2.total_size); |
} |
} // namespace net |