| Index: net/websockets/websocket_channel_test.cc
|
| diff --git a/net/websockets/websocket_channel_test.cc b/net/websockets/websocket_channel_test.cc
|
| index b9a8c3043414bb445fac884d6fa2665ba39ccc83..f9ea8de2cd75005ac9b7e90314f1813773ba159f 100644
|
| --- a/net/websockets/websocket_channel_test.cc
|
| +++ b/net/websockets/websocket_channel_test.cc
|
| @@ -16,6 +16,7 @@
|
| #include "base/location.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/memory/scoped_vector.h"
|
| +#include "base/memory/weak_ptr.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/safe_numerics.h"
|
| #include "base/strings/string_piece.h"
|
| @@ -85,6 +86,7 @@ std::ostream& operator<<(std::ostream& os,
|
| namespace {
|
|
|
| using ::testing::AnyNumber;
|
| +using ::testing::DefaultValue;
|
| using ::testing::InSequence;
|
| using ::testing::MockFunction;
|
| using ::testing::Return;
|
| @@ -116,29 +118,50 @@ const size_t kDefaultInitialQuota = 1 << 17;
|
| // kDefaultSendQuotaLowWaterMark change.
|
| const size_t kDefaultQuotaRefreshTrigger = (1 << 16) + 1;
|
|
|
| +typedef WebSocketEventInterface::ChannelState ChannelState;
|
| +const ChannelState CHANNEL_ALIVE = WebSocketEventInterface::CHANNEL_ALIVE;
|
| +const ChannelState CHANNEL_DELETED = WebSocketEventInterface::CHANNEL_DELETED;
|
| +
|
| +// This typedef mainly exists to avoid having to repeat the "NOLINT" incantation
|
| +// all over the place.
|
| +typedef MockFunction<void(int)> Checkpoint; // NOLINT
|
| +
|
| // This mock is for testing expectations about how the EventInterface is used.
|
| class MockWebSocketEventInterface : public WebSocketEventInterface {
|
| public:
|
| - MOCK_METHOD2(OnAddChannelResponse, void(bool, const std::string&));
|
| + MOCK_METHOD2(OnAddChannelResponse,
|
| + ChannelState(bool, const std::string&)); // NOLINT
|
| MOCK_METHOD3(OnDataFrame,
|
| - void(bool, WebSocketMessageType, const std::vector<char>&));
|
| - MOCK_METHOD1(OnFlowControl, void(int64));
|
| - MOCK_METHOD0(OnClosingHandshake, void(void));
|
| - MOCK_METHOD2(OnDropChannel, void(uint16, const std::string&));
|
| + ChannelState(bool,
|
| + WebSocketMessageType,
|
| + const std::vector<char>&)); // NOLINT
|
| + MOCK_METHOD1(OnFlowControl, ChannelState(int64)); // NOLINT
|
| + MOCK_METHOD0(OnClosingHandshake, ChannelState(void)); // NOLINT
|
| + MOCK_METHOD2(OnDropChannel,
|
| + ChannelState(uint16, const std::string&)); // NOLINT
|
| };
|
|
|
| // This fake EventInterface is for tests which need a WebSocketEventInterface
|
| // implementation but are not verifying how it is used.
|
| class FakeWebSocketEventInterface : public WebSocketEventInterface {
|
| - virtual void OnAddChannelResponse(
|
| + virtual ChannelState OnAddChannelResponse(
|
| bool fail,
|
| - const std::string& selected_protocol) OVERRIDE {}
|
| - virtual void OnDataFrame(bool fin,
|
| - WebSocketMessageType type,
|
| - const std::vector<char>& data) OVERRIDE {}
|
| - virtual void OnFlowControl(int64 quota) OVERRIDE {}
|
| - virtual void OnClosingHandshake() OVERRIDE {}
|
| - virtual void OnDropChannel(uint16 code, const std::string& reason) OVERRIDE {}
|
| + const std::string& selected_protocol) OVERRIDE {
|
| + return fail ? CHANNEL_DELETED : CHANNEL_ALIVE;
|
| + }
|
| + virtual ChannelState OnDataFrame(bool fin,
|
| + WebSocketMessageType type,
|
| + const std::vector<char>& data) OVERRIDE {
|
| + return CHANNEL_ALIVE;
|
| + }
|
| + virtual ChannelState OnFlowControl(int64 quota) OVERRIDE {
|
| + return CHANNEL_ALIVE;
|
| + }
|
| + virtual ChannelState OnClosingHandshake() OVERRIDE { return CHANNEL_ALIVE; }
|
| + virtual ChannelState OnDropChannel(uint16 code,
|
| + const std::string& reason) OVERRIDE {
|
| + return CHANNEL_DELETED;
|
| + }
|
| };
|
|
|
| // This fake WebSocketStream is for tests that require a WebSocketStream but are
|
| @@ -549,15 +572,28 @@ class EchoeyFakeWebSocketStream : public FakeWebSocketStream {
|
| // A FakeWebSocketStream where writes trigger a connection reset.
|
| // This differs from UnWriteableFakeWebSocketStream in that it is asynchronous
|
| // and triggers ReadFrames to return a reset as well. Tests using this need to
|
| -// run the message loop.
|
| +// run the message loop. There are two tricky parts here:
|
| +// 1. Calling the write callback may call Close(), after which the read callback
|
| +// should not be called.
|
| +// 2. Calling either callback may delete the stream altogether.
|
| class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream {
|
| public:
|
| + ResetOnWriteFakeWebSocketStream() : closed_(false), weak_ptr_factory_(this) {}
|
| +
|
| virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames,
|
| const CompletionCallback& callback) OVERRIDE {
|
| base::MessageLoop::current()->PostTask(
|
| - FROM_HERE, base::Bind(callback, ERR_CONNECTION_RESET));
|
| + FROM_HERE,
|
| + base::Bind(&ResetOnWriteFakeWebSocketStream::CallCallbackUnlessClosed,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + callback,
|
| + ERR_CONNECTION_RESET));
|
| base::MessageLoop::current()->PostTask(
|
| - FROM_HERE, base::Bind(read_callback_, ERR_CONNECTION_RESET));
|
| + FROM_HERE,
|
| + base::Bind(&ResetOnWriteFakeWebSocketStream::CallCallbackUnlessClosed,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + read_callback_,
|
| + ERR_CONNECTION_RESET));
|
| return ERR_IO_PENDING;
|
| }
|
|
|
| @@ -567,8 +603,19 @@ class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream {
|
| return ERR_IO_PENDING;
|
| }
|
|
|
| + virtual void Close() OVERRIDE { closed_ = true; }
|
| +
|
| private:
|
| + void CallCallbackUnlessClosed(const CompletionCallback& callback, int value) {
|
| + if (!closed_)
|
| + callback.Run(value);
|
| + }
|
| +
|
| CompletionCallback read_callback_;
|
| + bool closed_;
|
| + // An IO error can result in the socket being deleted, so we use weak pointers
|
| + // to ensure correct behaviour in that case.
|
| + base::WeakPtrFactory<ResetOnWriteFakeWebSocketStream> weak_ptr_factory_;
|
| };
|
|
|
| // This mock is for verifying that WebSocket protocol semantics are obeyed (to
|
| @@ -690,14 +737,41 @@ class WebSocketChannelTest : public ::testing::Test {
|
| scoped_ptr<WebSocketStream> stream_;
|
| };
|
|
|
| +// enum of WebSocketEventInterface calls. These are intended to be or'd together
|
| +// in order to instruct WebSocketChannelDeletingTest when it should fail.
|
| +enum EventInterfaceCall {
|
| + EVENT_ON_ADD_CHANNEL_RESPONSE = 0x1,
|
| + EVENT_ON_DATA_FRAME = 0x2,
|
| + EVENT_ON_FLOW_CONTROL = 0x4,
|
| + EVENT_ON_CLOSING_HANDSHAKE = 0x8,
|
| + EVENT_ON_DROP_CHANNEL = 0x10,
|
| +};
|
| +
|
| class WebSocketChannelDeletingTest : public WebSocketChannelTest {
|
| public:
|
| - void ResetChannel() { channel_.reset(); }
|
| + ChannelState DeleteIfDeleting(EventInterfaceCall call) {
|
| + if (deleting_ & call) {
|
| + channel_.reset();
|
| + return CHANNEL_DELETED;
|
| + } else {
|
| + return CHANNEL_ALIVE;
|
| + }
|
| + }
|
|
|
| protected:
|
| + WebSocketChannelDeletingTest()
|
| + : deleting_(EVENT_ON_ADD_CHANNEL_RESPONSE | EVENT_ON_DATA_FRAME |
|
| + EVENT_ON_FLOW_CONTROL |
|
| + EVENT_ON_CLOSING_HANDSHAKE |
|
| + EVENT_ON_DROP_CHANNEL) {}
|
| // Create a ChannelDeletingFakeWebSocketEventInterface. Defined out-of-line to
|
| // avoid circular dependency.
|
| virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE;
|
| +
|
| + // Tests can set deleting_ to a bitmap of EventInterfaceCall members that they
|
| + // want to cause Channel deletion. The default is for all calls to cause
|
| + // deletion.
|
| + int deleting_;
|
| };
|
|
|
| // A FakeWebSocketEventInterface that deletes the WebSocketChannel on failure to
|
| @@ -709,12 +783,29 @@ class ChannelDeletingFakeWebSocketEventInterface
|
| WebSocketChannelDeletingTest* fixture)
|
| : fixture_(fixture) {}
|
|
|
| - virtual void OnAddChannelResponse(
|
| + virtual ChannelState OnAddChannelResponse(
|
| bool fail,
|
| const std::string& selected_protocol) OVERRIDE {
|
| - if (fail) {
|
| - fixture_->ResetChannel();
|
| - }
|
| + return fixture_->DeleteIfDeleting(EVENT_ON_ADD_CHANNEL_RESPONSE);
|
| + }
|
| +
|
| + virtual ChannelState OnDataFrame(bool fin,
|
| + WebSocketMessageType type,
|
| + const std::vector<char>& data) OVERRIDE {
|
| + return fixture_->DeleteIfDeleting(EVENT_ON_DATA_FRAME);
|
| + }
|
| +
|
| + virtual ChannelState OnFlowControl(int64 quota) OVERRIDE {
|
| + return fixture_->DeleteIfDeleting(EVENT_ON_FLOW_CONTROL);
|
| + }
|
| +
|
| + virtual ChannelState OnClosingHandshake() OVERRIDE {
|
| + return fixture_->DeleteIfDeleting(EVENT_ON_CLOSING_HANDSHAKE);
|
| + }
|
| +
|
| + virtual ChannelState OnDropChannel(uint16 code,
|
| + const std::string& reason) OVERRIDE {
|
| + return fixture_->DeleteIfDeleting(EVENT_ON_DROP_CHANNEL);
|
| }
|
|
|
| private:
|
| @@ -734,7 +825,13 @@ WebSocketChannelDeletingTest::CreateEventInterface() {
|
| class WebSocketChannelEventInterfaceTest : public WebSocketChannelTest {
|
| protected:
|
| WebSocketChannelEventInterfaceTest()
|
| - : event_interface_(new StrictMock<MockWebSocketEventInterface>) {}
|
| + : event_interface_(new StrictMock<MockWebSocketEventInterface>) {
|
| + DefaultValue<ChannelState>::Set(CHANNEL_ALIVE);
|
| + ON_CALL(*event_interface_, OnAddChannelResponse(true, _))
|
| + .WillByDefault(Return(CHANNEL_DELETED));
|
| + ON_CALL(*event_interface_, OnDropChannel(_, _))
|
| + .WillByDefault(Return(CHANNEL_DELETED));
|
| + }
|
|
|
| // Tests using this fixture must set expectations on the event_interface_ mock
|
| // object before calling CreateChannelAndConnect() or
|
| @@ -779,18 +876,201 @@ TEST_F(WebSocketChannelTest, EverythingIsPassedToTheFactoryFunction) {
|
| connect_data_.factory.url_request_context);
|
| }
|
|
|
| -// The documentation for WebSocketEventInterface::OnAddChannelResponse() says
|
| -// that if the first argument is true, ie. the connection failed, then we can
|
| -// safely synchronously delete the WebSocketChannel. This test will only
|
| -// reliably find problems if run with a memory debugger such as
|
| -// AddressSanitizer.
|
| -TEST_F(WebSocketChannelDeletingTest, DeletingFromOnAddChannelResponseWorks) {
|
| +// Any WebSocketEventInterface methods can delete the WebSocketChannel and
|
| +// return CHANNEL_DELETED. The WebSocketChannelDeletingTests are intended to
|
| +// verify that there are no use-after-free bugs when this happens. Problems will
|
| +// probably only be found when running under Address Sanitizer or a similar
|
| +// tool.
|
| +TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseFail) {
|
| CreateChannelAndConnect();
|
| + EXPECT_TRUE(channel_);
|
| connect_data_.factory.connect_delegate->OnFailure(
|
| kWebSocketErrorNoStatusReceived);
|
| EXPECT_EQ(NULL, channel_.get());
|
| }
|
|
|
| +// Deletion is possible (due to IPC failure) even if the connect succeeds.
|
| +TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseSuccess) {
|
| + CreateChannelAndConnectSuccessfully();
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, OnDataFrameSync) {
|
| + scoped_ptr<ReadableFakeWebSocketStream> stream(
|
| + new ReadableFakeWebSocketStream);
|
| + static const InitFrame frames[] = {
|
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
|
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
|
| + set_stream(stream.Pass());
|
| + deleting_ = EVENT_ON_DATA_FRAME;
|
| +
|
| + CreateChannelAndConnectSuccessfully();
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, OnDataFrameAsync) {
|
| + scoped_ptr<ReadableFakeWebSocketStream> stream(
|
| + new ReadableFakeWebSocketStream);
|
| + static const InitFrame frames[] = {
|
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
|
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
|
| + set_stream(stream.Pass());
|
| + deleting_ = EVENT_ON_DATA_FRAME;
|
| +
|
| + CreateChannelAndConnectSuccessfully();
|
| + EXPECT_TRUE(channel_);
|
| + base::MessageLoop::current()->RunUntilIdle();
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterConnect) {
|
| + deleting_ = EVENT_ON_FLOW_CONTROL;
|
| +
|
| + CreateChannelAndConnectSuccessfully();
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterSend) {
|
| + set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream));
|
| + // Avoid deleting the channel yet.
|
| + deleting_ = EVENT_ON_DROP_CHANNEL;
|
| + CreateChannelAndConnectSuccessfully();
|
| + ASSERT_TRUE(channel_);
|
| + deleting_ = EVENT_ON_FLOW_CONTROL;
|
| + channel_->SendFrame(true,
|
| + WebSocketFrameHeader::kOpCodeText,
|
| + std::vector<char>(kDefaultInitialQuota, 'B'));
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeSync) {
|
| + scoped_ptr<ReadableFakeWebSocketStream> stream(
|
| + new ReadableFakeWebSocketStream);
|
| + static const InitFrame frames[] = {
|
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
|
| + NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}};
|
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
|
| + set_stream(stream.Pass());
|
| + deleting_ = EVENT_ON_CLOSING_HANDSHAKE;
|
| + CreateChannelAndConnectSuccessfully();
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeAsync) {
|
| + scoped_ptr<ReadableFakeWebSocketStream> stream(
|
| + new ReadableFakeWebSocketStream);
|
| + static const InitFrame frames[] = {
|
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
|
| + NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}};
|
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
|
| + set_stream(stream.Pass());
|
| + deleting_ = EVENT_ON_CLOSING_HANDSHAKE;
|
| + CreateChannelAndConnectSuccessfully();
|
| + ASSERT_TRUE(channel_);
|
| + base::MessageLoop::current()->RunUntilIdle();
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, OnDropChannelWriteError) {
|
| + set_stream(make_scoped_ptr(new UnWriteableFakeWebSocketStream));
|
| + deleting_ = EVENT_ON_DROP_CHANNEL;
|
| + CreateChannelAndConnectSuccessfully();
|
| + ASSERT_TRUE(channel_);
|
| + channel_->SendFrame(
|
| + true, WebSocketFrameHeader::kOpCodeText, AsVector("this will fail"));
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, OnDropChannelReadError) {
|
| + scoped_ptr<ReadableFakeWebSocketStream> stream(
|
| + new ReadableFakeWebSocketStream);
|
| + stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
|
| + ERR_FAILED);
|
| + set_stream(stream.Pass());
|
| + deleting_ = EVENT_ON_DROP_CHANNEL;
|
| + CreateChannelAndConnectSuccessfully();
|
| + ASSERT_TRUE(channel_);
|
| + base::MessageLoop::current()->RunUntilIdle();
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, FailChannelInSendFrame) {
|
| + set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream));
|
| + deleting_ = EVENT_ON_DROP_CHANNEL;
|
| + CreateChannelAndConnectSuccessfully();
|
| + ASSERT_TRUE(channel_);
|
| + channel_->SendFrame(true,
|
| + WebSocketFrameHeader::kOpCodeText,
|
| + std::vector<char>(kDefaultInitialQuota * 2, 'T'));
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, FailChannelInOnReadDone) {
|
| + scoped_ptr<ReadableFakeWebSocketStream> stream(
|
| + new ReadableFakeWebSocketStream);
|
| + stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
|
| + ERR_WS_PROTOCOL_ERROR);
|
| + set_stream(stream.Pass());
|
| + deleting_ = EVENT_ON_DROP_CHANNEL;
|
| + CreateChannelAndConnectSuccessfully();
|
| + ASSERT_TRUE(channel_);
|
| + base::MessageLoop::current()->RunUntilIdle();
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, FailChannelDueToMaskedFrame) {
|
| + scoped_ptr<ReadableFakeWebSocketStream> stream(
|
| + new ReadableFakeWebSocketStream);
|
| + static const InitFrame frames[] = {
|
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}};
|
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
|
| + set_stream(stream.Pass());
|
| + deleting_ = EVENT_ON_DROP_CHANNEL;
|
| +
|
| + CreateChannelAndConnectSuccessfully();
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, FailChannelDueToBadControlFrame) {
|
| + scoped_ptr<ReadableFakeWebSocketStream> stream(
|
| + new ReadableFakeWebSocketStream);
|
| + static const InitFrame frames[] = {
|
| + {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}};
|
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
|
| + set_stream(stream.Pass());
|
| + deleting_ = EVENT_ON_DROP_CHANNEL;
|
| +
|
| + CreateChannelAndConnectSuccessfully();
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, FailChannelDueToPongAfterClose) {
|
| + scoped_ptr<ReadableFakeWebSocketStream> stream(
|
| + new ReadableFakeWebSocketStream);
|
| + static const InitFrame frames[] = {
|
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED,
|
| + CLOSE_DATA(NORMAL_CLOSURE, "Success")},
|
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}};
|
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
|
| + set_stream(stream.Pass());
|
| + deleting_ = EVENT_ON_DROP_CHANNEL;
|
| +
|
| + CreateChannelAndConnectSuccessfully();
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| +TEST_F(WebSocketChannelDeletingTest, FailChannelDueToUnknownOpCode) {
|
| + scoped_ptr<ReadableFakeWebSocketStream> stream(
|
| + new ReadableFakeWebSocketStream);
|
| + static const InitFrame frames[] = {{FINAL_FRAME, 0x7, NOT_MASKED, ""}};
|
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
|
| + set_stream(stream.Pass());
|
| + deleting_ = EVENT_ON_DROP_CHANNEL;
|
| +
|
| + CreateChannelAndConnectSuccessfully();
|
| + EXPECT_EQ(NULL, channel_.get());
|
| +}
|
| +
|
| TEST_F(WebSocketChannelEventInterfaceTest, ConnectSuccessReported) {
|
| // false means success.
|
| EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, ""));
|
| @@ -897,7 +1177,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) {
|
| {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
|
| // We use this checkpoint object to verify that the callback isn't called
|
| // until we expect it to be.
|
| - MockFunction<void(int)> checkpoint;
|
| + Checkpoint checkpoint;
|
| stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
|
| set_stream(stream.Pass());
|
| {
|
| @@ -1185,7 +1465,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, LargeWriteUpdatesQuota) {
|
| set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream));
|
| // We use this checkpoint object to verify that the quota update comes after
|
| // the write.
|
| - MockFunction<void(int)> checkpoint;
|
| + Checkpoint checkpoint;
|
| {
|
| InSequence s;
|
| EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
|
| @@ -1206,7 +1486,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, LargeWriteUpdatesQuota) {
|
| // Verify that our quota actually is refreshed when we are told it is.
|
| TEST_F(WebSocketChannelEventInterfaceTest, QuotaReallyIsRefreshed) {
|
| set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream));
|
| - MockFunction<void(int)> checkpoint;
|
| + Checkpoint checkpoint;
|
| {
|
| InSequence s;
|
| EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
|
| @@ -1254,7 +1534,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, WriteOverQuotaIsRejected) {
|
| // If a write fails, the channel is dropped.
|
| TEST_F(WebSocketChannelEventInterfaceTest, FailedWrite) {
|
| set_stream(make_scoped_ptr(new UnWriteableFakeWebSocketStream));
|
| - MockFunction<void(int)> checkpoint;
|
| + Checkpoint checkpoint;
|
| {
|
| InSequence s;
|
| EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
|
| @@ -1429,7 +1709,7 @@ TEST_F(WebSocketChannelStreamTest, CloseOnlySentOnce) {
|
| ScopedVector<WebSocketFrame>* frames = NULL;
|
|
|
| // Use a checkpoint to make the ordering of events clearer.
|
| - MockFunction<void(int)> checkpoint;
|
| + Checkpoint checkpoint;
|
| {
|
| InSequence s;
|
| EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
|
| @@ -1548,7 +1828,7 @@ TEST_F(WebSocketChannelStreamTest, WriteFramesOneAtATime) {
|
| static const InitFrame expected2[] = {
|
| {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "World"}};
|
| CompletionCallback write_callback;
|
| - MockFunction<void(int)> checkpoint;
|
| + Checkpoint checkpoint;
|
|
|
| EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
|
| EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING));
|
|
|