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/base/test_completion_callback.h" | 24 #include "net/base/test_completion_callback.h" |
24 #include "net/url_request/url_request_context.h" | 25 #include "net/url_request/url_request_context.h" |
25 #include "net/websockets/websocket_errors.h" | 26 #include "net/websockets/websocket_errors.h" |
26 #include "net/websockets/websocket_event_interface.h" | 27 #include "net/websockets/websocket_event_interface.h" |
27 #include "net/websockets/websocket_mux.h" | 28 #include "net/websockets/websocket_mux.h" |
28 #include "testing/gmock/include/gmock/gmock.h" | 29 #include "testing/gmock/include/gmock/gmock.h" |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 std::ostream& operator<<(std::ostream& os, | 82 std::ostream& operator<<(std::ostream& os, |
82 const ScopedVector<WebSocketFrame>* vector) { | 83 const ScopedVector<WebSocketFrame>* vector) { |
83 return os << '&' << *vector; | 84 return os << '&' << *vector; |
84 } | 85 } |
85 | 86 |
86 namespace { | 87 namespace { |
87 | 88 |
88 using ::base::TimeDelta; | 89 using ::base::TimeDelta; |
89 | 90 |
90 using ::testing::AnyNumber; | 91 using ::testing::AnyNumber; |
| 92 using ::testing::DefaultValue; |
91 using ::testing::InSequence; | 93 using ::testing::InSequence; |
92 using ::testing::MockFunction; | 94 using ::testing::MockFunction; |
93 using ::testing::Return; | 95 using ::testing::Return; |
94 using ::testing::SaveArg; | 96 using ::testing::SaveArg; |
95 using ::testing::StrictMock; | 97 using ::testing::StrictMock; |
96 using ::testing::_; | 98 using ::testing::_; |
97 | 99 |
98 // A selection of characters that have traditionally been mangled in some | 100 // A selection of characters that have traditionally been mangled in some |
99 // environment or other, for testing 8-bit cleanliness. | 101 // environment or other, for testing 8-bit cleanliness. |
100 const char kBinaryBlob[] = {'\n', '\r', // BACKWARDS CRNL | 102 const char kBinaryBlob[] = {'\n', '\r', // BACKWARDS CRNL |
(...skipping 15 matching lines...) Expand all Loading... |
116 const size_t kDefaultInitialQuota = 1 << 17; | 118 const size_t kDefaultInitialQuota = 1 << 17; |
117 // The amount of bytes we need to send after the initial connection to trigger a | 119 // The amount of bytes we need to send after the initial connection to trigger a |
118 // quota refresh. TODO(ricea): Change this if kDefaultSendQuotaHighWaterMark or | 120 // quota refresh. TODO(ricea): Change this if kDefaultSendQuotaHighWaterMark or |
119 // kDefaultSendQuotaLowWaterMark change. | 121 // kDefaultSendQuotaLowWaterMark change. |
120 const size_t kDefaultQuotaRefreshTrigger = (1 << 16) + 1; | 122 const size_t kDefaultQuotaRefreshTrigger = (1 << 16) + 1; |
121 | 123 |
122 // TestTimeouts::tiny_timeout() is 100ms! I could run halfway around the world | 124 // TestTimeouts::tiny_timeout() is 100ms! I could run halfway around the world |
123 // in that time! I would like my tests to run a bit quicker. | 125 // in that time! I would like my tests to run a bit quicker. |
124 const int kVeryTinyTimeoutMillis = 1; | 126 const int kVeryTinyTimeoutMillis = 1; |
125 | 127 |
| 128 typedef WebSocketEventInterface::ChannelState ChannelState; |
| 129 const ChannelState CHANNEL_ALIVE = WebSocketEventInterface::CHANNEL_ALIVE; |
| 130 const ChannelState CHANNEL_DELETED = WebSocketEventInterface::CHANNEL_DELETED; |
| 131 |
| 132 // This typedef mainly exists to avoid having to repeat the "NOLINT" incantation |
| 133 // all over the place. |
| 134 typedef MockFunction<void(int)> Checkpoint; // NOLINT |
| 135 |
126 // This mock is for testing expectations about how the EventInterface is used. | 136 // This mock is for testing expectations about how the EventInterface is used. |
127 class MockWebSocketEventInterface : public WebSocketEventInterface { | 137 class MockWebSocketEventInterface : public WebSocketEventInterface { |
128 public: | 138 public: |
129 MOCK_METHOD2(OnAddChannelResponse, void(bool, const std::string&)); | 139 MOCK_METHOD2(OnAddChannelResponse, |
| 140 ChannelState(bool, const std::string&)); // NOLINT |
130 MOCK_METHOD3(OnDataFrame, | 141 MOCK_METHOD3(OnDataFrame, |
131 void(bool, WebSocketMessageType, const std::vector<char>&)); | 142 ChannelState(bool, |
132 MOCK_METHOD1(OnFlowControl, void(int64)); | 143 WebSocketMessageType, |
133 MOCK_METHOD0(OnClosingHandshake, void(void)); | 144 const std::vector<char>&)); // NOLINT |
134 MOCK_METHOD2(OnDropChannel, void(uint16, const std::string&)); | 145 MOCK_METHOD1(OnFlowControl, ChannelState(int64)); // NOLINT |
| 146 MOCK_METHOD0(OnClosingHandshake, ChannelState(void)); // NOLINT |
| 147 MOCK_METHOD2(OnDropChannel, |
| 148 ChannelState(uint16, const std::string&)); // NOLINT |
135 }; | 149 }; |
136 | 150 |
137 // This fake EventInterface is for tests which need a WebSocketEventInterface | 151 // This fake EventInterface is for tests which need a WebSocketEventInterface |
138 // implementation but are not verifying how it is used. | 152 // implementation but are not verifying how it is used. |
139 class FakeWebSocketEventInterface : public WebSocketEventInterface { | 153 class FakeWebSocketEventInterface : public WebSocketEventInterface { |
140 virtual void OnAddChannelResponse( | 154 virtual ChannelState OnAddChannelResponse( |
141 bool fail, | 155 bool fail, |
142 const std::string& selected_protocol) OVERRIDE {} | 156 const std::string& selected_protocol) OVERRIDE { |
143 virtual void OnDataFrame(bool fin, | 157 return fail ? CHANNEL_DELETED : CHANNEL_ALIVE; |
144 WebSocketMessageType type, | 158 } |
145 const std::vector<char>& data) OVERRIDE {} | 159 virtual ChannelState OnDataFrame(bool fin, |
146 virtual void OnFlowControl(int64 quota) OVERRIDE {} | 160 WebSocketMessageType type, |
147 virtual void OnClosingHandshake() OVERRIDE {} | 161 const std::vector<char>& data) OVERRIDE { |
148 virtual void OnDropChannel(uint16 code, const std::string& reason) OVERRIDE {} | 162 return CHANNEL_ALIVE; |
| 163 } |
| 164 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE { |
| 165 return CHANNEL_ALIVE; |
| 166 } |
| 167 virtual ChannelState OnClosingHandshake() OVERRIDE { return CHANNEL_ALIVE; } |
| 168 virtual ChannelState OnDropChannel(uint16 code, |
| 169 const std::string& reason) OVERRIDE { |
| 170 return CHANNEL_DELETED; |
| 171 } |
149 }; | 172 }; |
150 | 173 |
151 // This fake WebSocketStream is for tests that require a WebSocketStream but are | 174 // This fake WebSocketStream is for tests that require a WebSocketStream but are |
152 // not testing the way it is used. It has minimal functionality to return | 175 // not testing the way it is used. It has minimal functionality to return |
153 // the |protocol| and |extensions| that it was constructed with. | 176 // the |protocol| and |extensions| that it was constructed with. |
154 class FakeWebSocketStream : public WebSocketStream { | 177 class FakeWebSocketStream : public WebSocketStream { |
155 public: | 178 public: |
156 // Constructs with empty protocol and extensions. | 179 // Constructs with empty protocol and extensions. |
157 FakeWebSocketStream() {} | 180 FakeWebSocketStream() {} |
158 | 181 |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 void WaitForResult() { callback_.WaitForResult(); } | 378 void WaitForResult() { callback_.WaitForResult(); } |
356 | 379 |
357 private: | 380 private: |
358 // Delegate to TestCompletionCallback for the implementation. | 381 // Delegate to TestCompletionCallback for the implementation. |
359 TestCompletionCallback callback_; | 382 TestCompletionCallback callback_; |
360 }; | 383 }; |
361 | 384 |
362 // A GoogleMock action to run a Closure. | 385 // A GoogleMock action to run a Closure. |
363 ACTION_P(InvokeClosure, closure) { closure.Run(); } | 386 ACTION_P(InvokeClosure, closure) { closure.Run(); } |
364 | 387 |
| 388 // A GoogleMock action to run a Closure and return CHANNEL_DELETED. |
| 389 ACTION_P(InvokeClosureReturnDeleted, closure) { |
| 390 closure.Run(); |
| 391 return WebSocketEventInterface::CHANNEL_DELETED; |
| 392 } |
| 393 |
365 // A FakeWebSocketStream whose ReadFrames() function returns data. | 394 // A FakeWebSocketStream whose ReadFrames() function returns data. |
366 class ReadableFakeWebSocketStream : public FakeWebSocketStream { | 395 class ReadableFakeWebSocketStream : public FakeWebSocketStream { |
367 public: | 396 public: |
368 enum IsSync { | 397 enum IsSync { |
369 SYNC, | 398 SYNC, |
370 ASYNC | 399 ASYNC |
371 }; | 400 }; |
372 | 401 |
373 // After constructing the object, call PrepareReadFrames() once for each | 402 // After constructing the object, call PrepareReadFrames() once for each |
374 // time you wish it to return from the test. | 403 // time you wish it to return from the test. |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 CompletionCallback read_callback_; | 580 CompletionCallback read_callback_; |
552 // Owned by the caller of ReadFrames(). | 581 // Owned by the caller of ReadFrames(). |
553 ScopedVector<WebSocketFrame>* read_frames_; | 582 ScopedVector<WebSocketFrame>* read_frames_; |
554 // True if we should close the connection. | 583 // True if we should close the connection. |
555 bool done_; | 584 bool done_; |
556 }; | 585 }; |
557 | 586 |
558 // A FakeWebSocketStream where writes trigger a connection reset. | 587 // A FakeWebSocketStream where writes trigger a connection reset. |
559 // This differs from UnWriteableFakeWebSocketStream in that it is asynchronous | 588 // This differs from UnWriteableFakeWebSocketStream in that it is asynchronous |
560 // and triggers ReadFrames to return a reset as well. Tests using this need to | 589 // and triggers ReadFrames to return a reset as well. Tests using this need to |
561 // run the message loop. | 590 // run the message loop. There are two tricky parts here: |
| 591 // 1. Calling the write callback may call Close(), after which the read callback |
| 592 // should not be called. |
| 593 // 2. Calling either callback may delete the stream altogether. |
562 class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream { | 594 class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream { |
563 public: | 595 public: |
| 596 ResetOnWriteFakeWebSocketStream() : closed_(false), weak_ptr_factory_(this) {} |
| 597 |
564 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, | 598 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, |
565 const CompletionCallback& callback) OVERRIDE { | 599 const CompletionCallback& callback) OVERRIDE { |
566 base::MessageLoop::current()->PostTask( | 600 base::MessageLoop::current()->PostTask( |
567 FROM_HERE, base::Bind(callback, ERR_CONNECTION_RESET)); | 601 FROM_HERE, |
| 602 base::Bind(&ResetOnWriteFakeWebSocketStream::CallCallbackUnlessClosed, |
| 603 weak_ptr_factory_.GetWeakPtr(), |
| 604 callback, |
| 605 ERR_CONNECTION_RESET)); |
568 base::MessageLoop::current()->PostTask( | 606 base::MessageLoop::current()->PostTask( |
569 FROM_HERE, base::Bind(read_callback_, ERR_CONNECTION_RESET)); | 607 FROM_HERE, |
| 608 base::Bind(&ResetOnWriteFakeWebSocketStream::CallCallbackUnlessClosed, |
| 609 weak_ptr_factory_.GetWeakPtr(), |
| 610 read_callback_, |
| 611 ERR_CONNECTION_RESET)); |
570 return ERR_IO_PENDING; | 612 return ERR_IO_PENDING; |
571 } | 613 } |
572 | 614 |
573 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, | 615 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, |
574 const CompletionCallback& callback) OVERRIDE { | 616 const CompletionCallback& callback) OVERRIDE { |
575 read_callback_ = callback; | 617 read_callback_ = callback; |
576 return ERR_IO_PENDING; | 618 return ERR_IO_PENDING; |
577 } | 619 } |
578 | 620 |
| 621 virtual void Close() OVERRIDE { closed_ = true; } |
| 622 |
579 private: | 623 private: |
| 624 void CallCallbackUnlessClosed(const CompletionCallback& callback, int value) { |
| 625 if (!closed_) |
| 626 callback.Run(value); |
| 627 } |
| 628 |
580 CompletionCallback read_callback_; | 629 CompletionCallback read_callback_; |
| 630 bool closed_; |
| 631 // An IO error can result in the socket being deleted, so we use weak pointers |
| 632 // to ensure correct behaviour in that case. |
| 633 base::WeakPtrFactory<ResetOnWriteFakeWebSocketStream> weak_ptr_factory_; |
581 }; | 634 }; |
582 | 635 |
583 // This mock is for verifying that WebSocket protocol semantics are obeyed (to | 636 // This mock is for verifying that WebSocket protocol semantics are obeyed (to |
584 // the extent that they are implemented in WebSocketCommon). | 637 // the extent that they are implemented in WebSocketCommon). |
585 class MockWebSocketStream : public WebSocketStream { | 638 class MockWebSocketStream : public WebSocketStream { |
586 public: | 639 public: |
587 MOCK_METHOD2(ReadFrames, | 640 MOCK_METHOD2(ReadFrames, |
588 int(ScopedVector<WebSocketFrame>* frames, | 641 int(ScopedVector<WebSocketFrame>* frames, |
589 const CompletionCallback& callback)); | 642 const CompletionCallback& callback)); |
590 MOCK_METHOD2(WriteFrames, | 643 MOCK_METHOD2(WriteFrames, |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 }; | 742 }; |
690 ConnectData connect_data_; | 743 ConnectData connect_data_; |
691 | 744 |
692 // The channel we are testing. Not initialised until SetChannel() is called. | 745 // The channel we are testing. Not initialised until SetChannel() is called. |
693 scoped_ptr<WebSocketChannel> channel_; | 746 scoped_ptr<WebSocketChannel> channel_; |
694 | 747 |
695 // A mock or fake stream for tests that need one. | 748 // A mock or fake stream for tests that need one. |
696 scoped_ptr<WebSocketStream> stream_; | 749 scoped_ptr<WebSocketStream> stream_; |
697 }; | 750 }; |
698 | 751 |
| 752 // enum of WebSocketEventInterface calls. These are intended to be or'd together |
| 753 // in order to instruct WebSocketChannelDeletingTest when it should fail. |
| 754 enum EventInterfaceCall { |
| 755 EVENT_ON_ADD_CHANNEL_RESPONSE = 0x1, |
| 756 EVENT_ON_DATA_FRAME = 0x2, |
| 757 EVENT_ON_FLOW_CONTROL = 0x4, |
| 758 EVENT_ON_CLOSING_HANDSHAKE = 0x8, |
| 759 EVENT_ON_DROP_CHANNEL = 0x10, |
| 760 }; |
| 761 |
699 class WebSocketChannelDeletingTest : public WebSocketChannelTest { | 762 class WebSocketChannelDeletingTest : public WebSocketChannelTest { |
700 public: | 763 public: |
701 void ResetChannel() { channel_.reset(); } | 764 ChannelState DeleteIfDeleting(EventInterfaceCall call) { |
| 765 if (deleting_ & call) { |
| 766 channel_.reset(); |
| 767 return CHANNEL_DELETED; |
| 768 } else { |
| 769 return CHANNEL_ALIVE; |
| 770 } |
| 771 } |
702 | 772 |
703 protected: | 773 protected: |
| 774 WebSocketChannelDeletingTest() |
| 775 : deleting_(EVENT_ON_ADD_CHANNEL_RESPONSE | EVENT_ON_DATA_FRAME | |
| 776 EVENT_ON_FLOW_CONTROL | |
| 777 EVENT_ON_CLOSING_HANDSHAKE | |
| 778 EVENT_ON_DROP_CHANNEL) {} |
704 // Create a ChannelDeletingFakeWebSocketEventInterface. Defined out-of-line to | 779 // Create a ChannelDeletingFakeWebSocketEventInterface. Defined out-of-line to |
705 // avoid circular dependency. | 780 // avoid circular dependency. |
706 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE; | 781 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE; |
| 782 |
| 783 // Tests can set deleting_ to a bitmap of EventInterfaceCall members that they |
| 784 // want to cause Channel deletion. The default is for all calls to cause |
| 785 // deletion. |
| 786 int deleting_; |
707 }; | 787 }; |
708 | 788 |
709 // A FakeWebSocketEventInterface that deletes the WebSocketChannel on failure to | 789 // A FakeWebSocketEventInterface that deletes the WebSocketChannel on failure to |
710 // connect. | 790 // connect. |
711 class ChannelDeletingFakeWebSocketEventInterface | 791 class ChannelDeletingFakeWebSocketEventInterface |
712 : public FakeWebSocketEventInterface { | 792 : public FakeWebSocketEventInterface { |
713 public: | 793 public: |
714 ChannelDeletingFakeWebSocketEventInterface( | 794 ChannelDeletingFakeWebSocketEventInterface( |
715 WebSocketChannelDeletingTest* fixture) | 795 WebSocketChannelDeletingTest* fixture) |
716 : fixture_(fixture) {} | 796 : fixture_(fixture) {} |
717 | 797 |
718 virtual void OnAddChannelResponse( | 798 virtual ChannelState OnAddChannelResponse( |
719 bool fail, | 799 bool fail, |
720 const std::string& selected_protocol) OVERRIDE { | 800 const std::string& selected_protocol) OVERRIDE { |
721 if (fail) { | 801 return fixture_->DeleteIfDeleting(EVENT_ON_ADD_CHANNEL_RESPONSE); |
722 fixture_->ResetChannel(); | 802 } |
723 } | 803 |
| 804 virtual ChannelState OnDataFrame(bool fin, |
| 805 WebSocketMessageType type, |
| 806 const std::vector<char>& data) OVERRIDE { |
| 807 return fixture_->DeleteIfDeleting(EVENT_ON_DATA_FRAME); |
| 808 } |
| 809 |
| 810 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE { |
| 811 return fixture_->DeleteIfDeleting(EVENT_ON_FLOW_CONTROL); |
| 812 } |
| 813 |
| 814 virtual ChannelState OnClosingHandshake() OVERRIDE { |
| 815 return fixture_->DeleteIfDeleting(EVENT_ON_CLOSING_HANDSHAKE); |
| 816 } |
| 817 |
| 818 virtual ChannelState OnDropChannel(uint16 code, |
| 819 const std::string& reason) OVERRIDE { |
| 820 return fixture_->DeleteIfDeleting(EVENT_ON_DROP_CHANNEL); |
724 } | 821 } |
725 | 822 |
726 private: | 823 private: |
727 // A pointer to the test fixture. Owned by the test harness; this object will | 824 // A pointer to the test fixture. Owned by the test harness; this object will |
728 // be deleted before it is. | 825 // be deleted before it is. |
729 WebSocketChannelDeletingTest* fixture_; | 826 WebSocketChannelDeletingTest* fixture_; |
730 }; | 827 }; |
731 | 828 |
732 scoped_ptr<WebSocketEventInterface> | 829 scoped_ptr<WebSocketEventInterface> |
733 WebSocketChannelDeletingTest::CreateEventInterface() { | 830 WebSocketChannelDeletingTest::CreateEventInterface() { |
734 return scoped_ptr<WebSocketEventInterface>( | 831 return scoped_ptr<WebSocketEventInterface>( |
735 new ChannelDeletingFakeWebSocketEventInterface(this)); | 832 new ChannelDeletingFakeWebSocketEventInterface(this)); |
736 } | 833 } |
737 | 834 |
738 // Base class for tests which verify that EventInterface methods are called | 835 // Base class for tests which verify that EventInterface methods are called |
739 // appropriately. | 836 // appropriately. |
740 class WebSocketChannelEventInterfaceTest : public WebSocketChannelTest { | 837 class WebSocketChannelEventInterfaceTest : public WebSocketChannelTest { |
741 protected: | 838 protected: |
742 WebSocketChannelEventInterfaceTest() | 839 WebSocketChannelEventInterfaceTest() |
743 : event_interface_(new StrictMock<MockWebSocketEventInterface>) {} | 840 : event_interface_(new StrictMock<MockWebSocketEventInterface>) { |
| 841 DefaultValue<ChannelState>::Set(CHANNEL_ALIVE); |
| 842 ON_CALL(*event_interface_, OnAddChannelResponse(true, _)) |
| 843 .WillByDefault(Return(CHANNEL_DELETED)); |
| 844 ON_CALL(*event_interface_, OnDropChannel(_, _)) |
| 845 .WillByDefault(Return(CHANNEL_DELETED)); |
| 846 } |
| 847 |
| 848 virtual ~WebSocketChannelEventInterfaceTest() { |
| 849 DefaultValue<ChannelState>::Clear(); |
| 850 } |
744 | 851 |
745 // Tests using this fixture must set expectations on the event_interface_ mock | 852 // Tests using this fixture must set expectations on the event_interface_ mock |
746 // object before calling CreateChannelAndConnect() or | 853 // object before calling CreateChannelAndConnect() or |
747 // CreateChannelAndConnectSuccessfully(). This will only work once per test | 854 // CreateChannelAndConnectSuccessfully(). This will only work once per test |
748 // case, but once should be enough. | 855 // case, but once should be enough. |
749 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE { | 856 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE { |
750 return scoped_ptr<WebSocketEventInterface>(event_interface_.release()); | 857 return scoped_ptr<WebSocketEventInterface>(event_interface_.release()); |
751 } | 858 } |
752 | 859 |
753 scoped_ptr<MockWebSocketEventInterface> event_interface_; | 860 scoped_ptr<MockWebSocketEventInterface> event_interface_; |
(...skipping 26 matching lines...) Expand all Loading... |
780 const ArgumentCopyingWebSocketStreamFactory& actual = connect_data_.factory; | 887 const ArgumentCopyingWebSocketStreamFactory& actual = connect_data_.factory; |
781 | 888 |
782 EXPECT_EQ(&connect_data_.url_request_context, actual.url_request_context); | 889 EXPECT_EQ(&connect_data_.url_request_context, actual.url_request_context); |
783 | 890 |
784 EXPECT_EQ(connect_data_.socket_url, actual.socket_url); | 891 EXPECT_EQ(connect_data_.socket_url, actual.socket_url); |
785 EXPECT_EQ(connect_data_.requested_subprotocols, | 892 EXPECT_EQ(connect_data_.requested_subprotocols, |
786 actual.requested_subprotocols); | 893 actual.requested_subprotocols); |
787 EXPECT_EQ(connect_data_.origin, actual.origin); | 894 EXPECT_EQ(connect_data_.origin, actual.origin); |
788 } | 895 } |
789 | 896 |
790 // The documentation for WebSocketEventInterface::OnAddChannelResponse() says | 897 // Any WebSocketEventInterface methods can delete the WebSocketChannel and |
791 // that if the first argument is true, ie. the connection failed, then we can | 898 // return CHANNEL_DELETED. The WebSocketChannelDeletingTests are intended to |
792 // safely synchronously delete the WebSocketChannel. This test will only | 899 // verify that there are no use-after-free bugs when this happens. Problems will |
793 // reliably find problems if run with a memory debugger such as | 900 // probably only be found when running under Address Sanitizer or a similar |
794 // AddressSanitizer. | 901 // tool. |
795 TEST_F(WebSocketChannelDeletingTest, DeletingFromOnAddChannelResponseWorks) { | 902 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseFail) { |
796 CreateChannelAndConnect(); | 903 CreateChannelAndConnect(); |
| 904 EXPECT_TRUE(channel_); |
797 connect_data_.factory.connect_delegate->OnFailure( | 905 connect_data_.factory.connect_delegate->OnFailure( |
798 kWebSocketErrorNoStatusReceived); | 906 kWebSocketErrorNoStatusReceived); |
799 EXPECT_EQ(NULL, channel_.get()); | 907 EXPECT_EQ(NULL, channel_.get()); |
800 } | 908 } |
801 | 909 |
| 910 // Deletion is possible (due to IPC failure) even if the connect succeeds. |
| 911 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseSuccess) { |
| 912 CreateChannelAndConnectSuccessfully(); |
| 913 EXPECT_EQ(NULL, channel_.get()); |
| 914 } |
| 915 |
| 916 TEST_F(WebSocketChannelDeletingTest, OnDataFrameSync) { |
| 917 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 918 new ReadableFakeWebSocketStream); |
| 919 static const InitFrame frames[] = { |
| 920 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; |
| 921 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 922 set_stream(stream.Pass()); |
| 923 deleting_ = EVENT_ON_DATA_FRAME; |
| 924 |
| 925 CreateChannelAndConnectSuccessfully(); |
| 926 EXPECT_EQ(NULL, channel_.get()); |
| 927 } |
| 928 |
| 929 TEST_F(WebSocketChannelDeletingTest, OnDataFrameAsync) { |
| 930 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 931 new ReadableFakeWebSocketStream); |
| 932 static const InitFrame frames[] = { |
| 933 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; |
| 934 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); |
| 935 set_stream(stream.Pass()); |
| 936 deleting_ = EVENT_ON_DATA_FRAME; |
| 937 |
| 938 CreateChannelAndConnectSuccessfully(); |
| 939 EXPECT_TRUE(channel_); |
| 940 base::MessageLoop::current()->RunUntilIdle(); |
| 941 EXPECT_EQ(NULL, channel_.get()); |
| 942 } |
| 943 |
| 944 TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterConnect) { |
| 945 deleting_ = EVENT_ON_FLOW_CONTROL; |
| 946 |
| 947 CreateChannelAndConnectSuccessfully(); |
| 948 EXPECT_EQ(NULL, channel_.get()); |
| 949 } |
| 950 |
| 951 TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterSend) { |
| 952 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); |
| 953 // Avoid deleting the channel yet. |
| 954 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 955 CreateChannelAndConnectSuccessfully(); |
| 956 ASSERT_TRUE(channel_); |
| 957 deleting_ = EVENT_ON_FLOW_CONTROL; |
| 958 channel_->SendFrame(true, |
| 959 WebSocketFrameHeader::kOpCodeText, |
| 960 std::vector<char>(kDefaultInitialQuota, 'B')); |
| 961 EXPECT_EQ(NULL, channel_.get()); |
| 962 } |
| 963 |
| 964 TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeSync) { |
| 965 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 966 new ReadableFakeWebSocketStream); |
| 967 static const InitFrame frames[] = { |
| 968 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| 969 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; |
| 970 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 971 set_stream(stream.Pass()); |
| 972 deleting_ = EVENT_ON_CLOSING_HANDSHAKE; |
| 973 CreateChannelAndConnectSuccessfully(); |
| 974 EXPECT_EQ(NULL, channel_.get()); |
| 975 } |
| 976 |
| 977 TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeAsync) { |
| 978 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 979 new ReadableFakeWebSocketStream); |
| 980 static const InitFrame frames[] = { |
| 981 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| 982 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; |
| 983 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); |
| 984 set_stream(stream.Pass()); |
| 985 deleting_ = EVENT_ON_CLOSING_HANDSHAKE; |
| 986 CreateChannelAndConnectSuccessfully(); |
| 987 ASSERT_TRUE(channel_); |
| 988 base::MessageLoop::current()->RunUntilIdle(); |
| 989 EXPECT_EQ(NULL, channel_.get()); |
| 990 } |
| 991 |
| 992 TEST_F(WebSocketChannelDeletingTest, OnDropChannelWriteError) { |
| 993 set_stream(make_scoped_ptr(new UnWriteableFakeWebSocketStream)); |
| 994 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 995 CreateChannelAndConnectSuccessfully(); |
| 996 ASSERT_TRUE(channel_); |
| 997 channel_->SendFrame( |
| 998 true, WebSocketFrameHeader::kOpCodeText, AsVector("this will fail")); |
| 999 EXPECT_EQ(NULL, channel_.get()); |
| 1000 } |
| 1001 |
| 1002 TEST_F(WebSocketChannelDeletingTest, OnDropChannelReadError) { |
| 1003 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 1004 new ReadableFakeWebSocketStream); |
| 1005 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, |
| 1006 ERR_FAILED); |
| 1007 set_stream(stream.Pass()); |
| 1008 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 1009 CreateChannelAndConnectSuccessfully(); |
| 1010 ASSERT_TRUE(channel_); |
| 1011 base::MessageLoop::current()->RunUntilIdle(); |
| 1012 EXPECT_EQ(NULL, channel_.get()); |
| 1013 } |
| 1014 |
| 1015 TEST_F(WebSocketChannelDeletingTest, FailChannelInSendFrame) { |
| 1016 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); |
| 1017 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 1018 CreateChannelAndConnectSuccessfully(); |
| 1019 ASSERT_TRUE(channel_); |
| 1020 channel_->SendFrame(true, |
| 1021 WebSocketFrameHeader::kOpCodeText, |
| 1022 std::vector<char>(kDefaultInitialQuota * 2, 'T')); |
| 1023 EXPECT_EQ(NULL, channel_.get()); |
| 1024 } |
| 1025 |
| 1026 TEST_F(WebSocketChannelDeletingTest, FailChannelInOnReadDone) { |
| 1027 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 1028 new ReadableFakeWebSocketStream); |
| 1029 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, |
| 1030 ERR_WS_PROTOCOL_ERROR); |
| 1031 set_stream(stream.Pass()); |
| 1032 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 1033 CreateChannelAndConnectSuccessfully(); |
| 1034 ASSERT_TRUE(channel_); |
| 1035 base::MessageLoop::current()->RunUntilIdle(); |
| 1036 EXPECT_EQ(NULL, channel_.get()); |
| 1037 } |
| 1038 |
| 1039 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToMaskedFrame) { |
| 1040 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 1041 new ReadableFakeWebSocketStream); |
| 1042 static const InitFrame frames[] = { |
| 1043 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}}; |
| 1044 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 1045 set_stream(stream.Pass()); |
| 1046 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 1047 |
| 1048 CreateChannelAndConnectSuccessfully(); |
| 1049 EXPECT_EQ(NULL, channel_.get()); |
| 1050 } |
| 1051 |
| 1052 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToBadControlFrame) { |
| 1053 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 1054 new ReadableFakeWebSocketStream); |
| 1055 static const InitFrame frames[] = { |
| 1056 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}}; |
| 1057 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 1058 set_stream(stream.Pass()); |
| 1059 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 1060 |
| 1061 CreateChannelAndConnectSuccessfully(); |
| 1062 EXPECT_EQ(NULL, channel_.get()); |
| 1063 } |
| 1064 |
| 1065 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToPongAfterClose) { |
| 1066 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 1067 new ReadableFakeWebSocketStream); |
| 1068 static const InitFrame frames[] = { |
| 1069 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, |
| 1070 CLOSE_DATA(NORMAL_CLOSURE, "Success")}, |
| 1071 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}}; |
| 1072 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 1073 set_stream(stream.Pass()); |
| 1074 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 1075 |
| 1076 CreateChannelAndConnectSuccessfully(); |
| 1077 EXPECT_EQ(NULL, channel_.get()); |
| 1078 } |
| 1079 |
| 1080 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToUnknownOpCode) { |
| 1081 scoped_ptr<ReadableFakeWebSocketStream> stream( |
| 1082 new ReadableFakeWebSocketStream); |
| 1083 static const InitFrame frames[] = {{FINAL_FRAME, 0x7, NOT_MASKED, ""}}; |
| 1084 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| 1085 set_stream(stream.Pass()); |
| 1086 deleting_ = EVENT_ON_DROP_CHANNEL; |
| 1087 |
| 1088 CreateChannelAndConnectSuccessfully(); |
| 1089 EXPECT_EQ(NULL, channel_.get()); |
| 1090 } |
| 1091 |
802 TEST_F(WebSocketChannelEventInterfaceTest, ConnectSuccessReported) { | 1092 TEST_F(WebSocketChannelEventInterfaceTest, ConnectSuccessReported) { |
803 // false means success. | 1093 // false means success. |
804 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, "")); | 1094 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, "")); |
805 // OnFlowControl is always called immediately after connect to provide initial | 1095 // OnFlowControl is always called immediately after connect to provide initial |
806 // quota to the renderer. | 1096 // quota to the renderer. |
807 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1097 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
808 | 1098 |
809 CreateChannelAndConnect(); | 1099 CreateChannelAndConnect(); |
810 | 1100 |
811 connect_data_.factory.connect_delegate->OnSuccess(stream_.Pass()); | 1101 connect_data_.factory.connect_delegate->OnSuccess(stream_.Pass()); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 CreateChannelAndConnectSuccessfully(); | 1188 CreateChannelAndConnectSuccessfully(); |
899 } | 1189 } |
900 | 1190 |
901 TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) { | 1191 TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) { |
902 scoped_ptr<ReadableFakeWebSocketStream> stream( | 1192 scoped_ptr<ReadableFakeWebSocketStream> stream( |
903 new ReadableFakeWebSocketStream); | 1193 new ReadableFakeWebSocketStream); |
904 static const InitFrame frames[] = { | 1194 static const InitFrame frames[] = { |
905 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; | 1195 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; |
906 // We use this checkpoint object to verify that the callback isn't called | 1196 // We use this checkpoint object to verify that the callback isn't called |
907 // until we expect it to be. | 1197 // until we expect it to be. |
908 MockFunction<void(int)> checkpoint; | 1198 Checkpoint checkpoint; |
909 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); | 1199 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); |
910 set_stream(stream.Pass()); | 1200 set_stream(stream.Pass()); |
911 { | 1201 { |
912 InSequence s; | 1202 InSequence s; |
913 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); | 1203 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
914 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1204 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
915 EXPECT_CALL(checkpoint, Call(1)); | 1205 EXPECT_CALL(checkpoint, Call(1)); |
916 EXPECT_CALL( | 1206 EXPECT_CALL( |
917 *event_interface_, | 1207 *event_interface_, |
918 OnDataFrame( | 1208 OnDataFrame( |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1186 CreateChannelAndConnectSuccessfully(); | 1476 CreateChannelAndConnectSuccessfully(); |
1187 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("B")); | 1477 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("B")); |
1188 } | 1478 } |
1189 | 1479 |
1190 // If we send enough to go below send_quota_low_water_mask_ we should get our | 1480 // If we send enough to go below send_quota_low_water_mask_ we should get our |
1191 // quota refreshed. | 1481 // quota refreshed. |
1192 TEST_F(WebSocketChannelEventInterfaceTest, LargeWriteUpdatesQuota) { | 1482 TEST_F(WebSocketChannelEventInterfaceTest, LargeWriteUpdatesQuota) { |
1193 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); | 1483 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); |
1194 // We use this checkpoint object to verify that the quota update comes after | 1484 // We use this checkpoint object to verify that the quota update comes after |
1195 // the write. | 1485 // the write. |
1196 MockFunction<void(int)> checkpoint; | 1486 Checkpoint checkpoint; |
1197 { | 1487 { |
1198 InSequence s; | 1488 InSequence s; |
1199 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); | 1489 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
1200 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1490 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
1201 EXPECT_CALL(checkpoint, Call(1)); | 1491 EXPECT_CALL(checkpoint, Call(1)); |
1202 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1492 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
1203 EXPECT_CALL(checkpoint, Call(2)); | 1493 EXPECT_CALL(checkpoint, Call(2)); |
1204 } | 1494 } |
1205 | 1495 |
1206 CreateChannelAndConnectSuccessfully(); | 1496 CreateChannelAndConnectSuccessfully(); |
1207 checkpoint.Call(1); | 1497 checkpoint.Call(1); |
1208 channel_->SendFrame(true, | 1498 channel_->SendFrame(true, |
1209 WebSocketFrameHeader::kOpCodeText, | 1499 WebSocketFrameHeader::kOpCodeText, |
1210 std::vector<char>(kDefaultInitialQuota, 'B')); | 1500 std::vector<char>(kDefaultInitialQuota, 'B')); |
1211 checkpoint.Call(2); | 1501 checkpoint.Call(2); |
1212 } | 1502 } |
1213 | 1503 |
1214 // Verify that our quota actually is refreshed when we are told it is. | 1504 // Verify that our quota actually is refreshed when we are told it is. |
1215 TEST_F(WebSocketChannelEventInterfaceTest, QuotaReallyIsRefreshed) { | 1505 TEST_F(WebSocketChannelEventInterfaceTest, QuotaReallyIsRefreshed) { |
1216 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); | 1506 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); |
1217 MockFunction<void(int)> checkpoint; | 1507 Checkpoint checkpoint; |
1218 { | 1508 { |
1219 InSequence s; | 1509 InSequence s; |
1220 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); | 1510 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
1221 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1511 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
1222 EXPECT_CALL(checkpoint, Call(1)); | 1512 EXPECT_CALL(checkpoint, Call(1)); |
1223 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1513 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
1224 EXPECT_CALL(checkpoint, Call(2)); | 1514 EXPECT_CALL(checkpoint, Call(2)); |
1225 // If quota was not really refreshed, we would get an OnDropChannel() | 1515 // If quota was not really refreshed, we would get an OnDropChannel() |
1226 // message. | 1516 // message. |
1227 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1517 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
(...skipping 27 matching lines...) Expand all Loading... |
1255 | 1545 |
1256 CreateChannelAndConnectSuccessfully(); | 1546 CreateChannelAndConnectSuccessfully(); |
1257 channel_->SendFrame(true, | 1547 channel_->SendFrame(true, |
1258 WebSocketFrameHeader::kOpCodeText, | 1548 WebSocketFrameHeader::kOpCodeText, |
1259 std::vector<char>(kDefaultInitialQuota + 1, 'C')); | 1549 std::vector<char>(kDefaultInitialQuota + 1, 'C')); |
1260 } | 1550 } |
1261 | 1551 |
1262 // If a write fails, the channel is dropped. | 1552 // If a write fails, the channel is dropped. |
1263 TEST_F(WebSocketChannelEventInterfaceTest, FailedWrite) { | 1553 TEST_F(WebSocketChannelEventInterfaceTest, FailedWrite) { |
1264 set_stream(make_scoped_ptr(new UnWriteableFakeWebSocketStream)); | 1554 set_stream(make_scoped_ptr(new UnWriteableFakeWebSocketStream)); |
1265 MockFunction<void(int)> checkpoint; | 1555 Checkpoint checkpoint; |
1266 { | 1556 { |
1267 InSequence s; | 1557 InSequence s; |
1268 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); | 1558 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
1269 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1559 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
1270 EXPECT_CALL(checkpoint, Call(1)); | 1560 EXPECT_CALL(checkpoint, Call(1)); |
1271 EXPECT_CALL(*event_interface_, | 1561 EXPECT_CALL(*event_interface_, |
1272 OnDropChannel(kWebSocketErrorAbnormalClosure, _)); | 1562 OnDropChannel(kWebSocketErrorAbnormalClosure, _)); |
1273 EXPECT_CALL(checkpoint, Call(2)); | 1563 EXPECT_CALL(checkpoint, Call(2)); |
1274 } | 1564 } |
1275 | 1565 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1374 ClientInitiatedClosingHandshakeTimesOut) { | 1664 ClientInitiatedClosingHandshakeTimesOut) { |
1375 scoped_ptr<ReadableFakeWebSocketStream> stream( | 1665 scoped_ptr<ReadableFakeWebSocketStream> stream( |
1376 new ReadableFakeWebSocketStream); | 1666 new ReadableFakeWebSocketStream); |
1377 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, | 1667 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, |
1378 ERR_IO_PENDING); | 1668 ERR_IO_PENDING); |
1379 set_stream(stream.Pass()); | 1669 set_stream(stream.Pass()); |
1380 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); | 1670 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
1381 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1671 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
1382 // This checkpoint object verifies that the OnDropChannel message comes after | 1672 // This checkpoint object verifies that the OnDropChannel message comes after |
1383 // the timeout. | 1673 // the timeout. |
1384 MockFunction<void(int)> checkpoint; | 1674 Checkpoint checkpoint; |
1385 TestClosure completion; | 1675 TestClosure completion; |
1386 { | 1676 { |
1387 InSequence s; | 1677 InSequence s; |
1388 EXPECT_CALL(checkpoint, Call(1)); | 1678 EXPECT_CALL(checkpoint, Call(1)); |
1389 EXPECT_CALL(*event_interface_, | 1679 EXPECT_CALL(*event_interface_, |
1390 OnDropChannel(kWebSocketErrorAbnormalClosure, _)) | 1680 OnDropChannel(kWebSocketErrorAbnormalClosure, _)) |
1391 .WillOnce(InvokeClosure(completion.closure())); | 1681 .WillOnce(InvokeClosureReturnDeleted(completion.closure())); |
1392 } | 1682 } |
1393 CreateChannelAndConnectSuccessfully(); | 1683 CreateChannelAndConnectSuccessfully(); |
1394 // OneShotTimer is not very friendly to testing; there is no apparent way to | 1684 // OneShotTimer is not very friendly to testing; there is no apparent way to |
1395 // set an expectation on it. Instead the tests need to infer that the timeout | 1685 // set an expectation on it. Instead the tests need to infer that the timeout |
1396 // was fired by the behaviour of the WebSocketChannel object. | 1686 // was fired by the behaviour of the WebSocketChannel object. |
1397 channel_->SetClosingHandshakeTimeoutForTesting( | 1687 channel_->SetClosingHandshakeTimeoutForTesting( |
1398 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); | 1688 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); |
1399 channel_->StartClosingHandshake(kWebSocketNormalClosure, ""); | 1689 channel_->StartClosingHandshake(kWebSocketNormalClosure, ""); |
1400 checkpoint.Call(1); | 1690 checkpoint.Call(1); |
1401 completion.WaitForResult(); | 1691 completion.WaitForResult(); |
1402 } | 1692 } |
1403 | 1693 |
1404 // The closing handshake times out and sends an OnDropChannel event if a Close | 1694 // The closing handshake times out and sends an OnDropChannel event if a Close |
1405 // message is received but the connection isn't closed by the remote host. | 1695 // message is received but the connection isn't closed by the remote host. |
1406 TEST_F(WebSocketChannelEventInterfaceTest, | 1696 TEST_F(WebSocketChannelEventInterfaceTest, |
1407 ServerInitiatedClosingHandshakeTimesOut) { | 1697 ServerInitiatedClosingHandshakeTimesOut) { |
1408 scoped_ptr<ReadableFakeWebSocketStream> stream( | 1698 scoped_ptr<ReadableFakeWebSocketStream> stream( |
1409 new ReadableFakeWebSocketStream); | 1699 new ReadableFakeWebSocketStream); |
1410 static const InitFrame frames[] = { | 1700 static const InitFrame frames[] = { |
1411 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, | 1701 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
1412 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; | 1702 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; |
1413 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); | 1703 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); |
1414 set_stream(stream.Pass()); | 1704 set_stream(stream.Pass()); |
1415 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); | 1705 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
1416 EXPECT_CALL(*event_interface_, OnFlowControl(_)); | 1706 EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
1417 MockFunction<void(int)> checkpoint; | 1707 Checkpoint checkpoint; |
1418 TestClosure completion; | 1708 TestClosure completion; |
1419 { | 1709 { |
1420 InSequence s; | 1710 InSequence s; |
1421 EXPECT_CALL(checkpoint, Call(1)); | 1711 EXPECT_CALL(checkpoint, Call(1)); |
1422 EXPECT_CALL(*event_interface_, OnClosingHandshake()); | 1712 EXPECT_CALL(*event_interface_, OnClosingHandshake()); |
1423 EXPECT_CALL(*event_interface_, | 1713 EXPECT_CALL(*event_interface_, |
1424 OnDropChannel(kWebSocketErrorAbnormalClosure, _)) | 1714 OnDropChannel(kWebSocketErrorAbnormalClosure, _)) |
1425 .WillOnce(InvokeClosure(completion.closure())); | 1715 .WillOnce(InvokeClosureReturnDeleted(completion.closure())); |
1426 } | 1716 } |
1427 CreateChannelAndConnectSuccessfully(); | 1717 CreateChannelAndConnectSuccessfully(); |
1428 channel_->SetClosingHandshakeTimeoutForTesting( | 1718 channel_->SetClosingHandshakeTimeoutForTesting( |
1429 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); | 1719 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); |
1430 checkpoint.Call(1); | 1720 checkpoint.Call(1); |
1431 completion.WaitForResult(); | 1721 completion.WaitForResult(); |
1432 } | 1722 } |
1433 | 1723 |
1434 // RFC6455 5.1 "a client MUST mask all frames that it sends to the server". | 1724 // RFC6455 5.1 "a client MUST mask all frames that it sends to the server". |
1435 // WebSocketChannel actually only sets the mask bit in the header, it doesn't | 1725 // WebSocketChannel actually only sets the mask bit in the header, it doesn't |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1493 static const InitFrame frames_init[] = { | 1783 static const InitFrame frames_init[] = { |
1494 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, | 1784 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
1495 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; | 1785 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; |
1496 | 1786 |
1497 // We store the parameters that were passed to ReadFrames() so that we can | 1787 // We store the parameters that were passed to ReadFrames() so that we can |
1498 // call them explicitly later. | 1788 // call them explicitly later. |
1499 CompletionCallback read_callback; | 1789 CompletionCallback read_callback; |
1500 ScopedVector<WebSocketFrame>* frames = NULL; | 1790 ScopedVector<WebSocketFrame>* frames = NULL; |
1501 | 1791 |
1502 // Use a checkpoint to make the ordering of events clearer. | 1792 // Use a checkpoint to make the ordering of events clearer. |
1503 MockFunction<void(int)> checkpoint; | 1793 Checkpoint checkpoint; |
1504 { | 1794 { |
1505 InSequence s; | 1795 InSequence s; |
1506 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); | 1796 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
1507 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 1797 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
1508 .WillOnce(DoAll(SaveArg<0>(&frames), | 1798 .WillOnce(DoAll(SaveArg<0>(&frames), |
1509 SaveArg<1>(&read_callback), | 1799 SaveArg<1>(&read_callback), |
1510 Return(ERR_IO_PENDING))); | 1800 Return(ERR_IO_PENDING))); |
1511 EXPECT_CALL(checkpoint, Call(1)); | 1801 EXPECT_CALL(checkpoint, Call(1)); |
1512 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) | 1802 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
1513 .WillOnce(Return(OK)); | 1803 .WillOnce(Return(OK)); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1645 } | 1935 } |
1646 | 1936 |
1647 // WriteFrames() may not be called until the previous write has completed. | 1937 // WriteFrames() may not be called until the previous write has completed. |
1648 // WebSocketChannel must buffer writes that happen in the meantime. | 1938 // WebSocketChannel must buffer writes that happen in the meantime. |
1649 TEST_F(WebSocketChannelStreamTest, WriteFramesOneAtATime) { | 1939 TEST_F(WebSocketChannelStreamTest, WriteFramesOneAtATime) { |
1650 static const InitFrame expected1[] = { | 1940 static const InitFrame expected1[] = { |
1651 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "Hello "}}; | 1941 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "Hello "}}; |
1652 static const InitFrame expected2[] = { | 1942 static const InitFrame expected2[] = { |
1653 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "World"}}; | 1943 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "World"}}; |
1654 CompletionCallback write_callback; | 1944 CompletionCallback write_callback; |
1655 MockFunction<void(int)> checkpoint; | 1945 Checkpoint checkpoint; |
1656 | 1946 |
1657 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); | 1947 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
1658 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); | 1948 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); |
1659 { | 1949 { |
1660 InSequence s; | 1950 InSequence s; |
1661 EXPECT_CALL(checkpoint, Call(1)); | 1951 EXPECT_CALL(checkpoint, Call(1)); |
1662 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _)) | 1952 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _)) |
1663 .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING))); | 1953 .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING))); |
1664 EXPECT_CALL(checkpoint, Call(2)); | 1954 EXPECT_CALL(checkpoint, Call(2)); |
1665 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _)) | 1955 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _)) |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1854 static const InitFrame frames[] = { | 2144 static const InitFrame frames[] = { |
1855 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, | 2145 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
1856 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; | 2146 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; |
1857 static const InitFrame expected[] = { | 2147 static const InitFrame expected[] = { |
1858 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, | 2148 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
1859 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; | 2149 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; |
1860 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); | 2150 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
1861 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) | 2151 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
1862 .WillOnce(ReturnFrames(&frames)) | 2152 .WillOnce(ReturnFrames(&frames)) |
1863 .WillRepeatedly(Return(ERR_IO_PENDING)); | 2153 .WillRepeatedly(Return(ERR_IO_PENDING)); |
1864 MockFunction<void(int)> checkpoint; | 2154 Checkpoint checkpoint; |
1865 TestClosure completion; | 2155 TestClosure completion; |
1866 { | 2156 { |
1867 InSequence s; | 2157 InSequence s; |
1868 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) | 2158 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
1869 .WillOnce(Return(OK)); | 2159 .WillOnce(Return(OK)); |
1870 EXPECT_CALL(checkpoint, Call(1)); | 2160 EXPECT_CALL(checkpoint, Call(1)); |
1871 EXPECT_CALL(*mock_stream_, Close()) | 2161 EXPECT_CALL(*mock_stream_, Close()) |
1872 .WillOnce(InvokeClosure(completion.closure())); | 2162 .WillOnce(InvokeClosure(completion.closure())); |
1873 } | 2163 } |
1874 | 2164 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1943 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK"); | 2233 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK"); |
1944 ASSERT_TRUE(read_frames); | 2234 ASSERT_TRUE(read_frames); |
1945 // Provide the "Close" message from the server. | 2235 // Provide the "Close" message from the server. |
1946 *read_frames = CreateFrameVector(frames); | 2236 *read_frames = CreateFrameVector(frames); |
1947 read_callback.Run(OK); | 2237 read_callback.Run(OK); |
1948 completion.WaitForResult(); | 2238 completion.WaitForResult(); |
1949 } | 2239 } |
1950 | 2240 |
1951 } // namespace | 2241 } // namespace |
1952 } // namespace net | 2242 } // namespace net |
OLD | NEW |