summaryrefslogtreecommitdiffstats
path: root/net/socket
diff options
context:
space:
mode:
authorrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-31 11:47:33 +0000
committerrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-31 11:47:33 +0000
commit39eefa5297bc6671e8e442a11308b85e4fd5e438 (patch)
tree51b337986262836db472b8591c1f34a84ae06e63 /net/socket
parent9b3892f863b1a38fab509dc5a13b44620bfc5ae9 (diff)
downloadchromium_src-39eefa5297bc6671e8e442a11308b85e4fd5e438.zip
chromium_src-39eefa5297bc6671e8e442a11308b85e4fd5e438.tar.gz
chromium_src-39eefa5297bc6671e8e442a11308b85e4fd5e438.tar.bz2
SPDY - DeterministicSocketData - Fix to handle Async Read/write followed by
Sync read/write. R=rch@chromium.org TEST=network unit tests Review URL: https://chromiumcodereview.appspot.com/12096055 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@179864 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket')
-rw-r--r--net/socket/deterministic_socket_data_unittest.cc60
-rw-r--r--net/socket/socket_test_util.cc12
-rw-r--r--net/socket/socket_test_util.h1
3 files changed, 69 insertions, 4 deletions
diff --git a/net/socket/deterministic_socket_data_unittest.cc b/net/socket/deterministic_socket_data_unittest.cc
index 055fbdc..a007e36 100644
--- a/net/socket/deterministic_socket_data_unittest.cc
+++ b/net/socket/deterministic_socket_data_unittest.cc
@@ -31,6 +31,9 @@ class DeterministicSocketDataTest : public PlatformTest {
virtual void TearDown();
+ void ReentrantReadCallback(int len, int rv);
+ void ReentrantWriteCallback(const char* data, int len, int rv);
+
protected:
void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
size_t writes_count);
@@ -166,6 +169,22 @@ void DeterministicSocketDataTest::AssertWriteReturns(const char* data,
ASSERT_EQ(rv, sock_->Write(buf, len, write_callback_.callback()));
}
+void DeterministicSocketDataTest::ReentrantReadCallback(int len, int rv) {
+ scoped_refptr<IOBuffer> read_buf(new IOBuffer(len));
+ EXPECT_EQ(len, sock_->Read(read_buf, len,
+ base::Bind(&DeterministicSocketDataTest::ReentrantReadCallback,
+ base::Unretained(this), len)));
+}
+
+void DeterministicSocketDataTest::ReentrantWriteCallback(
+ const char* data, int len, int rv) {
+ scoped_refptr<IOBuffer> write_buf(new IOBuffer(len));
+ memcpy(write_buf->data(), data, len);
+ EXPECT_EQ(len, sock_->Write(write_buf, len,
+ base::Bind(&DeterministicSocketDataTest::ReentrantWriteCallback,
+ base::Unretained(this), data, len)));
+}
+
// ----------- Read
TEST_F(DeterministicSocketDataTest, SingleSyncReadWhileStopped) {
@@ -295,6 +314,23 @@ TEST_F(DeterministicSocketDataTest, MixedReads) {
AssertSyncReadEquals(kMsg1, kLen1);
}
+TEST_F(DeterministicSocketDataTest, SyncReadFromCompletionCallback) {
+ MockRead reads[] = {
+ MockRead(ASYNC, kMsg1, kLen1, 0), // Async Read
+ MockRead(SYNCHRONOUS, kMsg2, kLen2, 1), // Sync Read
+ };
+
+ Initialize(reads, arraysize(reads), NULL, 0);
+
+ data_->StopAfter(2);
+
+ scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
+ ASSERT_EQ(ERR_IO_PENDING, sock_->Read(read_buf, kLen1,
+ base::Bind(&DeterministicSocketDataTest::ReentrantReadCallback,
+ base::Unretained(this), kLen2)));
+ data_->Run();
+}
+
// ----------- Write
TEST_F(DeterministicSocketDataTest, SingleSyncWriteWhileStopped) {
@@ -418,6 +454,24 @@ TEST_F(DeterministicSocketDataTest, MixedWrites) {
AssertSyncWriteEquals(kMsg1, kLen1);
}
+TEST_F(DeterministicSocketDataTest, SyncWriteFromCompletionCallback) {
+ MockWrite writes[] = {
+ MockWrite(ASYNC, kMsg1, kLen1, 0), // Async Write
+ MockWrite(SYNCHRONOUS, kMsg2, kLen2, 1), // Sync Write
+ };
+
+ Initialize(NULL, 0, writes, arraysize(writes));
+
+ data_->StopAfter(2);
+
+ scoped_refptr<IOBuffer> write_buf(new IOBuffer(kLen1));
+ memcpy(write_buf->data(), kMsg1, kLen1);
+ ASSERT_EQ(ERR_IO_PENDING, sock_->Write(write_buf, kLen1,
+ base::Bind(&DeterministicSocketDataTest::ReentrantWriteCallback,
+ base::Unretained(this), kMsg2, kLen2)));
+ data_->Run();
+}
+
// ----------- Mixed Reads and Writes
TEST_F(DeterministicSocketDataTest, MixedSyncOperations) {
@@ -484,10 +538,12 @@ TEST_F(DeterministicSocketDataTest, InterleavedAsyncOperations) {
AssertReadReturns(kMsg1, kLen1, ERR_IO_PENDING);
data_->RunFor(1);
+ ASSERT_TRUE(read_callback_.have_result());
ASSERT_EQ(kLen1, read_callback_.WaitForResult());
AssertReadBufferEquals(kMsg1, kLen1);
data_->RunFor(1);
+ ASSERT_TRUE(write_callback_.have_result());
ASSERT_EQ(kLen2, write_callback_.WaitForResult());
data_->StopAfter(1);
@@ -498,9 +554,11 @@ TEST_F(DeterministicSocketDataTest, InterleavedAsyncOperations) {
AssertWriteReturns(kMsg3, kLen3, ERR_IO_PENDING);
data_->RunFor(1);
+ ASSERT_TRUE(write_callback_.have_result());
ASSERT_EQ(kLen3, write_callback_.WaitForResult());
data_->RunFor(1);
+ ASSERT_TRUE(read_callback_.have_result());
ASSERT_EQ(kLen2, read_callback_.WaitForResult());
AssertReadBufferEquals(kMsg2, kLen2);
}
@@ -528,6 +586,7 @@ TEST_F(DeterministicSocketDataTest, InterleavedMixedOperations) {
AssertSyncReadEquals(kMsg1, kLen1);
data_->RunFor(1);
+ ASSERT_TRUE(write_callback_.have_result());
ASSERT_EQ(kLen2, write_callback_.WaitForResult());
// Issue the read, which will block until the write completes
@@ -538,6 +597,7 @@ TEST_F(DeterministicSocketDataTest, InterleavedMixedOperations) {
AssertSyncWriteEquals(kMsg3, kLen3);
data_->RunFor(1);
+ ASSERT_TRUE(read_callback_.have_result());
ASSERT_EQ(kLen2, read_callback_.WaitForResult());
AssertReadBufferEquals(kMsg2, kLen2);
}
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index 6b0070b..d7111cc 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -451,13 +451,17 @@ DeterministicSocketData::DeterministicSocketData(MockRead* reads,
current_write_(),
stopping_sequence_number_(0),
stopped_(false),
- print_debug_(false) {
+ print_debug_(false),
+ is_running_(false) {
VerifyCorrectSequenceNumbers(reads, reads_count, writes, writes_count);
}
DeterministicSocketData::~DeterministicSocketData() {}
void DeterministicSocketData::Run() {
+ DCHECK(!is_running_);
+ is_running_ = true;
+
SetStopped(false);
int counter = 0;
// Continue to consume data until all data has run out, or the stopped_ flag
@@ -481,6 +485,7 @@ void DeterministicSocketData::Run() {
MessageLoop::current()->RunUntilIdle();
}
SetStopped(false);
+ is_running_ = false;
}
void DeterministicSocketData::RunFor(int steps) {
@@ -500,7 +505,6 @@ void DeterministicSocketData::StopAfter(int seq) {
MockRead DeterministicSocketData::GetNextRead() {
current_read_ = StaticSocketDataProvider::PeekRead();
- EXPECT_LE(sequence_number_, current_read_.sequence_number);
// Synchronous read while stopped is an error
if (stopped() && current_read_.mode == SYNCHRONOUS) {
@@ -586,14 +590,14 @@ void DeterministicSocketData::Reset() {
void DeterministicSocketData::InvokeCallbacks() {
if (socket_ && socket_->write_pending() &&
(current_write().sequence_number == sequence_number())) {
- socket_->CompleteWrite();
NextStep();
+ socket_->CompleteWrite();
return;
}
if (socket_ && socket_->read_pending() &&
(current_read().sequence_number == sequence_number())) {
- socket_->CompleteRead();
NextStep();
+ socket_->CompleteRead();
return;
}
}
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index 2811983..febd22a 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -508,6 +508,7 @@ class DeterministicSocketData
bool stopped_;
base::WeakPtr<DeterministicMockTCPClientSocket> socket_;
bool print_debug_;
+ bool is_running_;
};
// Holds an array of SocketDataProvider elements. As Mock{TCP,SSL}StreamSocket