1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246 |
- // Copyright 2015 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <memory>
- #include <string>
- #include "base/bind.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/ref_counted.h"
- #include "base/run_loop.h"
- #include "net/base/completion_once_callback.h"
- #include "net/base/io_buffer.h"
- #include "net/base/test_completion_callback.h"
- #include "net/log/net_log_with_source.h"
- #include "net/socket/socket_test_util.h"
- #include "net/test/gtest_util.h"
- #include "net/test/test_with_task_environment.h"
- #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest-spi.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "testing/platform_test.h"
- using net::test::IsError;
- using net::test::IsOk;
- //-----------------------------------------------------------------------------
- namespace net {
- namespace {
- const char kMsg1[] = "\0hello!\xff";
- const int kLen1 = std::size(kMsg1);
- const char kMsg2[] = "\0a2345678\0";
- const int kLen2 = std::size(kMsg2);
- const char kMsg3[] = "bye!";
- const int kLen3 = std::size(kMsg3);
- const char kMsg4[] = "supercalifragilisticexpialidocious";
- const int kLen4 = std::size(kMsg4);
- // Helper class for starting the next operation operation reentrantly after the
- // previous operation completed asynchronously. When OnIOComplete is called,
- // it will first verify that the previous operation behaved as expected. This is
- // specified by either SetExpectedRead or SetExpectedWrite. It will then invoke
- // a read or write operation specified by SetInvokeRead or SetInvokeWrite.
- class ReentrantHelper {
- public:
- explicit ReentrantHelper(StreamSocket* socket) : socket_(socket) {}
- ReentrantHelper(const ReentrantHelper&) = delete;
- ReentrantHelper& operator=(const ReentrantHelper&) = delete;
- // Expect that the previous operation will return |first_len| and will fill
- // |first_read_data_| with |first_read_data|.
- void SetExpectedRead(const char* first_read_data, int first_len) {
- verify_read_ = true;
- first_read_buf_ = base::MakeRefCounted<IOBuffer>(first_len);
- first_read_data_ = first_read_data;
- first_len_ = first_len;
- }
- // Expect that the previous operation will return |first_len|.
- void SetExpectedWrite(int first_len) {
- verify_read_ = false;
- first_len_ = first_len;
- }
- // After verifying expectations, invoke a read of |read_len| bytes into
- // |read_buf|, notifying |callback| when complete.
- void SetInvokeRead(scoped_refptr<IOBuffer> read_buf,
- int read_len,
- int second_rv,
- CompletionOnceCallback callback) {
- second_read_ = true;
- second_read_buf_ = read_buf;
- second_rv_ = second_rv;
- second_callback_ = std::move(callback);
- second_len_ = read_len;
- }
- // After verifying expectations, invoke a write of |write_len| bytes from
- // |write_data|, notifying |callback| when complete.
- void SetInvokeWrite(const char* write_data,
- int write_len,
- int second_rv,
- CompletionOnceCallback callback) {
- second_read_ = false;
- second_rv_ = second_rv;
- second_write_data_ = write_data;
- second_callback_ = std::move(callback);
- second_len_ = write_len;
- }
- // Returns the OnIOComplete callback for this helper.
- CompletionOnceCallback callback() {
- return base::BindOnce(&ReentrantHelper::OnIOComplete,
- base::Unretained(this));
- }
- // Retuns the buffer where data is expected to have been written,
- // when checked by SetExpectRead()
- scoped_refptr<IOBuffer> read_buf() { return first_read_buf_; }
- private:
- void OnIOComplete(int rv) {
- CHECK_NE(-1, first_len_) << "Expectation not set.";
- CHECK_NE(-1, second_len_) << "Invocation not set.";
- ASSERT_EQ(first_len_, rv);
- if (verify_read_) {
- ASSERT_EQ(std::string(first_read_data_, first_len_),
- std::string(first_read_buf_->data(), rv));
- }
- if (second_read_) {
- ASSERT_EQ(second_rv_, socket_->Read(second_read_buf_.get(), second_len_,
- std::move(second_callback_)));
- } else {
- scoped_refptr<IOBuffer> write_buf =
- base::MakeRefCounted<IOBuffer>(second_len_);
- memcpy(write_buf->data(), second_write_data_, second_len_);
- ASSERT_EQ(second_rv_, socket_->Write(write_buf.get(), second_len_,
- std::move(second_callback_),
- TRAFFIC_ANNOTATION_FOR_TESTS));
- }
- }
- raw_ptr<StreamSocket> socket_;
- bool verify_read_ = false;
- scoped_refptr<IOBuffer> first_read_buf_;
- const char* first_read_data_ = nullptr;
- int first_len_ = -1;
- CompletionOnceCallback second_callback_;
- bool second_read_ = false;
- int second_rv_;
- scoped_refptr<IOBuffer> second_read_buf_;
- const char* second_write_data_ = nullptr;
- int second_len_ = -1;
- };
- class SequencedSocketDataTest : public TestWithTaskEnvironment {
- public:
- SequencedSocketDataTest();
- ~SequencedSocketDataTest() override;
- // This method is used as the completion callback for an async read
- // operation and when invoked, it verifies that the correct data was read,
- // then reads from the socket and verifies that that it returns the correct
- // value.
- void ReentrantReadCallback(const char* data,
- int len1,
- int len2,
- int expected_rv2,
- int rv);
- // This method is used at the completion callback for an async operation.
- // When executed, verifies that |rv| equals |expected_rv| and then
- // attempts an aync read from the socket into |read_buf_| (initialized
- // to |read_buf_len|) using |callback|.
- void ReentrantAsyncReadCallback(int len1, int len2, int rv);
- // This method is used as the completion callback for an async write
- // operation and when invoked, it verifies that the write returned correctly,
- // then
- // attempts to write to the socket and verifies that that it returns the
- // correct value.
- void ReentrantWriteCallback(int expected_rv1,
- const char* data,
- int len,
- int expected_rv2,
- int rv);
- // This method is used at the completion callback for an async operation.
- // When executed, verifies that |rv| equals |expected_rv| and then
- // attempts an aync write of |data| with |callback|
- void ReentrantAsyncWriteCallback(const char* data,
- int len,
- CompletionOnceCallback callback,
- int expected_rv,
- int rv);
- // Callback which adds a failure if it's ever called.
- void FailingCompletionCallback(int rv);
- protected:
- void Initialize(base::span<const MockRead> reads,
- base::span<const MockWrite> writes);
- void AssertSyncReadEquals(const char* data, int len);
- void AssertAsyncReadEquals(const char* data, int len);
- void AssertReadReturns(int len, int rv);
- void AssertReadBufferEquals(const char* data, int len);
- void AssertSyncWriteEquals(const char* data, int len);
- void AssertAsyncWriteEquals(const char* data, int len);
- void AssertWriteReturns(const char* data, int len, int rv);
- bool IsPaused() const;
- void Resume();
- void RunUntilPaused();
- // When a given test completes, data_.at_eof() is expected to
- // match the value specified here. Most test should consume all
- // reads and writes, but some tests verify error handling behavior
- // do not consume all data.
- void set_expect_eof(bool expect_eof) { expect_eof_ = expect_eof; }
- CompletionOnceCallback failing_callback() {
- return base::BindOnce(&SequencedSocketDataTest::FailingCompletionCallback,
- base::Unretained(this));
- }
- TestCompletionCallback read_callback_;
- scoped_refptr<IOBuffer> read_buf_;
- TestCompletionCallback write_callback_;
- std::unique_ptr<SequencedSocketData> data_;
- MockClientSocketFactory socket_factory_;
- bool expect_eof_ = true;
- std::unique_ptr<StreamSocket> sock_;
- };
- SequencedSocketDataTest::SequencedSocketDataTest() = default;
- SequencedSocketDataTest::~SequencedSocketDataTest() {
- // Make sure no unexpected pending tasks will cause a failure.
- base::RunLoop().RunUntilIdle();
- if (expect_eof_) {
- EXPECT_EQ(expect_eof_, data_->AllReadDataConsumed());
- EXPECT_EQ(expect_eof_, data_->AllWriteDataConsumed());
- }
- }
- void SequencedSocketDataTest::Initialize(base::span<const MockRead> reads,
- base::span<const MockWrite> writes) {
- data_ = std::make_unique<SequencedSocketData>(MockConnect(SYNCHRONOUS, OK),
- reads, writes);
- socket_factory_.AddSocketDataProvider(data_.get());
- sock_ = socket_factory_.CreateTransportClientSocket(
- AddressList(IPEndPoint(IPAddress::IPv4Localhost(), 443)),
- nullptr /* socket_performance_watcher */,
- nullptr /* network_quality_estimator */, nullptr /* net_log */,
- NetLogSource());
- TestCompletionCallback callback;
- EXPECT_EQ(OK, sock_->Connect(callback.callback()));
- }
- void SequencedSocketDataTest::AssertSyncReadEquals(const char* data, int len) {
- // Issue the read, which will complete immediately.
- AssertReadReturns(len, len);
- AssertReadBufferEquals(data, len);
- }
- void SequencedSocketDataTest::AssertAsyncReadEquals(const char* data, int len) {
- // Issue the read, which will be completed asynchronously.
- AssertReadReturns(len, ERR_IO_PENDING);
- EXPECT_TRUE(sock_->IsConnected());
- // Now the read should complete.
- ASSERT_EQ(len, read_callback_.WaitForResult());
- AssertReadBufferEquals(data, len);
- }
- void SequencedSocketDataTest::AssertReadReturns(int len, int rv) {
- read_buf_ = base::MakeRefCounted<IOBuffer>(len);
- if (rv == ERR_IO_PENDING) {
- ASSERT_EQ(rv, sock_->Read(read_buf_.get(), len, read_callback_.callback()));
- ASSERT_FALSE(read_callback_.have_result());
- } else {
- ASSERT_EQ(rv, sock_->Read(read_buf_.get(), len, failing_callback()));
- }
- }
- void SequencedSocketDataTest::AssertReadBufferEquals(const char* data,
- int len) {
- ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
- }
- void SequencedSocketDataTest::AssertSyncWriteEquals(const char* data, int len) {
- // Issue the write, which should be complete immediately.
- AssertWriteReturns(data, len, len);
- ASSERT_FALSE(write_callback_.have_result());
- }
- void SequencedSocketDataTest::AssertAsyncWriteEquals(const char* data,
- int len) {
- // Issue the read, which should be completed asynchronously.
- AssertWriteReturns(data, len, ERR_IO_PENDING);
- EXPECT_FALSE(read_callback_.have_result());
- EXPECT_TRUE(sock_->IsConnected());
- ASSERT_EQ(len, write_callback_.WaitForResult());
- }
- bool SequencedSocketDataTest::IsPaused() const {
- return data_->IsPaused();
- }
- void SequencedSocketDataTest::Resume() {
- data_->Resume();
- }
- void SequencedSocketDataTest::RunUntilPaused() {
- data_->RunUntilPaused();
- }
- void SequencedSocketDataTest::AssertWriteReturns(const char* data,
- int len,
- int rv) {
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(len);
- memcpy(buf->data(), data, len);
- if (rv == ERR_IO_PENDING) {
- ASSERT_EQ(rv, sock_->Write(buf.get(), len, write_callback_.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS));
- ASSERT_FALSE(write_callback_.have_result());
- } else {
- ASSERT_EQ(rv, sock_->Write(buf.get(), len, failing_callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS));
- }
- }
- void SequencedSocketDataTest::ReentrantReadCallback(const char* data,
- int len1,
- int len2,
- int expected_rv2,
- int rv) {
- ASSERT_EQ(len1, rv);
- AssertReadBufferEquals(data, len1);
- AssertReadReturns(len2, expected_rv2);
- }
- void SequencedSocketDataTest::ReentrantAsyncReadCallback(int expected_rv,
- int len,
- int rv) {
- ASSERT_EQ(expected_rv, rv);
- AssertReadReturns(len, ERR_IO_PENDING);
- }
- void SequencedSocketDataTest::ReentrantWriteCallback(int expected_rv1,
- const char* data,
- int len,
- int expected_rv2,
- int rv) {
- ASSERT_EQ(expected_rv1, rv);
- AssertWriteReturns(data, len, expected_rv2);
- }
- void SequencedSocketDataTest::ReentrantAsyncWriteCallback(
- const char* data,
- int len,
- CompletionOnceCallback callback,
- int expected_rv,
- int rv) {
- EXPECT_EQ(expected_rv, rv);
- scoped_refptr<IOBuffer> write_buf = base::MakeRefCounted<IOBuffer>(len);
- memcpy(write_buf->data(), data, len);
- EXPECT_THAT(sock_->Write(write_buf.get(), len, std::move(callback),
- TRAFFIC_ANNOTATION_FOR_TESTS),
- IsError(ERR_IO_PENDING));
- }
- void SequencedSocketDataTest::FailingCompletionCallback(int rv) {
- ADD_FAILURE() << "Callback should not have been invoked";
- }
- // ----------- Read
- TEST_F(SequencedSocketDataTest, SingleSyncRead) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
- };
- Initialize(reads, base::span<MockWrite>());
- AssertSyncReadEquals(kMsg1, kLen1);
- }
- TEST_F(SequencedSocketDataTest, MultipleSyncReads) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
- MockRead(SYNCHRONOUS, kMsg2, kLen2, 1),
- MockRead(SYNCHRONOUS, kMsg3, kLen3, 2),
- MockRead(SYNCHRONOUS, kMsg3, kLen3, 3),
- MockRead(SYNCHRONOUS, kMsg2, kLen2, 4),
- MockRead(SYNCHRONOUS, kMsg3, kLen3, 5),
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 6),
- };
- Initialize(reads, base::span<MockWrite>());
- AssertSyncReadEquals(kMsg1, kLen1);
- AssertSyncReadEquals(kMsg2, kLen2);
- AssertSyncReadEquals(kMsg3, kLen3);
- AssertSyncReadEquals(kMsg3, kLen3);
- AssertSyncReadEquals(kMsg2, kLen2);
- AssertSyncReadEquals(kMsg3, kLen3);
- AssertSyncReadEquals(kMsg1, kLen1);
- }
- TEST_F(SequencedSocketDataTest, SingleAsyncRead) {
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0),
- };
- Initialize(reads, base::span<MockWrite>());
- AssertAsyncReadEquals(kMsg1, kLen1);
- }
- TEST_F(SequencedSocketDataTest, MultipleAsyncReads) {
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0),
- MockRead(ASYNC, kMsg2, kLen2, 1),
- MockRead(ASYNC, kMsg3, kLen3, 2),
- MockRead(ASYNC, kMsg3, kLen3, 3),
- MockRead(ASYNC, kMsg2, kLen2, 4),
- MockRead(ASYNC, kMsg3, kLen3, 5),
- MockRead(ASYNC, kMsg1, kLen1, 6),
- };
- Initialize(reads, base::span<MockWrite>());
- AssertAsyncReadEquals(kMsg1, kLen1);
- AssertAsyncReadEquals(kMsg2, kLen2);
- AssertAsyncReadEquals(kMsg3, kLen3);
- AssertAsyncReadEquals(kMsg3, kLen3);
- AssertAsyncReadEquals(kMsg2, kLen2);
- AssertAsyncReadEquals(kMsg3, kLen3);
- AssertAsyncReadEquals(kMsg1, kLen1);
- }
- TEST_F(SequencedSocketDataTest, MixedReads) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
- MockRead(ASYNC, kMsg2, kLen2, 1),
- MockRead(SYNCHRONOUS, kMsg3, kLen3, 2),
- MockRead(ASYNC, kMsg3, kLen3, 3),
- MockRead(SYNCHRONOUS, kMsg2, kLen2, 4),
- MockRead(ASYNC, kMsg3, kLen3, 5),
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 6),
- };
- Initialize(reads, base::span<MockWrite>());
- AssertSyncReadEquals(kMsg1, kLen1);
- AssertAsyncReadEquals(kMsg2, kLen2);
- AssertSyncReadEquals(kMsg3, kLen3);
- AssertAsyncReadEquals(kMsg3, kLen3);
- AssertSyncReadEquals(kMsg2, kLen2);
- AssertAsyncReadEquals(kMsg3, kLen3);
- AssertSyncReadEquals(kMsg1, kLen1);
- }
- TEST_F(SequencedSocketDataTest, SyncReadFromCompletionCallback) {
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0), MockRead(SYNCHRONOUS, kMsg2, kLen2, 1),
- };
- Initialize(reads, base::span<MockWrite>());
- read_buf_ = base::MakeRefCounted<IOBuffer>(kLen1);
- ASSERT_EQ(
- ERR_IO_PENDING,
- sock_->Read(
- read_buf_.get(), kLen1,
- base::BindOnce(&SequencedSocketDataTest::ReentrantReadCallback,
- base::Unretained(this), kMsg1, kLen1, kLen2, kLen2)));
- base::RunLoop().RunUntilIdle();
- AssertReadBufferEquals(kMsg2, kLen2);
- }
- TEST_F(SequencedSocketDataTest, ManyReentrantReads) {
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0),
- MockRead(ASYNC, kMsg2, kLen2, 1),
- MockRead(ASYNC, kMsg3, kLen3, 2),
- MockRead(ASYNC, kMsg4, kLen4, 3),
- };
- Initialize(reads, base::span<MockWrite>());
- read_buf_ = base::MakeRefCounted<IOBuffer>(kLen4);
- ReentrantHelper helper3(sock_.get());
- helper3.SetExpectedRead(kMsg3, kLen3);
- helper3.SetInvokeRead(read_buf_, kLen4, ERR_IO_PENDING,
- read_callback_.callback());
- ReentrantHelper helper2(sock_.get());
- helper2.SetExpectedRead(kMsg2, kLen2);
- helper2.SetInvokeRead(helper3.read_buf(), kLen3, ERR_IO_PENDING,
- helper3.callback());
- ReentrantHelper helper(sock_.get());
- helper.SetExpectedRead(kMsg1, kLen1);
- helper.SetInvokeRead(helper2.read_buf(), kLen2, ERR_IO_PENDING,
- helper2.callback());
- sock_->Read(helper.read_buf().get(), kLen1, helper.callback());
- ASSERT_EQ(kLen4, read_callback_.WaitForResult());
- AssertReadBufferEquals(kMsg4, kLen4);
- }
- TEST_F(SequencedSocketDataTest, AsyncReadFromCompletionCallback) {
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0), MockRead(ASYNC, kMsg2, kLen2, 1),
- };
- Initialize(reads, base::span<MockWrite>());
- read_buf_ = base::MakeRefCounted<IOBuffer>(kLen1);
- ASSERT_EQ(ERR_IO_PENDING,
- sock_->Read(
- read_buf_.get(), kLen1,
- base::BindOnce(&SequencedSocketDataTest::ReentrantReadCallback,
- base::Unretained(this), kMsg1, kLen1, kLen2,
- ERR_IO_PENDING)));
- ASSERT_FALSE(read_callback_.have_result());
- ASSERT_EQ(kLen2, read_callback_.WaitForResult());
- AssertReadBufferEquals(kMsg2, kLen2);
- }
- TEST_F(SequencedSocketDataTest, SingleSyncReadTooEarly) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 1),
- };
- MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, 0)};
- Initialize(reads, writes);
- EXPECT_NONFATAL_FAILURE(AssertReadReturns(kLen1, ERR_UNEXPECTED),
- "Unable to perform synchronous IO while stopped");
- set_expect_eof(false);
- }
- TEST_F(SequencedSocketDataTest, SingleSyncReadSmallBuffer) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
- };
- Initialize(reads, base::span<MockWrite>());
- // Read the first chunk.
- AssertReadReturns(kLen1 - 1, kLen1 - 1);
- AssertReadBufferEquals(kMsg1, kLen1 - 1);
- // Then read the second chunk.
- AssertReadReturns(1, 1);
- AssertReadBufferEquals(kMsg1 + kLen1 - 1, 1);
- }
- TEST_F(SequencedSocketDataTest, SingleSyncReadLargeBuffer) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
- };
- Initialize(reads, base::span<MockWrite>());
- scoped_refptr<IOBuffer> read_buf = base::MakeRefCounted<IOBuffer>(2 * kLen1);
- ASSERT_EQ(kLen1, sock_->Read(read_buf.get(), 2 * kLen1, failing_callback()));
- ASSERT_EQ(std::string(kMsg1, kLen1), std::string(read_buf->data(), kLen1));
- }
- TEST_F(SequencedSocketDataTest, SingleAsyncReadLargeBuffer) {
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0),
- };
- Initialize(reads, base::span<MockWrite>());
- scoped_refptr<IOBuffer> read_buf = base::MakeRefCounted<IOBuffer>(2 * kLen1);
- ASSERT_EQ(ERR_IO_PENDING,
- sock_->Read(read_buf.get(), 2 * kLen1, read_callback_.callback()));
- ASSERT_EQ(kLen1, read_callback_.WaitForResult());
- ASSERT_EQ(std::string(kMsg1, kLen1), std::string(read_buf->data(), kLen1));
- }
- TEST_F(SequencedSocketDataTest, HangingRead) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
- };
- Initialize(reads, base::span<MockWrite>());
- scoped_refptr<IOBuffer> read_buf = base::MakeRefCounted<IOBuffer>(1);
- ASSERT_EQ(ERR_IO_PENDING,
- sock_->Read(read_buf.get(), 1, read_callback_.callback()));
- ASSERT_FALSE(read_callback_.have_result());
- // Even though the read is scheduled to complete at sequence number 0,
- // verify that the read callback in never called.
- base::RunLoop().RunUntilIdle();
- ASSERT_FALSE(read_callback_.have_result());
- }
- // ----------- Write
- TEST_F(SequencedSocketDataTest, SingleSyncWriteTooEarly) {
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 1),
- };
- MockRead reads[] = {MockRead(SYNCHRONOUS, 0, 0)};
- Initialize(reads, writes);
- EXPECT_NONFATAL_FAILURE(AssertWriteReturns(kMsg1, kLen1, ERR_UNEXPECTED),
- "Unable to perform synchronous IO while stopped");
- set_expect_eof(false);
- }
- TEST_F(SequencedSocketDataTest, SingleSyncWriteTooSmall) {
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0),
- };
- Initialize(base::span<MockRead>(), writes);
- // Expecting too small of a write triggers multiple expectation failures.
- //
- // The gtest infrastructure does not have a macro similar to
- // EXPECT_NONFATAL_FAILURE which works when there is more than one
- // failure.
- //
- // However, tests can gather the TestPartResultArray and directly
- // validate the test failures. That's what the rest of this test does.
- ::testing::TestPartResultArray gtest_failures;
- {
- ::testing::ScopedFakeTestPartResultReporter gtest_reporter(
- ::testing::ScopedFakeTestPartResultReporter::
- INTERCEPT_ONLY_CURRENT_THREAD,
- >est_failures);
- AssertSyncWriteEquals(kMsg1, kLen1 - 1);
- }
- static const char* kExpectedFailures[] = {
- "Expected: (data.length()) >= (expected_data.length())",
- "Value of: actual_data == expected_data\n Actual: false\nExpected: true",
- "Expected equality of these values:\n rv"};
- ASSERT_EQ(std::size(kExpectedFailures),
- static_cast<size_t>(gtest_failures.size()));
- for (int i = 0; i < gtest_failures.size(); ++i) {
- const ::testing::TestPartResult& result =
- gtest_failures.GetTestPartResult(i);
- EXPECT_TRUE(strstr(result.message(), kExpectedFailures[i]) != nullptr);
- }
- set_expect_eof(false);
- }
- TEST_F(SequencedSocketDataTest, SingleSyncPartialWrite) {
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg1, kLen1 - 1, 0),
- MockWrite(SYNCHRONOUS, kMsg1 + kLen1 - 1, 1, 1),
- };
- Initialize(base::span<MockRead>(), writes);
- // Attempt to write all of the message, but only some will be written.
- AssertSyncWriteEquals(kMsg1, kLen1 - 1);
- // Write the rest of the message.
- AssertSyncWriteEquals(kMsg1 + kLen1 - 1, 1);
- }
- TEST_F(SequencedSocketDataTest, SingleSyncWrite) {
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0),
- };
- Initialize(base::span<MockRead>(), writes);
- AssertSyncWriteEquals(kMsg1, kLen1);
- }
- TEST_F(SequencedSocketDataTest, MultipleSyncWrites) {
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0),
- MockWrite(SYNCHRONOUS, kMsg2, kLen2, 1),
- MockWrite(SYNCHRONOUS, kMsg3, kLen3, 2),
- MockWrite(SYNCHRONOUS, kMsg3, kLen3, 3),
- MockWrite(SYNCHRONOUS, kMsg2, kLen2, 4),
- MockWrite(SYNCHRONOUS, kMsg3, kLen3, 5),
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 6),
- };
- Initialize(base::span<MockRead>(), writes);
- AssertSyncWriteEquals(kMsg1, kLen1);
- AssertSyncWriteEquals(kMsg2, kLen2);
- AssertSyncWriteEquals(kMsg3, kLen3);
- AssertSyncWriteEquals(kMsg3, kLen3);
- AssertSyncWriteEquals(kMsg2, kLen2);
- AssertSyncWriteEquals(kMsg3, kLen3);
- AssertSyncWriteEquals(kMsg1, kLen1);
- }
- TEST_F(SequencedSocketDataTest, SingleAsyncWrite) {
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg1, kLen1, 0),
- };
- Initialize(base::span<MockRead>(), writes);
- AssertAsyncWriteEquals(kMsg1, kLen1);
- }
- TEST_F(SequencedSocketDataTest, MultipleAsyncWrites) {
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg1, kLen1, 0),
- MockWrite(ASYNC, kMsg2, kLen2, 1),
- MockWrite(ASYNC, kMsg3, kLen3, 2),
- MockWrite(ASYNC, kMsg3, kLen3, 3),
- MockWrite(ASYNC, kMsg2, kLen2, 4),
- MockWrite(ASYNC, kMsg3, kLen3, 5),
- MockWrite(ASYNC, kMsg1, kLen1, 6),
- };
- Initialize(base::span<MockRead>(), writes);
- AssertAsyncWriteEquals(kMsg1, kLen1);
- AssertAsyncWriteEquals(kMsg2, kLen2);
- AssertAsyncWriteEquals(kMsg3, kLen3);
- AssertAsyncWriteEquals(kMsg3, kLen3);
- AssertAsyncWriteEquals(kMsg2, kLen2);
- AssertAsyncWriteEquals(kMsg3, kLen3);
- AssertAsyncWriteEquals(kMsg1, kLen1);
- }
- TEST_F(SequencedSocketDataTest, MixedWrites) {
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0),
- MockWrite(ASYNC, kMsg2, kLen2, 1),
- MockWrite(SYNCHRONOUS, kMsg3, kLen3, 2),
- MockWrite(ASYNC, kMsg3, kLen3, 3),
- MockWrite(SYNCHRONOUS, kMsg2, kLen2, 4),
- MockWrite(ASYNC, kMsg3, kLen3, 5),
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 6),
- };
- Initialize(base::span<MockRead>(), writes);
- AssertSyncWriteEquals(kMsg1, kLen1);
- AssertAsyncWriteEquals(kMsg2, kLen2);
- AssertSyncWriteEquals(kMsg3, kLen3);
- AssertAsyncWriteEquals(kMsg3, kLen3);
- AssertSyncWriteEquals(kMsg2, kLen2);
- AssertAsyncWriteEquals(kMsg3, kLen3);
- AssertSyncWriteEquals(kMsg1, kLen1);
- }
- TEST_F(SequencedSocketDataTest, SyncWriteFromCompletionCallback) {
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg1, kLen1, 0),
- MockWrite(SYNCHRONOUS, kMsg2, kLen2, 1),
- };
- Initialize(base::span<MockRead>(), writes);
- scoped_refptr<IOBuffer> write_buf = base::MakeRefCounted<IOBuffer>(kLen1);
- memcpy(write_buf->data(), kMsg1, kLen1);
- ASSERT_EQ(
- ERR_IO_PENDING,
- sock_->Write(
- write_buf.get(), kLen1,
- base::BindOnce(&SequencedSocketDataTest::ReentrantWriteCallback,
- base::Unretained(this), kLen1, kMsg2, kLen2, kLen2),
- TRAFFIC_ANNOTATION_FOR_TESTS));
- base::RunLoop().RunUntilIdle();
- }
- TEST_F(SequencedSocketDataTest, AsyncWriteFromCompletionCallback) {
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg1, kLen1, 0), MockWrite(ASYNC, kMsg2, kLen2, 1),
- };
- Initialize(base::span<MockRead>(), writes);
- scoped_refptr<IOBuffer> write_buf = base::MakeRefCounted<IOBuffer>(kLen1);
- memcpy(write_buf->data(), kMsg1, kLen1);
- ASSERT_EQ(ERR_IO_PENDING,
- sock_->Write(
- write_buf.get(), kLen1,
- base::BindOnce(&SequencedSocketDataTest::ReentrantWriteCallback,
- base::Unretained(this), kLen1, kMsg2, kLen2,
- ERR_IO_PENDING),
- TRAFFIC_ANNOTATION_FOR_TESTS));
- ASSERT_FALSE(write_callback_.have_result());
- ASSERT_EQ(kLen2, write_callback_.WaitForResult());
- }
- TEST_F(SequencedSocketDataTest, ManyReentrantWrites) {
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg1, kLen1, 0),
- MockWrite(ASYNC, kMsg2, kLen2, 1),
- MockWrite(ASYNC, kMsg3, kLen3, 2),
- MockWrite(ASYNC, kMsg4, kLen4, 3),
- };
- Initialize(base::span<MockRead>(), writes);
- ReentrantHelper helper3(sock_.get());
- helper3.SetExpectedWrite(kLen3);
- helper3.SetInvokeWrite(kMsg4, kLen4, ERR_IO_PENDING,
- write_callback_.callback());
- ReentrantHelper helper2(sock_.get());
- helper2.SetExpectedWrite(kLen2);
- helper2.SetInvokeWrite(kMsg3, kLen3, ERR_IO_PENDING, helper3.callback());
- ReentrantHelper helper(sock_.get());
- helper.SetExpectedWrite(kLen1);
- helper.SetInvokeWrite(kMsg2, kLen2, ERR_IO_PENDING, helper2.callback());
- scoped_refptr<IOBuffer> write_buf = base::MakeRefCounted<IOBuffer>(kLen1);
- memcpy(write_buf->data(), kMsg1, kLen1);
- sock_->Write(write_buf.get(), kLen1, helper.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
- ASSERT_EQ(kLen4, write_callback_.WaitForResult());
- }
- // ----------- Mixed Reads and Writes
- TEST_F(SequencedSocketDataTest, MixedSyncOperations) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
- MockRead(SYNCHRONOUS, kMsg2, kLen2, 3),
- };
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg2, kLen2, 1),
- MockWrite(SYNCHRONOUS, kMsg3, kLen3, 2),
- };
- Initialize(reads, writes);
- AssertSyncReadEquals(kMsg1, kLen1);
- AssertSyncWriteEquals(kMsg2, kLen2);
- AssertSyncWriteEquals(kMsg3, kLen3);
- AssertSyncReadEquals(kMsg2, kLen2);
- }
- TEST_F(SequencedSocketDataTest, MixedAsyncOperations) {
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0), MockRead(ASYNC, kMsg2, kLen2, 3),
- };
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg2, kLen2, 1), MockWrite(ASYNC, kMsg3, kLen3, 2),
- };
- Initialize(reads, writes);
- AssertAsyncReadEquals(kMsg1, kLen1);
- AssertAsyncWriteEquals(kMsg2, kLen2);
- AssertAsyncWriteEquals(kMsg3, kLen3);
- AssertAsyncReadEquals(kMsg2, kLen2);
- }
- TEST_F(SequencedSocketDataTest, InterleavedAsyncOperations) {
- // Order of completion is read, write, write, read.
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0), MockRead(ASYNC, kMsg2, kLen2, 3),
- };
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg2, kLen2, 1), MockWrite(ASYNC, kMsg3, kLen3, 2),
- };
- Initialize(reads, writes);
- // Issue the write, which will block until the read completes.
- AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
- // Issue the read which will return first.
- AssertReadReturns(kLen1, ERR_IO_PENDING);
- ASSERT_EQ(kLen1, read_callback_.WaitForResult());
- AssertReadBufferEquals(kMsg1, kLen1);
- // Run posted OnWriteComplete().
- base::RunLoop().RunUntilIdle();
- ASSERT_TRUE(write_callback_.have_result());
- ASSERT_EQ(kLen2, write_callback_.WaitForResult());
- // Issue the read, which will block until the write completes.
- AssertReadReturns(kLen2, ERR_IO_PENDING);
- // Issue the writes which will return first.
- AssertWriteReturns(kMsg3, kLen3, ERR_IO_PENDING);
- ASSERT_EQ(kLen3, write_callback_.WaitForResult());
- ASSERT_EQ(kLen2, read_callback_.WaitForResult());
- AssertReadBufferEquals(kMsg2, kLen2);
- }
- TEST_F(SequencedSocketDataTest, InterleavedMixedOperations) {
- // Order of completion is read, write, write, read.
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
- MockRead(ASYNC, kMsg2, kLen2, 3),
- MockRead(ASYNC, kMsg3, kLen3, 5),
- };
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg2, kLen2, 1),
- MockWrite(SYNCHRONOUS, kMsg3, kLen3, 2),
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 4),
- };
- Initialize(reads, writes);
- // Issue the write, which will block until the read completes.
- AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
- // Issue the writes which will complete immediately.
- AssertSyncReadEquals(kMsg1, kLen1);
- ASSERT_FALSE(write_callback_.have_result());
- ASSERT_EQ(kLen2, write_callback_.WaitForResult());
- // Issue the read, which will block until the write completes.
- AssertReadReturns(kLen2, ERR_IO_PENDING);
- // Issue the writes which will complete immediately.
- AssertSyncWriteEquals(kMsg3, kLen3);
- ASSERT_FALSE(read_callback_.have_result());
- ASSERT_EQ(kLen2, read_callback_.WaitForResult());
- AssertReadBufferEquals(kMsg2, kLen2);
- // Issue the read, which will block until the write completes.
- AssertReadReturns(kLen2, ERR_IO_PENDING);
- // Issue the writes which will complete immediately.
- AssertSyncWriteEquals(kMsg1, kLen1);
- ASSERT_FALSE(read_callback_.have_result());
- ASSERT_EQ(kLen3, read_callback_.WaitForResult());
- AssertReadBufferEquals(kMsg3, kLen3);
- }
- TEST_F(SequencedSocketDataTest, AsyncReadFromWriteCompletionCallback) {
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg1, kLen1, 0),
- };
- MockRead reads[] = {
- MockRead(ASYNC, kMsg2, kLen2, 1),
- };
- Initialize(reads, writes);
- scoped_refptr<IOBuffer> write_buf = base::MakeRefCounted<IOBuffer>(kLen1);
- memcpy(write_buf->data(), kMsg1, kLen1);
- ASSERT_EQ(
- ERR_IO_PENDING,
- sock_->Write(
- write_buf.get(), kLen1,
- base::BindOnce(&SequencedSocketDataTest::ReentrantAsyncReadCallback,
- base::Unretained(this), kLen1, kLen2),
- TRAFFIC_ANNOTATION_FOR_TESTS));
- ASSERT_FALSE(read_callback_.have_result());
- ASSERT_EQ(kLen2, read_callback_.WaitForResult());
- AssertReadBufferEquals(kMsg2, kLen2);
- }
- TEST_F(SequencedSocketDataTest, AsyncWriteFromReadCompletionCallback) {
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg2, kLen2, 1),
- };
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0),
- };
- Initialize(reads, writes);
- scoped_refptr<IOBuffer> read_buf = base::MakeRefCounted<IOBuffer>(kLen1);
- ASSERT_EQ(
- ERR_IO_PENDING,
- sock_->Read(
- read_buf.get(), kLen1,
- base::BindOnce(&SequencedSocketDataTest::ReentrantAsyncWriteCallback,
- base::Unretained(this), kMsg2, kLen2,
- write_callback_.callback(), kLen1)));
- ASSERT_FALSE(write_callback_.have_result());
- ASSERT_EQ(kLen2, write_callback_.WaitForResult());
- }
- TEST_F(SequencedSocketDataTest, MixedReentrantOperations) {
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg1, kLen1, 0), MockWrite(ASYNC, kMsg3, kLen3, 2),
- };
- MockRead reads[] = {
- MockRead(ASYNC, kMsg2, kLen2, 1), MockRead(ASYNC, kMsg4, kLen4, 3),
- };
- Initialize(reads, writes);
- read_buf_ = base::MakeRefCounted<IOBuffer>(kLen4);
- ReentrantHelper helper3(sock_.get());
- helper3.SetExpectedWrite(kLen3);
- helper3.SetInvokeRead(read_buf_, kLen4, ERR_IO_PENDING,
- read_callback_.callback());
- ReentrantHelper helper2(sock_.get());
- helper2.SetExpectedRead(kMsg2, kLen2);
- helper2.SetInvokeWrite(kMsg3, kLen3, ERR_IO_PENDING, helper3.callback());
- ReentrantHelper helper(sock_.get());
- helper.SetExpectedWrite(kLen1);
- helper.SetInvokeRead(helper2.read_buf(), kLen2, ERR_IO_PENDING,
- helper2.callback());
- scoped_refptr<IOBuffer> write_buf = base::MakeRefCounted<IOBuffer>(kLen1);
- memcpy(write_buf->data(), kMsg1, kLen1);
- sock_->Write(write_buf.get(), kLen1, helper.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
- ASSERT_EQ(kLen4, read_callback_.WaitForResult());
- }
- TEST_F(SequencedSocketDataTest, MixedReentrantOperationsThenSynchronousRead) {
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg1, kLen1, 0), MockWrite(ASYNC, kMsg3, kLen3, 2),
- };
- MockRead reads[] = {
- MockRead(ASYNC, kMsg2, kLen2, 1), MockRead(SYNCHRONOUS, kMsg4, kLen4, 3),
- };
- Initialize(reads, writes);
- read_buf_ = base::MakeRefCounted<IOBuffer>(kLen4);
- ReentrantHelper helper3(sock_.get());
- helper3.SetExpectedWrite(kLen3);
- helper3.SetInvokeRead(read_buf_, kLen4, kLen4, failing_callback());
- ReentrantHelper helper2(sock_.get());
- helper2.SetExpectedRead(kMsg2, kLen2);
- helper2.SetInvokeWrite(kMsg3, kLen3, ERR_IO_PENDING, helper3.callback());
- ReentrantHelper helper(sock_.get());
- helper.SetExpectedWrite(kLen1);
- helper.SetInvokeRead(helper2.read_buf(), kLen2, ERR_IO_PENDING,
- helper2.callback());
- scoped_refptr<IOBuffer> write_buf = base::MakeRefCounted<IOBuffer>(kLen1);
- memcpy(write_buf->data(), kMsg1, kLen1);
- ASSERT_EQ(ERR_IO_PENDING,
- sock_->Write(write_buf.get(), kLen1, helper.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS));
- base::RunLoop().RunUntilIdle();
- AssertReadBufferEquals(kMsg4, kLen4);
- }
- TEST_F(SequencedSocketDataTest, MixedReentrantOperationsThenSynchronousWrite) {
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg2, kLen2, 1),
- MockWrite(SYNCHRONOUS, kMsg4, kLen4, 3),
- };
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0), MockRead(ASYNC, kMsg3, kLen3, 2),
- };
- Initialize(reads, writes);
- read_buf_ = base::MakeRefCounted<IOBuffer>(kLen4);
- ReentrantHelper helper3(sock_.get());
- helper3.SetExpectedRead(kMsg3, kLen3);
- helper3.SetInvokeWrite(kMsg4, kLen4, kLen4, failing_callback());
- ReentrantHelper helper2(sock_.get());
- helper2.SetExpectedWrite(kLen2);
- helper2.SetInvokeRead(helper3.read_buf(), kLen3, ERR_IO_PENDING,
- helper3.callback());
- ReentrantHelper helper(sock_.get());
- helper.SetExpectedRead(kMsg1, kLen1);
- helper.SetInvokeWrite(kMsg2, kLen2, ERR_IO_PENDING, helper2.callback());
- ASSERT_EQ(ERR_IO_PENDING,
- sock_->Read(helper.read_buf().get(), kLen1, helper.callback()));
- base::RunLoop().RunUntilIdle();
- }
- // Test the basic case where a read is paused.
- TEST_F(SequencedSocketDataTest, PauseAndResume_PauseRead) {
- MockRead reads[] = {
- MockRead(ASYNC, ERR_IO_PENDING, 0), MockRead(ASYNC, kMsg1, kLen1, 1),
- };
- Initialize(reads, base::span<MockWrite>());
- AssertReadReturns(kLen1, ERR_IO_PENDING);
- ASSERT_FALSE(read_callback_.have_result());
- RunUntilPaused();
- ASSERT_TRUE(IsPaused());
- // Spinning the message loop should do nothing.
- base::RunLoop().RunUntilIdle();
- ASSERT_FALSE(read_callback_.have_result());
- ASSERT_TRUE(IsPaused());
- Resume();
- ASSERT_FALSE(IsPaused());
- ASSERT_TRUE(read_callback_.have_result());
- ASSERT_EQ(kLen1, read_callback_.WaitForResult());
- AssertReadBufferEquals(kMsg1, kLen1);
- }
- // Test the case where a read that will be paused is started before write that
- // completes before the pause.
- TEST_F(SequencedSocketDataTest, PauseAndResume_WritePauseRead) {
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0),
- };
- MockRead reads[] = {
- MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, kMsg2, kLen2, 2),
- };
- Initialize(reads, writes);
- AssertReadReturns(kLen2, ERR_IO_PENDING);
- ASSERT_FALSE(read_callback_.have_result());
- // Nothing should happen until the write starts.
- base::RunLoop().RunUntilIdle();
- ASSERT_FALSE(read_callback_.have_result());
- ASSERT_FALSE(IsPaused());
- AssertSyncWriteEquals(kMsg1, kLen1);
- RunUntilPaused();
- ASSERT_FALSE(read_callback_.have_result());
- ASSERT_TRUE(IsPaused());
- // Spinning the message loop should do nothing.
- base::RunLoop().RunUntilIdle();
- ASSERT_FALSE(read_callback_.have_result());
- ASSERT_TRUE(IsPaused());
- Resume();
- ASSERT_FALSE(IsPaused());
- ASSERT_TRUE(read_callback_.have_result());
- ASSERT_EQ(kLen2, read_callback_.WaitForResult());
- AssertReadBufferEquals(kMsg2, kLen2);
- }
- // Test the basic case where a write is paused.
- TEST_F(SequencedSocketDataTest, PauseAndResume_PauseWrite) {
- MockWrite writes[] = {
- MockWrite(ASYNC, ERR_IO_PENDING, 0), MockWrite(ASYNC, kMsg1, kLen1, 1),
- };
- Initialize(base::span<MockRead>(), writes);
- AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
- ASSERT_FALSE(write_callback_.have_result());
- RunUntilPaused();
- ASSERT_TRUE(IsPaused());
- // Spinning the message loop should do nothing.
- base::RunLoop().RunUntilIdle();
- ASSERT_FALSE(write_callback_.have_result());
- ASSERT_TRUE(IsPaused());
- Resume();
- ASSERT_FALSE(IsPaused());
- ASSERT_TRUE(write_callback_.have_result());
- ASSERT_EQ(kLen1, write_callback_.WaitForResult());
- }
- // Test the case where a write that will be paused is started before read that
- // completes before the pause.
- TEST_F(SequencedSocketDataTest, PauseAndResume_ReadPauseWrite) {
- MockWrite writes[] = {
- MockWrite(ASYNC, ERR_IO_PENDING, 1), MockWrite(ASYNC, kMsg2, kLen2, 2),
- };
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
- };
- Initialize(reads, writes);
- AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
- ASSERT_FALSE(write_callback_.have_result());
- // Nothing should happen until the write starts.
- base::RunLoop().RunUntilIdle();
- ASSERT_FALSE(write_callback_.have_result());
- ASSERT_FALSE(IsPaused());
- AssertSyncReadEquals(kMsg1, kLen1);
- RunUntilPaused();
- ASSERT_FALSE(write_callback_.have_result());
- ASSERT_TRUE(IsPaused());
- // Spinning the message loop should do nothing.
- base::RunLoop().RunUntilIdle();
- ASSERT_FALSE(write_callback_.have_result());
- ASSERT_TRUE(IsPaused());
- Resume();
- ASSERT_FALSE(IsPaused());
- ASSERT_TRUE(write_callback_.have_result());
- ASSERT_EQ(kLen2, write_callback_.WaitForResult());
- }
- } // namespace
- } // namespace net
|