Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannelTest.cpp

Issue 2930263002: Add blink::WebSocketHandshakeThrottle (Closed)
Patch Set: Fixes from yhirano review Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "modules/websockets/WebSocketChannel.h" 5 #include "modules/websockets/DocumentWebSocketChannel.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <memory> 8 #include <memory>
9 #include "core/dom/DOMArrayBuffer.h" 9 #include "core/dom/DOMArrayBuffer.h"
10 #include "core/dom/Document.h" 10 #include "core/dom/Document.h"
11 #include "core/fileapi/Blob.h" 11 #include "core/fileapi/Blob.h"
12 #include "core/testing/DummyPageHolder.h" 12 #include "core/testing/DummyPageHolder.h"
13 #include "modules/websockets/DocumentWebSocketChannel.h" 13 #include "modules/websockets/WebSocketChannel.h"
14 #include "modules/websockets/WebSocketChannelClient.h" 14 #include "modules/websockets/WebSocketChannelClient.h"
15 #include "modules/websockets/WebSocketHandle.h" 15 #include "modules/websockets/WebSocketHandle.h"
16 #include "modules/websockets/WebSocketHandleClient.h" 16 #include "modules/websockets/WebSocketHandleClient.h"
17 #include "platform/heap/Handle.h" 17 #include "platform/heap/Handle.h"
18 #include "platform/weborigin/KURL.h" 18 #include "platform/weborigin/KURL.h"
19 #include "platform/wtf/PtrUtil.h" 19 #include "platform/wtf/PtrUtil.h"
20 #include "platform/wtf/Vector.h" 20 #include "platform/wtf/Vector.h"
21 #include "platform/wtf/text/WTFString.h" 21 #include "platform/wtf/text/WTFString.h"
22 #include "public/platform/WebCallbacks.h"
23 #include "public/platform/WebSocketHandshakeThrottle.h"
24 #include "public/platform/WebURL.h"
25 #include "public/web/WebLocalFrame.h"
22 #include "testing/gmock/include/gmock/gmock.h" 26 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/gtest/include/gtest/gtest.h"
24 28
25 using testing::_; 29 using testing::_;
26 using testing::InSequence; 30 using testing::InSequence;
27 using testing::PrintToString; 31 using testing::PrintToString;
28 using testing::AnyNumber; 32 using testing::AnyNumber;
29 using testing::SaveArg; 33 using testing::SaveArg;
30 34
31 namespace blink { 35 namespace blink {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 SecurityOrigin*, 86 SecurityOrigin*,
83 const KURL&, 87 const KURL&,
84 const String&, 88 const String&,
85 WebSocketHandleClient*)); 89 WebSocketHandleClient*));
86 MOCK_METHOD4(Send, 90 MOCK_METHOD4(Send,
87 void(bool, WebSocketHandle::MessageType, const char*, size_t)); 91 void(bool, WebSocketHandle::MessageType, const char*, size_t));
88 MOCK_METHOD1(FlowControl, void(int64_t)); 92 MOCK_METHOD1(FlowControl, void(int64_t));
89 MOCK_METHOD2(Close, void(unsigned short, const String&)); 93 MOCK_METHOD2(Close, void(unsigned short, const String&));
90 }; 94 };
91 95
96 class MockWebSocketHandshakeThrottle : public WebSocketHandshakeThrottle {
97 public:
98 static MockWebSocketHandshakeThrottle* Create() {
99 return new testing::StrictMock<MockWebSocketHandshakeThrottle>();
100 }
101 MockWebSocketHandshakeThrottle() {}
102 ~MockWebSocketHandshakeThrottle() override { Destructor(); }
103
104 MOCK_METHOD3(ThrottleHandshake,
105 void(const WebURL&,
106 WebLocalFrame*,
107 WebCallbacks<void, const WebString&>*));
108
109 // This method is used to allow us to require that the destructor is called at
110 // a particular time.
111 MOCK_METHOD0(Destructor, void());
112 };
113
92 class DocumentWebSocketChannelTest : public ::testing::Test { 114 class DocumentWebSocketChannelTest : public ::testing::Test {
93 public: 115 public:
94 DocumentWebSocketChannelTest() 116 DocumentWebSocketChannelTest()
95 : page_holder_(DummyPageHolder::Create()), 117 : page_holder_(DummyPageHolder::Create()),
96 channel_client_(MockWebSocketChannelClient::Create()), 118 channel_client_(MockWebSocketChannelClient::Create()),
97 handle_(MockWebSocketHandle::Create()), 119 handle_(MockWebSocketHandle::Create()),
98 channel_(DocumentWebSocketChannel::Create(&page_holder_->GetDocument(), 120 handshake_throttle_(nullptr),
99 channel_client_.Get(),
100 SourceLocation::Capture(),
101 Handle())),
102 sum_of_consumed_buffered_amount_(0) { 121 sum_of_consumed_buffered_amount_(0) {
103 ON_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)) 122 ON_CALL(*ChannelClient(), DidConsumeBufferedAmount(_))
104 .WillByDefault(Invoke( 123 .WillByDefault(Invoke(
105 this, &DocumentWebSocketChannelTest::DidConsumeBufferedAmount)); 124 this, &DocumentWebSocketChannelTest::DidConsumeBufferedAmount));
106 } 125 }
107 126
108 ~DocumentWebSocketChannelTest() { Channel()->Disconnect(); } 127 ~DocumentWebSocketChannelTest() { Channel()->Disconnect(); }
109 128
129 void SetUp() override {
130 channel_ = DocumentWebSocketChannel::CreateForTesting(
131 &page_holder_->GetDocument(), channel_client_.Get(),
132 SourceLocation::Capture(), Handle(),
133 WTF::WrapUnique(handshake_throttle_));
134 }
135
110 MockWebSocketChannelClient* ChannelClient() { return channel_client_.Get(); } 136 MockWebSocketChannelClient* ChannelClient() { return channel_client_.Get(); }
111 137
112 WebSocketChannel* Channel() { 138 WebSocketChannel* Channel() {
113 return static_cast<WebSocketChannel*>(channel_.Get()); 139 return static_cast<WebSocketChannel*>(channel_.Get());
114 } 140 }
115 141
116 WebSocketHandleClient* HandleClient() { 142 WebSocketHandleClient* HandleClient() {
117 return static_cast<WebSocketHandleClient*>(channel_.Get()); 143 return static_cast<WebSocketHandleClient*>(channel_.Get());
118 } 144 }
119 145
146 WebCallbacks<void, const WebString&>* WebCallbacks() {
147 return channel_.Get();
148 }
149
120 MockWebSocketHandle* Handle() { return handle_; } 150 MockWebSocketHandle* Handle() { return handle_; }
121 151
122 void DidConsumeBufferedAmount(unsigned long a) { 152 void DidConsumeBufferedAmount(unsigned long a) {
123 sum_of_consumed_buffered_amount_ += a; 153 sum_of_consumed_buffered_amount_ += a;
124 } 154 }
125 155
126 void Connect() { 156 void Connect() {
127 { 157 {
128 InSequence s; 158 InSequence s;
129 EXPECT_CALL(*Handle(), Initialize(_)); 159 EXPECT_CALL(*Handle(), Initialize(_));
130 EXPECT_CALL(*Handle(), Connect(KURL(KURL(), "ws://localhost/"), _, _, _, 160 EXPECT_CALL(*Handle(), Connect(KURL(KURL(), "ws://localhost/"), _, _, _,
131 _, HandleClient())); 161 _, HandleClient()));
132 EXPECT_CALL(*Handle(), FlowControl(65536)); 162 EXPECT_CALL(*Handle(), FlowControl(65536));
133 EXPECT_CALL(*ChannelClient(), DidConnect(String("a"), String("b"))); 163 EXPECT_CALL(*ChannelClient(), DidConnect(String("a"), String("b")));
134 } 164 }
135 EXPECT_TRUE(Channel()->Connect(KURL(KURL(), "ws://localhost/"), "x")); 165 EXPECT_TRUE(Channel()->Connect(KURL(KURL(), "ws://localhost/"), "x"));
136 HandleClient()->DidConnect(Handle(), String("a"), String("b")); 166 HandleClient()->DidConnect(Handle(), String("a"), String("b"));
137 ::testing::Mock::VerifyAndClearExpectations(this); 167 ::testing::Mock::VerifyAndClearExpectations(this);
138 } 168 }
139 169
140 std::unique_ptr<DummyPageHolder> page_holder_; 170 std::unique_ptr<DummyPageHolder> page_holder_;
141 Persistent<MockWebSocketChannelClient> channel_client_; 171 Persistent<MockWebSocketChannelClient> channel_client_;
142 MockWebSocketHandle* handle_; 172 MockWebSocketHandle* handle_;
173 // |handshake_throttle_| is owned by |channel_| once SetUp() has been called.
174 MockWebSocketHandshakeThrottle* handshake_throttle_;
143 Persistent<DocumentWebSocketChannel> channel_; 175 Persistent<DocumentWebSocketChannel> channel_;
144 unsigned long sum_of_consumed_buffered_amount_; 176 unsigned long sum_of_consumed_buffered_amount_;
145 }; 177 };
146 178
147 MATCHER_P2(MemEq, 179 MATCHER_P2(MemEq,
148 p, 180 p,
149 len, 181 len,
150 std::string("pointing to memory") + (negation ? " not" : "") + 182 std::string("pointing to memory") + (negation ? " not" : "") +
151 " equal to \"" + 183 " equal to \"" +
152 std::string(p, len) + 184 std::string(p, len) +
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 EXPECT_CALL( 800 EXPECT_CALL(
769 *ChannelClient(), 801 *ChannelClient(),
770 DidClose(WebSocketChannelClient::kClosingHandshakeIncomplete, 802 DidClose(WebSocketChannelClient::kClosingHandshakeIncomplete,
771 WebSocketChannel::kCloseEventCodeAbnormalClosure, String())); 803 WebSocketChannel::kCloseEventCodeAbnormalClosure, String()));
772 } 804 }
773 805
774 Channel()->Fail("fail message from WebSocket", kErrorMessageLevel, 806 Channel()->Fail("fail message from WebSocket", kErrorMessageLevel,
775 SourceLocation::Create(String(), 0, 0, nullptr)); 807 SourceLocation::Create(String(), 0, 0, nullptr));
776 } 808 }
777 809
810 class DocumentWebSocketChannelHandshakeThrottleTest
811 : public DocumentWebSocketChannelTest {
812 public:
813 DocumentWebSocketChannelHandshakeThrottleTest() {
814 handshake_throttle_ = MockWebSocketHandshakeThrottle::Create();
815 }
816
817 // Expectations for the normal result of calling Channel()->Connect() with a
818 // non-null throttle.
819 void NormalHandshakeExpectations() {
820 EXPECT_CALL(*Handle(), Initialize(_));
821 EXPECT_CALL(*Handle(), Connect(_, _, _, _, _, _));
822 EXPECT_CALL(*Handle(), FlowControl(_));
823 EXPECT_CALL(*handshake_throttle_, ThrottleHandshake(_, _, _));
824 }
825
826 static KURL url() { return KURL(KURL(), "ws://localhost/"); }
827 };
828
829 TEST_F(DocumentWebSocketChannelHandshakeThrottleTest, ThrottleArguments) {
830 EXPECT_CALL(*Handle(), Initialize(_));
831 EXPECT_CALL(*Handle(), Connect(_, _, _, _, _, _));
832 EXPECT_CALL(*Handle(), FlowControl(_));
833 EXPECT_CALL(*handshake_throttle_,
834 ThrottleHandshake(WebURL(url()), _, WebCallbacks()));
835 EXPECT_CALL(*handshake_throttle_, Destructor());
836 Channel()->Connect(url(), "");
837 }
838
839 TEST_F(DocumentWebSocketChannelHandshakeThrottleTest, ThrottleSucceedsFirst) {
840 Checkpoint checkpoint;
841 NormalHandshakeExpectations();
842 {
843 InSequence s;
844 EXPECT_CALL(checkpoint, Call(1));
845 EXPECT_CALL(*handshake_throttle_, Destructor());
846 EXPECT_CALL(checkpoint, Call(2));
847 EXPECT_CALL(*ChannelClient(), DidConnect(String("a"), String("b")));
848 }
849 Channel()->Connect(url(), "");
850 checkpoint.Call(1);
851 WebCallbacks()->OnSuccess();
852 checkpoint.Call(2);
853 HandleClient()->DidConnect(Handle(), String("a"), String("b"));
854 }
855
856 TEST_F(DocumentWebSocketChannelHandshakeThrottleTest, HandshakeSucceedsFirst) {
857 Checkpoint checkpoint;
858 NormalHandshakeExpectations();
859 {
860 InSequence s;
861 EXPECT_CALL(checkpoint, Call(1));
862 EXPECT_CALL(checkpoint, Call(2));
863 EXPECT_CALL(*handshake_throttle_, Destructor());
864 EXPECT_CALL(*ChannelClient(), DidConnect(String("a"), String("b")));
865 }
866 Channel()->Connect(url(), "");
867 checkpoint.Call(1);
868 HandleClient()->DidConnect(Handle(), String("a"), String("b"));
869 checkpoint.Call(2);
870 WebCallbacks()->OnSuccess();
871 }
872
873 // This happens if JS code calls close() during the handshake.
874 TEST_F(DocumentWebSocketChannelHandshakeThrottleTest, FailDuringThrottle) {
875 Checkpoint checkpoint;
876 NormalHandshakeExpectations();
877 {
878 InSequence s;
879 EXPECT_CALL(*handshake_throttle_, Destructor());
880 EXPECT_CALL(*ChannelClient(), DidError());
881 EXPECT_CALL(*ChannelClient(), DidClose(_, _, _));
882 EXPECT_CALL(checkpoint, Call(1));
883 }
884 Channel()->Connect(url(), "");
885 Channel()->Fail("close during handshake", kWarningMessageLevel,
886 SourceLocation::Create(String(), 0, 0, nullptr));
887 checkpoint.Call(1);
888 }
889
890 // It makes no difference to the behaviour if the WebSocketHandle has actually
891 // connected.
892 TEST_F(DocumentWebSocketChannelHandshakeThrottleTest,
893 FailDuringThrottleAfterConnect) {
894 Checkpoint checkpoint;
895 NormalHandshakeExpectations();
896 {
897 InSequence s;
898 EXPECT_CALL(*handshake_throttle_, Destructor());
899 EXPECT_CALL(*ChannelClient(), DidError());
900 EXPECT_CALL(*ChannelClient(), DidClose(_, _, _));
901 EXPECT_CALL(checkpoint, Call(1));
902 }
903 Channel()->Connect(url(), "");
904 HandleClient()->DidConnect(Handle(), String("a"), String("b"));
905 Channel()->Fail("close during handshake", kWarningMessageLevel,
906 SourceLocation::Create(String(), 0, 0, nullptr));
907 checkpoint.Call(1);
908 }
909
910 // This happens if the JS context is destroyed during the handshake.
911 TEST_F(DocumentWebSocketChannelHandshakeThrottleTest, CloseDuringThrottle) {
912 Checkpoint checkpoint;
913 NormalHandshakeExpectations();
914 {
915 InSequence s;
916 EXPECT_CALL(*handshake_throttle_, Destructor());
917 EXPECT_CALL(*Handle(), Close(_, _));
918 EXPECT_CALL(checkpoint, Call(1));
919 }
920 Channel()->Connect(url(), "");
921 Channel()->Close(DocumentWebSocketChannel::kCloseEventCodeGoingAway, "");
922 checkpoint.Call(1);
923 }
924
925 TEST_F(DocumentWebSocketChannelHandshakeThrottleTest,
926 CloseDuringThrottleAfterConnect) {
927 Checkpoint checkpoint;
928 NormalHandshakeExpectations();
929 {
930 InSequence s;
931 EXPECT_CALL(*handshake_throttle_, Destructor());
932 EXPECT_CALL(*Handle(), Close(_, _));
933 EXPECT_CALL(checkpoint, Call(1));
934 }
935 Channel()->Connect(url(), "");
936 HandleClient()->DidConnect(Handle(), String("a"), String("b"));
937 Channel()->Close(DocumentWebSocketChannel::kCloseEventCodeGoingAway, "");
938 checkpoint.Call(1);
939 }
940
941 TEST_F(DocumentWebSocketChannelHandshakeThrottleTest,
942 DisconnectDuringThrottle) {
943 Checkpoint checkpoint;
944 NormalHandshakeExpectations();
945 {
946 InSequence s;
947 EXPECT_CALL(*handshake_throttle_, Destructor());
948 EXPECT_CALL(checkpoint, Call(1));
949 }
950 Channel()->Connect(url(), "");
951 Channel()->Disconnect();
952 checkpoint.Call(1);
953 }
954
955 TEST_F(DocumentWebSocketChannelHandshakeThrottleTest,
956 DisconnectDuringThrottleAfterConnect) {
957 Checkpoint checkpoint;
958 NormalHandshakeExpectations();
959 {
960 InSequence s;
961 EXPECT_CALL(*handshake_throttle_, Destructor());
962 EXPECT_CALL(checkpoint, Call(1));
963 }
964 Channel()->Connect(url(), "");
965 HandleClient()->DidConnect(Handle(), String("a"), String("b"));
966 Channel()->Disconnect();
967 checkpoint.Call(1);
968 }
969
970 TEST_F(DocumentWebSocketChannelHandshakeThrottleTest,
971 ThrottleReportsErrorBeforeConnect) {
972 NormalHandshakeExpectations();
973 {
974 InSequence s;
975 EXPECT_CALL(*handshake_throttle_, Destructor());
976 EXPECT_CALL(*ChannelClient(), DidError());
977 EXPECT_CALL(*ChannelClient(), DidClose(_, _, _));
978 }
979 Channel()->Connect(url(), "");
980 WebCallbacks()->OnError("Connection blocked by throttle");
981 }
982
983 TEST_F(DocumentWebSocketChannelHandshakeThrottleTest,
984 ThrottleReportsErrorAfterConnect) {
985 NormalHandshakeExpectations();
986 {
987 InSequence s;
988 EXPECT_CALL(*handshake_throttle_, Destructor());
989 EXPECT_CALL(*ChannelClient(), DidError());
990 EXPECT_CALL(*ChannelClient(), DidClose(_, _, _));
991 }
992 Channel()->Connect(url(), "");
993 HandleClient()->DidConnect(Handle(), String("a"), String("b"));
994 WebCallbacks()->OnError("Connection blocked by throttle");
995 }
996
997 TEST_F(DocumentWebSocketChannelHandshakeThrottleTest,
998 ConnectFailBeforeThrottle) {
999 NormalHandshakeExpectations();
1000 {
1001 InSequence s;
1002 EXPECT_CALL(*handshake_throttle_, Destructor());
1003 EXPECT_CALL(*ChannelClient(), DidError());
1004 EXPECT_CALL(*ChannelClient(), DidClose(_, _, _));
1005 }
1006 Channel()->Connect(url(), "");
1007 HandleClient()->DidFail(Handle(), "connect failed");
1008 }
1009
1010 // TODO(ricea): Can this actually happen?
1011 TEST_F(DocumentWebSocketChannelHandshakeThrottleTest,
1012 ConnectCloseBeforeThrottle) {
1013 NormalHandshakeExpectations();
1014 {
1015 InSequence s;
1016 EXPECT_CALL(*handshake_throttle_, Destructor());
1017 EXPECT_CALL(*ChannelClient(), DidClose(_, _, _));
1018 }
1019 Channel()->Connect(url(), "");
1020 HandleClient()->DidClose(Handle(), false,
1021 WebSocketChannel::kCloseEventCodeProtocolError,
1022 "connect error");
1023 }
1024
778 } // namespace 1025 } // namespace
779 1026
780 } // namespace blink 1027 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698