| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/websockets/websocket_channel.h" | 5 #include "net/websockets/websocket_channel.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <iostream> | 9 #include <iostream> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
| 15 #include "base/callback.h" | 15 #include "base/callback.h" |
| 16 #include "base/location.h" | 16 #include "base/location.h" |
| 17 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
| 18 #include "base/memory/scoped_vector.h" | 18 #include "base/memory/scoped_vector.h" |
| 19 #include "base/memory/weak_ptr.h" |
| 19 #include "base/message_loop/message_loop.h" | 20 #include "base/message_loop/message_loop.h" |
| 20 #include "base/safe_numerics.h" | 21 #include "base/safe_numerics.h" |
| 21 #include "base/strings/string_piece.h" | 22 #include "base/strings/string_piece.h" |
| 22 #include "net/base/net_errors.h" | 23 #include "net/base/net_errors.h" |
| 23 #include "net/url_request/url_request_context.h" | 24 #include "net/url_request/url_request_context.h" |
| 24 #include "net/websockets/websocket_errors.h" | 25 #include "net/websockets/websocket_errors.h" |
| 25 #include "net/websockets/websocket_event_interface.h" | 26 #include "net/websockets/websocket_event_interface.h" |
| 26 #include "net/websockets/websocket_mux.h" | 27 #include "net/websockets/websocket_mux.h" |
| 27 #include "testing/gmock/include/gmock/gmock.h" | 28 #include "testing/gmock/include/gmock/gmock.h" |
| 28 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 } | 79 } |
| 79 | 80 |
| 80 std::ostream& operator<<(std::ostream& os, | 81 std::ostream& operator<<(std::ostream& os, |
| 81 const ScopedVector<WebSocketFrame>* vector) { | 82 const ScopedVector<WebSocketFrame>* vector) { |
| 82 return os << '&' << *vector; | 83 return os << '&' << *vector; |
| 83 } | 84 } |
| 84 | 85 |
| 85 namespace { | 86 namespace { |
| 86 | 87 |
| 87 using ::testing::AnyNumber; | 88 using ::testing::AnyNumber; |
| 89 using ::testing::DefaultValue; |
| 88 using ::testing::InSequence; | 90 using ::testing::InSequence; |
| 89 using ::testing::MockFunction; | 91 using ::testing::MockFunction; |
| 90 using ::testing::Return; | 92 using ::testing::Return; |
| 91 using ::testing::SaveArg; | 93 using ::testing::SaveArg; |
| 92 using ::testing::StrictMock; | 94 using ::testing::StrictMock; |
| 93 using ::testing::_; | 95 using ::testing::_; |
| 94 | 96 |
| 95 // A selection of characters that have traditionally been mangled in some | 97 // A selection of characters that have traditionally been mangled in some |
| 96 // environment or other, for testing 8-bit cleanliness. | 98 // environment or other, for testing 8-bit cleanliness. |
| 97 const char kBinaryBlob[] = {'\n', '\r', // BACKWARDS CRNL | 99 const char kBinaryBlob[] = {'\n', '\r', // BACKWARDS CRNL |
| (...skipping 11 matching lines...) Expand all Loading... |
| 109 | 111 |
| 110 // The amount of quota a new connection gets by default. | 112 // The amount of quota a new connection gets by default. |
| 111 // TODO(ricea): If kDefaultSendQuotaHighWaterMark changes, then this value will | 113 // TODO(ricea): If kDefaultSendQuotaHighWaterMark changes, then this value will |
| 112 // need to be updated. | 114 // need to be updated. |
| 113 const size_t kDefaultInitialQuota = 1 << 17; | 115 const size_t kDefaultInitialQuota = 1 << 17; |
| 114 // The amount of bytes we need to send after the initial connection to trigger a | 116 // The amount of bytes we need to send after the initial connection to trigger a |
| 115 // quota refresh. TODO(ricea): Change this if kDefaultSendQuotaHighWaterMark or | 117 // quota refresh. TODO(ricea): Change this if kDefaultSendQuotaHighWaterMark or |
| 116 // kDefaultSendQuotaLowWaterMark change. | 118 // kDefaultSendQuotaLowWaterMark change. |
| 117 const size_t kDefaultQuotaRefreshTrigger = (1 << 16) + 1; | 119 const size_t kDefaultQuotaRefreshTrigger = (1 << 16) + 1; |
| 118 | 120 |
| 121 typedef WebSocketEventInterface::ChannelState ChannelState; |
| 122 const ChannelState CHANNEL_ALIVE = WebSocketEventInterface::CHANNEL_ALIVE; |
| 123 const ChannelState CHANNEL_DELETED = WebSocketEventInterface::CHANNEL_DELETED; |
| 124 |
| 125 // This typedef mainly exists to avoid having to repeat the "NOLINT" incantation |
| 126 // all over the place. |
| 127 typedef MockFunction<void(int)> Checkpoint; // NOLINT |
| 128 |
| 119 // This mock is for testing expectations about how the EventInterface is used. | 129 // This mock is for testing expectations about how the EventInterface is used. |
| 120 class MockWebSocketEventInterface : public WebSocketEventInterface { | 130 class MockWebSocketEventInterface : public WebSocketEventInterface { |
| 121 public: | 131 public: |
| 122 MOCK_METHOD2(OnAddChannelResponse, void(bool, const std::string&)); | 132 MOCK_METHOD2(OnAddChannelResponse, |
| 133 ChannelState(bool, const std::string&)); // NOLINT |
| 123 MOCK_METHOD3(OnDataFrame, | 134 MOCK_METHOD3(OnDataFrame, |
| 124 void(bool, WebSocketMessageType, const std::vector<char>&)); | 135 ChannelState(bool, |
| 125 MOCK_METHOD1(OnFlowControl, void(int64)); | 136 WebSocketMessageType, |
| 126 MOCK_METHOD0(OnClosingHandshake, void(void)); | 137 const std::vector<char>&)); // NOLINT |
| 127 MOCK_METHOD2(OnDropChannel, void(uint16, const std::string&)); | 138 MOCK_METHOD1(OnFlowControl, ChannelState(int64)); // NOLINT |
| 139 MOCK_METHOD0(OnClosingHandshake, ChannelState(void)); // NOLINT |
| 140 MOCK_METHOD2(OnDropChannel, |
| 141 ChannelState(uint16, const std::string&)); // NOLINT |
| 128 }; | 142 }; |
| 129 | 143 |
| 130 // This fake EventInterface is for tests which need a WebSocketEventInterface | 144 // This fake EventInterface is for tests which need a WebSocketEventInterface |
| 131 // implementation but are not verifying how it is used. | 145 // implementation but are not verifying how it is used. |
| 132 class FakeWebSocketEventInterface : public WebSocketEventInterface { | 146 class FakeWebSocketEventInterface : public WebSocketEventInterface { |
| 133 virtual void OnAddChannelResponse( | 147 virtual ChannelState OnAddChannelResponse( |
| 134 bool fail, | 148 bool fail, |
| 135 const std::string& selected_protocol) OVERRIDE {} | 149 const std::string& selected_protocol) OVERRIDE { |
| 136 virtual void OnDataFrame(bool fin, | 150 return fail ? CHANNEL_DELETED : CHANNEL_ALIVE; |
| 137 WebSocketMessageType type, | 151 } |
| 138 const std::vector<char>& data) OVERRIDE {} | 152 virtual ChannelState OnDataFrame(bool fin, |
| 139 virtual void OnFlowControl(int64 quota) OVERRIDE {} | 153 WebSocketMessageType type, |
| 140 virtual void OnClosingHandshake() OVERRIDE {} | 154 const std::vector<char>& data) OVERRIDE { |
| 141 virtual void OnDropChannel(uint16 code, const std::string& reason) OVERRIDE {} | 155 return CHANNEL_ALIVE; |
| 156 } |
| 157 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE { |
| 158 return CHANNEL_ALIVE; |
| 159 } |
| 160 virtual ChannelState OnClosingHandshake() OVERRIDE { return CHANNEL_ALIVE; } |
| 161 virtual ChannelState OnDropChannel(uint16 code, |
| 162 const std::string& reason) OVERRIDE { |
| 163 return CHANNEL_DELETED; |
| 164 } |
| 142 }; | 165 }; |
| 143 | 166 |
| 144 // This fake WebSocketStream is for tests that require a WebSocketStream but are | 167 // This fake WebSocketStream is for tests that require a WebSocketStream but are |
| 145 // not testing the way it is used. It has minimal functionality to return | 168 // not testing the way it is used. It has minimal functionality to return |
| 146 // the |protocol| and |extensions| that it was constructed with. | 169 // the |protocol| and |extensions| that it was constructed with. |
| 147 class FakeWebSocketStream : public WebSocketStream { | 170 class FakeWebSocketStream : public WebSocketStream { |
| 148 public: | 171 public: |
| 149 // Constructs with empty protocol and extensions. | 172 // Constructs with empty protocol and extensions. |
| 150 FakeWebSocketStream() {} | 173 FakeWebSocketStream() {} |
| 151 | 174 |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 CompletionCallback read_callback_; | 565 CompletionCallback read_callback_; |
| 543 // Owned by the caller of ReadFrames(). | 566 // Owned by the caller of ReadFrames(). |
| 544 ScopedVector<WebSocketFrame>* read_frames_; | 567 ScopedVector<WebSocketFrame>* read_frames_; |
| 545 // True if we should close the connection. | 568 // True if we should close the connection. |
| 546 bool done_; | 569 bool done_; |
| 547 }; | 570 }; |
| 548 | 571 |
| 549 // A FakeWebSocketStream where writes trigger a connection reset. | 572 // A FakeWebSocketStream where writes trigger a connection reset. |
| 550 // This differs from UnWriteableFakeWebSocketStream in that it is asynchronous | 573 // This differs from UnWriteableFakeWebSocketStream in that it is asynchronous |
| 551 // and triggers ReadFrames to return a reset as well. Tests using this need to | 574 // and triggers ReadFrames to return a reset as well. Tests using this need to |
| 552 // run the message loop. | 575 // run the message loop. There are two tricky parts here: |
| 576 // 1. Calling the write callback may call Close(), after which the read callback |
| 577 // should not be called. |
| 578 // 2. Calling either callback may delete the stream altogether. |
| 553 class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream { | 579 class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream { |
| 554 public: | 580 public: |
| 581 ResetOnWriteFakeWebSocketStream() : closed_(false), weak_ptr_factory_(this) {} |
| 582 |
| 555 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, | 583 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, |
| 556 const CompletionCallback& callback) OVERRIDE { | 584 const CompletionCallback& callback) OVERRIDE { |
| 557 base::MessageLoop::current()->PostTask( | 585 base::MessageLoop::current()->PostTask( |
| 558 FROM_HERE, base::Bind(callback, ERR_CONNECTION_RESET)); | 586 FROM_HERE, |
| 587 base::Bind(&ResetOnWriteFakeWebSocketStream::CallCallbackUnlessClosed, |
| 588 weak_ptr_factory_.GetWeakPtr(), |
| 589 callback, |
| 590 ERR_CONNECTION_RESET)); |
| 559 base::MessageLoop::current()->PostTask( | 591 base::MessageLoop::current()->PostTask( |
| 560 FROM_HERE, base::Bind(read_callback_, ERR_CONNECTION_RESET)); | 592 FROM_HERE, |
| 593 base::Bind(&ResetOnWriteFakeWebSocketStream::CallCallbackUnlessClosed, |
| 594 weak_ptr_factory_.GetWeakPtr(), |
| 595 read_callback_, |
| 596 ERR_CONNECTION_RESET)); |
| 561 return ERR_IO_PENDING; | 597 return ERR_IO_PENDING; |
| 562 } | 598 } |
| 563 | 599 |
| 564 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, | 600 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, |
| 565 const CompletionCallback& callback) OVERRIDE { | 601 const CompletionCallback& callback) OVERRIDE { |
| 566 read_callback_ = callback; | 602 read_callback_ = callback; |
| 567 return ERR_IO_PENDING; | 603 return ERR_IO_PENDING; |
| 568 } | 604 } |
| 569 | 605 |
| 606 virtual void Close() OVERRIDE { closed_ = true; } |
| 607 |
| 570 private: | 608 private: |
| 609 void CallCallbackUnlessClosed(const CompletionCallback& callback, int value) { |
| 610 if (!closed_) |
| 611 callback.Run(value); |
| 612 } |
| 613 |
| 571 CompletionCallback read_callback_; | 614 CompletionCallback read_callback_; |
| 615 bool closed_; |
| 616 // An IO error can result in the socket being deleted, so we use weak pointers |
| 617 // to ensure correct behaviour in that case. |
| 618 base::WeakPtrFactory<ResetOnWriteFakeWebSocketStream> weak_ptr_factory_; |
| 572 }; | 619 }; |
| 573 | 620 |
| 574 // This mock is for verifying that WebSocket protocol semantics are obeyed (to | 621 // This mock is for verifying that WebSocket protocol semantics are obeyed (to |
| 575 // the extent that they are implemented in WebSocketCommon). | 622 // the extent that they are implemented in WebSocketCommon). |
| 576 class MockWebSocketStream : public WebSocketStream { | 623 class MockWebSocketStream : public WebSocketStream { |
| 577 public: | 624 public: |
| 578 MOCK_METHOD2(ReadFrames, | 625 MOCK_METHOD2(ReadFrames, |
| 579 int(ScopedVector<WebSocketFrame>* frames, | 626 int(ScopedVector<WebSocketFrame>* frames, |
| 580 const CompletionCallback& callback)); | 627 const CompletionCallback& callback)); |
| 581 MOCK_METHOD2(WriteFrames, | 628 MOCK_METHOD2(WriteFrames, |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 }; | 730 }; |
| 684 ConnectData connect_data_; | 731 ConnectData connect_data_; |
| 685 | 732 |
| 686 // The channel we are testing. Not initialised until SetChannel() is called. | 733 // The channel we are testing. Not initialised until SetChannel() is called. |
| 687 scoped_ptr<WebSocketChannel> channel_; | 734 scoped_ptr<WebSocketChannel> channel_; |
| 688 | 735 |
| 689 // A mock or fake stream for tests that need one. | 736 // A mock or fake stream for tests that need one. |
| 690 scoped_ptr<WebSocketStream> stream_; | 737 scoped_ptr<WebSocketStream> stream_; |
| 691 }; | 738 }; |
| 692 | 739 |
| 740 // enum of WebSocketEventInterface calls. These are intended to be or'd together |
| 741 // in order to instruct WebSocketChannelDeletingTest when it should fail. |
| 742 enum EventInterfaceCall { |
| 743 EVENT_ON_ADD_CHANNEL_RESPONSE = 0x1, |
| 744 EVENT_ON_DATA_FRAME = 0x2, |
| 745 EVENT_ON_FLOW_CONTROL = 0x4, |
| 746 EVENT_ON_CLOSING_HANDSHAKE = 0x8, |
| 747 EVENT_ON_DROP_CHANNEL = 0x10, |
| 748 }; |
| 749 |
| 693 class WebSocketChannelDeletingTest : public WebSocketChannelTest { | 750 class WebSocketChannelDeletingTest : public WebSocketChannelTest { |
| 694 public: | 751 public: |
| 695 void ResetChannel() { channel_.reset(); } | 752 ChannelState DeleteIfDeleting(EventInterfaceCall call) { |
| 753 if (deleting_ & call) { |
| 754 channel_.reset(); |
| 755 return CHANNEL_DELETED; |
| 756 } else { |
| 757 return CHANNEL_ALIVE; |
| 758 } |
| 759 } |
| 696 | 760 |
| 697 protected: | 761 protected: |
| 762 WebSocketChannelDeletingTest() |
| 763 : deleting_(EVENT_ON_ADD_CHANNEL_RESPONSE | EVENT_ON_DATA_FRAME | |
| 764 EVENT_ON_FLOW_CONTROL | |
| 765 EVENT_ON_CLOSING_HANDSHAKE | |
| 766 EVENT_ON_DROP_CHANNEL) {} |
| 698 // Create a ChannelDeletingFakeWebSocketEventInterface. Defined out-of-line to | 767 // Create a ChannelDeletingFakeWebSocketEventInterface. Defined out-of-line to |
| 699 // avoid circular dependency. | 768 // avoid circular dependency. |
| 700 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE; | 769 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE; |
| 770 |
| 771 // Tests can set deleting_ to a bitmap of EventInterfaceCall members that they |
| 772 // want to cause Channel deletion. The default is for all calls to cause |
| 773 // deletion. |
| 774 int deleting_; |
| 701 }; | 775 }; |
| 702 | 776 |
| 703 // A FakeWebSocketEventInterface that deletes the WebSocketChannel on failure to | 777 // A FakeWebSocketEventInterface that deletes the WebSocketChannel on failure to |
| 704 // connect. | 778 // connect. |
| 705 class ChannelDeletingFakeWebSocketEventInterface | 779 class ChannelDeletingFakeWebSocketEventInterface |
| 706 : public FakeWebSocketEventInterface { | 780 : public FakeWebSocketEventInterface { |
| 707 public: | 781 public: |
| 708 ChannelDeletingFakeWebSocketEventInterface( | 782 ChannelDeletingFakeWebSocketEventInterface( |
| 709 WebSocketChannelDeletingTest* fixture) | 783 WebSocketChannelDeletingTest* fixture) |
| 710 : fixture_(fixture) {} | 784 : fixture_(fixture) {} |
| 711 | 785 |
| 712 virtual void OnAddChannelResponse( | 786 virtual ChannelState OnAddChannelResponse( |
| 713 bool fail, | 787 bool fail, |
| 714 const std::string& selected_protocol) OVERRIDE { | 788 const std::string& selected_protocol) OVERRIDE { |
| 715 if (fail) { | 789 return fixture_->DeleteIfDeleting(EVENT_ON_ADD_CHANNEL_RESPONSE); |
| 716 fixture_->ResetChannel(); | 790 } |
| 717 } | 791 |
| 792 virtual ChannelState OnDataFrame(bool fin, |
| 793 WebSocketMessageType type, |
| 794 const std::vector<char>& data) OVERRIDE { |
| 795 return fixture_->DeleteIfDeleting(EVENT_ON_DATA_FRAME); |
| 796 } |
| 797 |
| 798 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE { |
| 799 return fixture_->DeleteIfDeleting(EVENT_ON_FLOW_CONTROL); |
| 800 } |
| 801 |
| 802 virtual ChannelState OnClosingHandshake() OVERRIDE { |
| 803 return fixture_->DeleteIfDeleting(EVENT_ON_CLOSING_HANDSHAKE); |
| 804 } |
| 805 |
| 806 virtual ChannelState OnDropChannel(uint16 code, |
| 807 const std::string& reason) OVERRIDE { |
| 808 return fixture_->DeleteIfDeleting(EVENT_ON_DROP_CHANNEL); |
| 718 } | 809 } |
| 719 | 810 |
| 720 private: | 811 private: |
| 721 // A pointer to the test fixture. Owned by the test harness; this object will | 812 // A pointer to the test fixture. Owned by the test harness; this object will |
| 722 // be deleted before it is. | 813 // be deleted before it is. |
| 723 WebSocketChannelDeletingTest* fixture_; | 814 WebSocketChannelDeletingTest* fixture_; |
| 724 }; | 815 }; |
| 725 | 816 |
| 726 scoped_ptr<WebSocketEventInterface> | 817 scoped_ptr<WebSocketEventInterface> |
| 727 WebSocketChannelDeletingTest::CreateEventInterface() { | 818 WebSocketChannelDeletingTest::CreateEventInterface() { |
| 728 return scoped_ptr<WebSocketEventInterface>( | 819 return scoped_ptr<WebSocketEventInterface>( |
| 729 new ChannelDeletingFakeWebSocketEventInterface(this)); | 820 new ChannelDeletingFakeWebSocketEventInterface(this)); |
| 730 } | 821 } |
| 731 | 822 |
| 732 // Base class for tests which verify that EventInterface methods are called | 823 // Base class for tests which verify that EventInterface methods are called |
| 733 // appropriately. | 824 // appropriately. |
| 734 class WebSocketChannelEventInterfaceTest : public WebSocketChannelTest { | 825 class WebSocketChannelEventInterfaceTest : public WebSocketChannelTest { |
| 735 protected: | 826 protected: |
| 736 WebSocketChannelEventInterfaceTest() | 827 WebSocketChannelEventInterfaceTest() |
| 737 : event_interface_(new StrictMock<MockWebSocketEventInterface>) {} | 828 : event_interface_(new StrictMock<MockWebSocketEventInterface>) { |
| 829 DefaultValue<ChannelState>::Set(CHANNEL_ALIVE); |
| 830 ON_CALL(*event_interface_, OnAddChannelResponse(true, _)) |
| 831 .WillByDefault(Return(CHANNEL_DELETED)); |
| 832 ON_CALL(*event_interface_, OnDropChannel(_, _)) |
| 833 .WillByDefault(Return(CHANNEL_DELETED)); |
| 834 } |
| 738 | 835 |
| 739 // Tests using this fixture must set expectations on the event_interface_ mock | 836 // Tests using this fixture must set expectations on the event_interface_ mock |
| 740 // object before calling CreateChannelAndConnect() or | 837 // object before calling CreateChannelAndConnect() or |
| 741 // CreateChannelAndConnectSuccessfully(). This will only work once per test | 838 // CreateChannelAndConnectSuccessfully(). This will only work once per test |
| 742 // case, but once should be enough. | 839 // case, but once should be enough. |
| 743 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE { | 840 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE { |
| 744 return scoped_ptr<WebSocketEventInterface>(event_interface_.release()); | 841 return scoped_ptr<WebSocketEventInterface>(event_interface_.release()); |
| 745 } | 842 } |
| 746 | 843 |
| 747 scoped_ptr<MockWebSocketEventInterface> event_interface_; | 844 scoped_ptr<MockWebSocketEventInterface> event_interface_; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 772 CreateChannelAndConnect(); | 869 CreateChannelAndConnect(); |
| 773 | 870 |
| 774 EXPECT_EQ(connect_data_.url, connect_data_.factory.socket_url); | 871 EXPECT_EQ(connect_data_.url, connect_data_.factory.socket_url); |
| 775 EXPECT_EQ(connect_data_.origin, connect_data_.factory.origin); | 872 EXPECT_EQ(connect_data_.origin, connect_data_.factory.origin); |
| 776 EXPECT_EQ(connect_data_.requested_subprotocols, | 873 EXPECT_EQ(connect_data_.requested_subprotocols, |
| 777 connect_data_.factory.requested_subprotocols); | 874 connect_data_.factory.requested_subprotocols); |
| 778 EXPECT_EQ(&connect_data_.url_request_context, | 875 EXPECT_EQ(&connect_data_.url_request_context, |
| 779 connect_data_.factory.url_request_context); | 876 connect_data_.factory.url_request_context); |
| 780 } | 877 } |
| 781 | 878 |
| 782 // The documentation for WebSocketEventInterface::OnAddChannelResponse() says | 879 // Any WebSocketEventInterface methods can delete the WebSocketChannel and |
| 783 // that if the first argument is true, ie. the connection failed, then we can | 880 // return CHANNEL_DELETED. The WebSocketChannelDeletingTests are intended to |
| 784 // safely synchronously delete the WebSocketChannel. This test will only | 881 // verify that there are no use-after-free bugs when this happens. Problems will |
| 785 // reliably find problems if run with a memory debugger such as | 882 // probably only be found when running under Address Sanitizer or a similar |
| 786 // AddressSanitizer. | 883 // tool. |
| 787 TEST_F(WebSocketChannelDeletingTest, DeletingFromOnAddChannelResponseWorks) { | 884 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseFail) { |
| 788 CreateChannelAndConnect(); | 885 CreateChannelAndConnect(); |
| 886 EXPECT_TRUE(channel_); |
| 789 connect_data_.factory.connect_delegate->OnFailure( | 887 connect_data_.factory.connect_delegate->OnFailure( |
| 790 kWebSocketErrorNoStatusReceived); | 888 kWebSocketErrorNoStatusReceived); |
| 791 EXPECT_EQ(NULL, channel_.get()); | 889 EXPECT_EQ(NULL, channel_.get()); |
| 792 } | 890 } |
| 793 | 891 |
| 892 // Deletion is possible (due to IPC failure) even if the connect succeeds. |
| 893 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseSuccess) { |
| 894 CreateChannelAndConnectSuccessfully(); |
| 895 EXPECT_EQ(NULL, channel_.get()); |
| 896 } |
| 897 |
| 898 TEST_F(WebSocketChannelDeletingTest, OnDataFrameSync) { |
| 899 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 900 new ReadableFakeWebSocketStream); |
| 901 static const InitFrame frames[] = { |
| 902 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; |
| 903 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 904 set_stream(stream.Pass()); |
| 905 deleting_ = EVENT_ON_DATA_FRAME; |
| 906 |
| 907 CreateChannelAndConnectSuccessfully(); |
| 908 EXPECT_EQ(NULL, channel_.get()); |
| 909 } |
| 910 |
| 911 TEST_F(WebSocketChannelDeletingTest, OnDataFrameAsync) { |
| 912 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 913 new ReadableFakeWebSocketStream); |
| 914 static const InitFrame frames[] = { |
| 915 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; |
| 916 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); |
| 917 set_stream(stream.Pass()); |
| 918 deleting_ = EVENT_ON_DATA_FRAME; |
| 919 |
| 920 CreateChannelAndConnectSuccessfully(); |
| 921 EXPECT_TRUE(channel_); |
| 922 base::MessageLoop::current()->RunUntilIdle(); |
| 923 EXPECT_EQ(NULL, channel_.get()); |
| 924 } |
| 925 |
| 926 TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterConnect) { |
| 927 deleting_ = EVENT_ON_FLOW_CONTROL; |
| 928 |
| 929 CreateChannelAndConnectSuccessfully(); |
| 930 EXPECT_EQ(NULL, channel_.get()); |
| 931 } |
| 932 |
| 933 TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterSend) { |
| 934 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); |
| 935 // Avoid deleting the channel yet. |
| 936 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 937 CreateChannelAndConnectSuccessfully(); |
| 938 ASSERT_TRUE(channel_); |
| 939 deleting_ = EVENT_ON_FLOW_CONTROL; |
| 940 channel_->SendFrame(true, |
| 941 WebSocketFrameHeader::kOpCodeText, |
| 942 std::vector<char>(kDefaultInitialQuota, 'B')); |
| 943 EXPECT_EQ(NULL, channel_.get()); |
| 944 } |
| 945 |
| 946 TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeSync) { |
| 947 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 948 new ReadableFakeWebSocketStream); |
| 949 static const InitFrame frames[] = { |
| 950 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| 951 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; |
| 952 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 953 set_stream(stream.Pass()); |
| 954 deleting_ = EVENT_ON_CLOSING_HANDSHAKE; |
| 955 CreateChannelAndConnectSuccessfully(); |
| 956 EXPECT_EQ(NULL, channel_.get()); |
| 957 } |
| 958 |
| 959 TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeAsync) { |
| 960 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 961 new ReadableFakeWebSocketStream); |
| 962 static const InitFrame frames[] = { |
| 963 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| 964 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; |
| 965 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); |
| 966 set_stream(stream.Pass()); |
| 967 deleting_ = EVENT_ON_CLOSING_HANDSHAKE; |
| 968 CreateChannelAndConnectSuccessfully(); |
| 969 ASSERT_TRUE(channel_); |
| 970 base::MessageLoop::current()->RunUntilIdle(); |
| 971 EXPECT_EQ(NULL, channel_.get()); |
| 972 } |
| 973 |
| 974 TEST_F(WebSocketChannelDeletingTest, OnDropChannelWriteError) { |
| 975 set_stream(make_scoped_ptr(new UnWriteableFakeWebSocketStream)); |
| 976 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 977 CreateChannelAndConnectSuccessfully(); |
| 978 ASSERT_TRUE(channel_); |
| 979 channel_->SendFrame( |
| 980 true, WebSocketFrameHeader::kOpCodeText, AsVector("this will fail")); |
| 981 EXPECT_EQ(NULL, channel_.get()); |
| 982 } |
| 983 |
| 984 TEST_F(WebSocketChannelDeletingTest, OnDropChannelReadError) { |
| 985 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 986 new ReadableFakeWebSocketStream); |
| 987 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, |
| 988 ERR_FAILED); |
| 989 set_stream(stream.Pass()); |
| 990 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 991 CreateChannelAndConnectSuccessfully(); |
| 992 ASSERT_TRUE(channel_); |
| 993 base::MessageLoop::current()->RunUntilIdle(); |
| 994 EXPECT_EQ(NULL, channel_.get()); |
| 995 } |
| 996 |
| 997 TEST_F(WebSocketChannelDeletingTest, FailChannelInSendFrame) { |
| 998 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); |
| 999 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 1000 CreateChannelAndConnectSuccessfully(); |
| 1001 ASSERT_TRUE(channel_); |
| 1002 channel_->SendFrame(true, |
| 1003 WebSocketFrameHeader::kOpCodeText, |
| 1004 std::vector<char>(kDefaultInitialQuota * 2, 'T')); |
| 1005 EXPECT_EQ(NULL, channel_.get()); |
| 1006 } |
| 1007 |
| 1008 TEST_F(WebSocketChannelDeletingTest, FailChannelInOnReadDone) { |
| 1009 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 1010 new ReadableFakeWebSocketStream); |
| 1011 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, |
| 1012 ERR_WS_PROTOCOL_ERROR); |
| 1013 set_stream(stream.Pass()); |
| 1014 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 1015 CreateChannelAndConnectSuccessfully(); |
| 1016 ASSERT_TRUE(channel_); |
| 1017 base::MessageLoop::current()->RunUntilIdle(); |
| 1018 EXPECT_EQ(NULL, channel_.get()); |
| 1019 } |
| 1020 |
| 1021 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToMaskedFrame) { |
| 1022 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 1023 new ReadableFakeWebSocketStream); |
| 1024 static const InitFrame frames[] = { |
| 1025 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}}; |
| 1026 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 1027 set_stream(stream.Pass()); |
| 1028 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 1029 |
| 1030 CreateChannelAndConnectSuccessfully(); |
| 1031 EXPECT_EQ(NULL, channel_.get()); |
| 1032 } |
| 1033 |
| 1034 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToBadControlFrame) { |
| 1035 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 1036 new ReadableFakeWebSocketStream); |
| 1037 static const InitFrame frames[] = { |
| 1038 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}}; |
| 1039 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 1040 set_stream(stream.Pass()); |
| 1041 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 1042 |
| 1043 CreateChannelAndConnectSuccessfully(); |
| 1044 EXPECT_EQ(NULL, channel_.get()); |
| 1045 } |
| 1046 |
| 1047 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToPongAfterClose) { |
| 1048 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 1049 new ReadableFakeWebSocketStream); |
| 1050 static const InitFrame frames[] = { |
| 1051 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, |
| 1052 CLOSE_DATA(NORMAL_CLOSURE, "Success")}, |
| 1053 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}}; |
| 1054 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 1055 set_stream(stream.Pass()); |
| 1056 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 1057 |
| 1058 CreateChannelAndConnectSuccessfully(); |
| 1059 EXPECT_EQ(NULL, channel_.get()); |
| 1060 } |
| 1061 |
| 1062 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToUnknownOpCode) { |
| 1063 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 1064 new ReadableFakeWebSocketStream); |
| 1065 static const InitFrame frames[] = {{FINAL_FRAME, 0x7, NOT_MASKED, ""}}; |
| 1066 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 1067 set_stream(stream.Pass()); |
| 1068 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 1069 |
| 1070 CreateChannelAndConnectSuccessfully(); |
| 1071 EXPECT_EQ(NULL, channel_.get()); |
| 1072 } |
| 1073 |
| 794 TEST_F(WebSocketChannelEventInterfaceTest, ConnectSuccessReported) { | 1074 TEST_F(WebSocketChannelEventInterfaceTest, ConnectSuccessReported) { |
| 795 // false means success. | 1075 // false means success. |
| 796 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, "")); | 1076 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, "")); |
| 797 // OnFlowControl is always called immediately after connect to provide initial | 1077 // OnFlowControl is always called immediately after connect to provide initial |
| 798 // quota to the renderer. | 1078 // quota to the renderer. |
| 799 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1079 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| 800 | 1080 |
| 801 CreateChannelAndConnect(); | 1081 CreateChannelAndConnect(); |
| 802 | 1082 |
| 803 connect_data_.factory.connect_delegate->OnSuccess(stream_.Pass()); | 1083 connect_data_.factory.connect_delegate->OnSuccess(stream_.Pass()); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 CreateChannelAndConnectSuccessfully(); | 1170 CreateChannelAndConnectSuccessfully(); |
| 891 } | 1171 } |
| 892 | 1172 |
| 893 TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) { | 1173 TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) { |
| 894 scoped_ptr<ReadableFakeWebSocketStream> stream( | 1174 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 895 new ReadableFakeWebSocketStream); | 1175 new ReadableFakeWebSocketStream); |
| 896 static const InitFrame frames[] = { | 1176 static const InitFrame frames[] = { |
| 897 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; | 1177 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; |
| 898 // We use this checkpoint object to verify that the callback isn't called | 1178 // We use this checkpoint object to verify that the callback isn't called |
| 899 // until we expect it to be. | 1179 // until we expect it to be. |
| 900 MockFunction<void(int)> checkpoint; | 1180 Checkpoint checkpoint; |
| 901 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); | 1181 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); |
| 902 set_stream(stream.Pass()); | 1182 set_stream(stream.Pass()); |
| 903 { | 1183 { |
| 904 InSequence s; | 1184 InSequence s; |
| 905 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); | 1185 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
| 906 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1186 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| 907 EXPECT_CALL(checkpoint, Call(1)); | 1187 EXPECT_CALL(checkpoint, Call(1)); |
| 908 EXPECT_CALL( | 1188 EXPECT_CALL( |
| 909 *event_interface_, | 1189 *event_interface_, |
| 910 OnDataFrame( | 1190 OnDataFrame( |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1178 CreateChannelAndConnectSuccessfully(); | 1458 CreateChannelAndConnectSuccessfully(); |
| 1179 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("B")); | 1459 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("B")); |
| 1180 } | 1460 } |
| 1181 | 1461 |
| 1182 // If we send enough to go below send_quota_low_water_mask_ we should get our | 1462 // If we send enough to go below send_quota_low_water_mask_ we should get our |
| 1183 // quota refreshed. | 1463 // quota refreshed. |
| 1184 TEST_F(WebSocketChannelEventInterfaceTest, LargeWriteUpdatesQuota) { | 1464 TEST_F(WebSocketChannelEventInterfaceTest, LargeWriteUpdatesQuota) { |
| 1185 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); | 1465 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); |
| 1186 // We use this checkpoint object to verify that the quota update comes after | 1466 // We use this checkpoint object to verify that the quota update comes after |
| 1187 // the write. | 1467 // the write. |
| 1188 MockFunction<void(int)> checkpoint; | 1468 Checkpoint checkpoint; |
| 1189 { | 1469 { |
| 1190 InSequence s; | 1470 InSequence s; |
| 1191 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); | 1471 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
| 1192 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1472 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| 1193 EXPECT_CALL(checkpoint, Call(1)); | 1473 EXPECT_CALL(checkpoint, Call(1)); |
| 1194 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1474 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| 1195 EXPECT_CALL(checkpoint, Call(2)); | 1475 EXPECT_CALL(checkpoint, Call(2)); |
| 1196 } | 1476 } |
| 1197 | 1477 |
| 1198 CreateChannelAndConnectSuccessfully(); | 1478 CreateChannelAndConnectSuccessfully(); |
| 1199 checkpoint.Call(1); | 1479 checkpoint.Call(1); |
| 1200 channel_->SendFrame(true, | 1480 channel_->SendFrame(true, |
| 1201 WebSocketFrameHeader::kOpCodeText, | 1481 WebSocketFrameHeader::kOpCodeText, |
| 1202 std::vector<char>(kDefaultInitialQuota, 'B')); | 1482 std::vector<char>(kDefaultInitialQuota, 'B')); |
| 1203 checkpoint.Call(2); | 1483 checkpoint.Call(2); |
| 1204 } | 1484 } |
| 1205 | 1485 |
| 1206 // Verify that our quota actually is refreshed when we are told it is. | 1486 // Verify that our quota actually is refreshed when we are told it is. |
| 1207 TEST_F(WebSocketChannelEventInterfaceTest, QuotaReallyIsRefreshed) { | 1487 TEST_F(WebSocketChannelEventInterfaceTest, QuotaReallyIsRefreshed) { |
| 1208 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); | 1488 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); |
| 1209 MockFunction<void(int)> checkpoint; | 1489 Checkpoint checkpoint; |
| 1210 { | 1490 { |
| 1211 InSequence s; | 1491 InSequence s; |
| 1212 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); | 1492 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
| 1213 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1493 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| 1214 EXPECT_CALL(checkpoint, Call(1)); | 1494 EXPECT_CALL(checkpoint, Call(1)); |
| 1215 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1495 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| 1216 EXPECT_CALL(checkpoint, Call(2)); | 1496 EXPECT_CALL(checkpoint, Call(2)); |
| 1217 // If quota was not really refreshed, we would get an OnDropChannel() | 1497 // If quota was not really refreshed, we would get an OnDropChannel() |
| 1218 // message. | 1498 // message. |
| 1219 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1499 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1247 | 1527 |
| 1248 CreateChannelAndConnectSuccessfully(); | 1528 CreateChannelAndConnectSuccessfully(); |
| 1249 channel_->SendFrame(true, | 1529 channel_->SendFrame(true, |
| 1250 WebSocketFrameHeader::kOpCodeText, | 1530 WebSocketFrameHeader::kOpCodeText, |
| 1251 std::vector<char>(kDefaultInitialQuota + 1, 'C')); | 1531 std::vector<char>(kDefaultInitialQuota + 1, 'C')); |
| 1252 } | 1532 } |
| 1253 | 1533 |
| 1254 // If a write fails, the channel is dropped. | 1534 // If a write fails, the channel is dropped. |
| 1255 TEST_F(WebSocketChannelEventInterfaceTest, FailedWrite) { | 1535 TEST_F(WebSocketChannelEventInterfaceTest, FailedWrite) { |
| 1256 set_stream(make_scoped_ptr(new UnWriteableFakeWebSocketStream)); | 1536 set_stream(make_scoped_ptr(new UnWriteableFakeWebSocketStream)); |
| 1257 MockFunction<void(int)> checkpoint; | 1537 Checkpoint checkpoint; |
| 1258 { | 1538 { |
| 1259 InSequence s; | 1539 InSequence s; |
| 1260 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); | 1540 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
| 1261 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1541 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| 1262 EXPECT_CALL(checkpoint, Call(1)); | 1542 EXPECT_CALL(checkpoint, Call(1)); |
| 1263 EXPECT_CALL(*event_interface_, | 1543 EXPECT_CALL(*event_interface_, |
| 1264 OnDropChannel(kWebSocketErrorAbnormalClosure, _)); | 1544 OnDropChannel(kWebSocketErrorAbnormalClosure, _)); |
| 1265 EXPECT_CALL(checkpoint, Call(2)); | 1545 EXPECT_CALL(checkpoint, Call(2)); |
| 1266 } | 1546 } |
| 1267 | 1547 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1422 static const InitFrame frames_init[] = { | 1702 static const InitFrame frames_init[] = { |
| 1423 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, | 1703 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| 1424 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; | 1704 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; |
| 1425 | 1705 |
| 1426 // We store the parameters that were passed to ReadFrames() so that we can | 1706 // We store the parameters that were passed to ReadFrames() so that we can |
| 1427 // call them explicitly later. | 1707 // call them explicitly later. |
| 1428 CompletionCallback read_callback; | 1708 CompletionCallback read_callback; |
| 1429 ScopedVector<WebSocketFrame>* frames = NULL; | 1709 ScopedVector<WebSocketFrame>* frames = NULL; |
| 1430 | 1710 |
| 1431 // Use a checkpoint to make the ordering of events clearer. | 1711 // Use a checkpoint to make the ordering of events clearer. |
| 1432 MockFunction<void(int)> checkpoint; | 1712 Checkpoint checkpoint; |
| 1433 { | 1713 { |
| 1434 InSequence s; | 1714 InSequence s; |
| 1435 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); | 1715 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| 1436 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 1716 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| 1437 .WillOnce(DoAll(SaveArg<0>(&frames), | 1717 .WillOnce(DoAll(SaveArg<0>(&frames), |
| 1438 SaveArg<1>(&read_callback), | 1718 SaveArg<1>(&read_callback), |
| 1439 Return(ERR_IO_PENDING))); | 1719 Return(ERR_IO_PENDING))); |
| 1440 EXPECT_CALL(checkpoint, Call(1)); | 1720 EXPECT_CALL(checkpoint, Call(1)); |
| 1441 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) | 1721 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
| 1442 .WillOnce(Return(OK)); | 1722 .WillOnce(Return(OK)); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1541 } | 1821 } |
| 1542 | 1822 |
| 1543 // WriteFrames() may not be called until the previous write has completed. | 1823 // WriteFrames() may not be called until the previous write has completed. |
| 1544 // WebSocketChannel must buffer writes that happen in the meantime. | 1824 // WebSocketChannel must buffer writes that happen in the meantime. |
| 1545 TEST_F(WebSocketChannelStreamTest, WriteFramesOneAtATime) { | 1825 TEST_F(WebSocketChannelStreamTest, WriteFramesOneAtATime) { |
| 1546 static const InitFrame expected1[] = { | 1826 static const InitFrame expected1[] = { |
| 1547 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "Hello "}}; | 1827 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "Hello "}}; |
| 1548 static const InitFrame expected2[] = { | 1828 static const InitFrame expected2[] = { |
| 1549 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "World"}}; | 1829 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "World"}}; |
| 1550 CompletionCallback write_callback; | 1830 CompletionCallback write_callback; |
| 1551 MockFunction<void(int)> checkpoint; | 1831 Checkpoint checkpoint; |
| 1552 | 1832 |
| 1553 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); | 1833 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| 1554 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); | 1834 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); |
| 1555 { | 1835 { |
| 1556 InSequence s; | 1836 InSequence s; |
| 1557 EXPECT_CALL(checkpoint, Call(1)); | 1837 EXPECT_CALL(checkpoint, Call(1)); |
| 1558 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _)) | 1838 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _)) |
| 1559 .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING))); | 1839 .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING))); |
| 1560 EXPECT_CALL(checkpoint, Call(2)); | 1840 EXPECT_CALL(checkpoint, Call(2)); |
| 1561 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _)) | 1841 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _)) |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1722 .WillOnce(Return(ERR_WS_PROTOCOL_ERROR)); | 2002 .WillOnce(Return(ERR_WS_PROTOCOL_ERROR)); |
| 1723 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) | 2003 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
| 1724 .WillOnce(Return(OK)); | 2004 .WillOnce(Return(OK)); |
| 1725 EXPECT_CALL(*mock_stream_, Close()); | 2005 EXPECT_CALL(*mock_stream_, Close()); |
| 1726 | 2006 |
| 1727 CreateChannelAndConnectSuccessfully(); | 2007 CreateChannelAndConnectSuccessfully(); |
| 1728 } | 2008 } |
| 1729 | 2009 |
| 1730 } // namespace | 2010 } // namespace |
| 1731 } // namespace net | 2011 } // namespace net |
| OLD | NEW |