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

Side by Side Diff: net/websockets/websocket_throttle_unittest.cc

Issue 669157: Refactor WebSocket throttling feature. (Closed)
Patch Set: Fix for tyoshino's comment Created 10 years, 9 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
« no previous file with comments | « net/websockets/websocket_throttle.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 <string> 5 #include <string>
6 6
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "googleurl/src/gurl.h" 8 #include "googleurl/src/gurl.h"
9 #include "net/base/address_list.h" 9 #include "net/base/address_list.h"
10 #include "net/base/sys_addrinfo.h" 10 #include "net/base/sys_addrinfo.h"
11 #include "net/base/test_completion_callback.h" 11 #include "net/base/test_completion_callback.h"
12 #include "net/socket_stream/socket_stream.h" 12 #include "net/socket_stream/socket_stream.h"
13 #include "net/websockets/websocket_job.h"
13 #include "net/websockets/websocket_throttle.h" 14 #include "net/websockets/websocket_throttle.h"
14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
15 #include "testing/platform_test.h" 16 #include "testing/platform_test.h"
16 17
17 class DummySocketStreamDelegate : public net::SocketStream::Delegate { 18 class DummySocketStreamDelegate : public net::SocketStream::Delegate {
18 public: 19 public:
19 DummySocketStreamDelegate() {} 20 DummySocketStreamDelegate() {}
20 virtual ~DummySocketStreamDelegate() {} 21 virtual ~DummySocketStreamDelegate() {}
21 virtual void OnConnected( 22 virtual void OnConnected(
22 net::SocketStream* socket, int max_pending_send_allowed) {} 23 net::SocketStream* socket, int max_pending_send_allowed) {}
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 delete a; 60 delete a;
60 } 61 }
61 } 62 }
62 63
63 static void SetAddressList(SocketStream* socket, struct addrinfo* head) { 64 static void SetAddressList(SocketStream* socket, struct addrinfo* head) {
64 socket->CopyAddrInfo(head); 65 socket->CopyAddrInfo(head);
65 } 66 }
66 }; 67 };
67 68
68 TEST_F(WebSocketThrottleTest, Throttle) { 69 TEST_F(WebSocketThrottleTest, Throttle) {
69 WebSocketThrottle::Init();
70 DummySocketStreamDelegate delegate; 70 DummySocketStreamDelegate delegate;
71 71
72 WebSocketThrottle* throttle = Singleton<WebSocketThrottle>::get();
73
74 EXPECT_EQ(throttle,
75 SocketStreamThrottle::GetSocketStreamThrottleForScheme("ws"));
76 EXPECT_EQ(throttle,
77 SocketStreamThrottle::GetSocketStreamThrottleForScheme("wss"));
78
79 // For host1: 1.2.3.4, 1.2.3.5, 1.2.3.6 72 // For host1: 1.2.3.4, 1.2.3.5, 1.2.3.6
80 struct addrinfo* addr = AddAddr(1, 2, 3, 4, NULL); 73 struct addrinfo* addr = AddAddr(1, 2, 3, 4, NULL);
81 addr = AddAddr(1, 2, 3, 5, addr); 74 addr = AddAddr(1, 2, 3, 5, addr);
82 addr = AddAddr(1, 2, 3, 6, addr); 75 addr = AddAddr(1, 2, 3, 6, addr);
76 scoped_refptr<WebSocketJob> w1 = new WebSocketJob(&delegate);
83 scoped_refptr<SocketStream> s1 = 77 scoped_refptr<SocketStream> s1 =
84 new SocketStream(GURL("ws://host1/"), &delegate); 78 new SocketStream(GURL("ws://host1/"), w1.get());
79 w1->InitSocketStream(s1.get());
85 WebSocketThrottleTest::SetAddressList(s1, addr); 80 WebSocketThrottleTest::SetAddressList(s1, addr);
86 DeleteAddrInfo(addr); 81 DeleteAddrInfo(addr);
87 82
83 DLOG(INFO) << "socket1";
88 TestCompletionCallback callback_s1; 84 TestCompletionCallback callback_s1;
89 EXPECT_EQ(OK, throttle->OnStartOpenConnection(s1, &callback_s1)); 85 // Trying to open connection to host1 will start without wait.
86 EXPECT_EQ(OK, w1->OnStartOpenConnection(s1, &callback_s1));
87
88 // Now connecting to host1, so waiting queue looks like
89 // Address | head -> tail
90 // 1.2.3.4 | w1
91 // 1.2.3.5 | w1
92 // 1.2.3.6 | w1
90 93
91 // For host2: 1.2.3.4 94 // For host2: 1.2.3.4
92 addr = AddAddr(1, 2, 3, 4, NULL); 95 addr = AddAddr(1, 2, 3, 4, NULL);
96 scoped_refptr<WebSocketJob> w2 = new WebSocketJob(&delegate);
93 scoped_refptr<SocketStream> s2 = 97 scoped_refptr<SocketStream> s2 =
94 new SocketStream(GURL("ws://host2/"), &delegate); 98 new SocketStream(GURL("ws://host2/"), w2.get());
99 w2->InitSocketStream(s2.get());
95 WebSocketThrottleTest::SetAddressList(s2, addr); 100 WebSocketThrottleTest::SetAddressList(s2, addr);
96 DeleteAddrInfo(addr); 101 DeleteAddrInfo(addr);
97 102
103 DLOG(INFO) << "socket2";
98 TestCompletionCallback callback_s2; 104 TestCompletionCallback callback_s2;
99 EXPECT_EQ(ERR_IO_PENDING, throttle->OnStartOpenConnection(s2, &callback_s2)); 105 // Trying to open connection to host2 will wait for w1.
106 EXPECT_EQ(ERR_IO_PENDING, w2->OnStartOpenConnection(s2, &callback_s2));
107 // Now waiting queue looks like
108 // Address | head -> tail
109 // 1.2.3.4 | w1 w2
110 // 1.2.3.5 | w1
111 // 1.2.3.6 | w1
100 112
101 // For host3: 1.2.3.5 113 // For host3: 1.2.3.5
102 addr = AddAddr(1, 2, 3, 5, NULL); 114 addr = AddAddr(1, 2, 3, 5, NULL);
115 scoped_refptr<WebSocketJob> w3 = new WebSocketJob(&delegate);
103 scoped_refptr<SocketStream> s3 = 116 scoped_refptr<SocketStream> s3 =
104 new SocketStream(GURL("ws://host3/"), &delegate); 117 new SocketStream(GURL("ws://host3/"), w3.get());
118 w3->InitSocketStream(s3.get());
105 WebSocketThrottleTest::SetAddressList(s3, addr); 119 WebSocketThrottleTest::SetAddressList(s3, addr);
106 DeleteAddrInfo(addr); 120 DeleteAddrInfo(addr);
107 121
122 DLOG(INFO) << "socket3";
108 TestCompletionCallback callback_s3; 123 TestCompletionCallback callback_s3;
109 EXPECT_EQ(ERR_IO_PENDING, throttle->OnStartOpenConnection(s3, &callback_s3)); 124 // Trying to open connection to host3 will wait for w1.
125 EXPECT_EQ(ERR_IO_PENDING, w3->OnStartOpenConnection(s3, &callback_s3));
126 // Address | head -> tail
127 // 1.2.3.4 | w1 w2
128 // 1.2.3.5 | w1 w3
129 // 1.2.3.6 | w1
110 130
111 // For host4: 1.2.3.4, 1.2.3.6 131 // For host4: 1.2.3.4, 1.2.3.6
112 addr = AddAddr(1, 2, 3, 4, NULL); 132 addr = AddAddr(1, 2, 3, 4, NULL);
113 addr = AddAddr(1, 2, 3, 6, addr); 133 addr = AddAddr(1, 2, 3, 6, addr);
134 scoped_refptr<WebSocketJob> w4 = new WebSocketJob(&delegate);
114 scoped_refptr<SocketStream> s4 = 135 scoped_refptr<SocketStream> s4 =
115 new SocketStream(GURL("ws://host4/"), &delegate); 136 new SocketStream(GURL("ws://host4/"), w4.get());
137 w4->InitSocketStream(s4.get());
116 WebSocketThrottleTest::SetAddressList(s4, addr); 138 WebSocketThrottleTest::SetAddressList(s4, addr);
117 DeleteAddrInfo(addr); 139 DeleteAddrInfo(addr);
118 140
141 DLOG(INFO) << "socket4";
119 TestCompletionCallback callback_s4; 142 TestCompletionCallback callback_s4;
120 EXPECT_EQ(ERR_IO_PENDING, throttle->OnStartOpenConnection(s4, &callback_s4)); 143 // Trying to open connection to host4 will wait for w1, w2.
121 144 EXPECT_EQ(ERR_IO_PENDING, w4->OnStartOpenConnection(s4, &callback_s4));
145 // Address | head -> tail
146 // 1.2.3.4 | w1 w2 w4
147 // 1.2.3.5 | w1 w3
148 // 1.2.3.6 | w1 w4
149
150 // For host5: 1.2.3.6
151 addr = AddAddr(1, 2, 3, 6, NULL);
152 scoped_refptr<WebSocketJob> w5 = new WebSocketJob(&delegate);
153 scoped_refptr<SocketStream> s5 =
154 new SocketStream(GURL("ws://host5/"), w5.get());
155 w5->InitSocketStream(s5.get());
156 WebSocketThrottleTest::SetAddressList(s5, addr);
157 DeleteAddrInfo(addr);
158
159 DLOG(INFO) << "socket5";
160 TestCompletionCallback callback_s5;
161 // Trying to open connection to host5 will wait for w1, w4
162 EXPECT_EQ(ERR_IO_PENDING, w5->OnStartOpenConnection(s5, &callback_s5));
163 // Address | head -> tail
164 // 1.2.3.4 | w1 w2 w4
165 // 1.2.3.5 | w1 w3
166 // 1.2.3.6 | w1 w4 w5
167
168 // For host6: 1.2.3.6
169 addr = AddAddr(1, 2, 3, 6, NULL);
170 scoped_refptr<WebSocketJob> w6 = new WebSocketJob(&delegate);
171 scoped_refptr<SocketStream> s6 =
172 new SocketStream(GURL("ws://host6/"), w6.get());
173 w6->InitSocketStream(s6.get());
174 WebSocketThrottleTest::SetAddressList(s6, addr);
175 DeleteAddrInfo(addr);
176
177 DLOG(INFO) << "socket6";
178 TestCompletionCallback callback_s6;
179 // Trying to open connection to host6 will wait for w1, w4, w5
180 EXPECT_EQ(ERR_IO_PENDING, w6->OnStartOpenConnection(s6, &callback_s6));
181 // Address | head -> tail
182 // 1.2.3.4 | w1 w2 w4
183 // 1.2.3.5 | w1 w3
184 // 1.2.3.6 | w1 w4 w5 w6
185
186 // Receive partial response on w1, still connecting.
187 DLOG(INFO) << "socket1 1";
122 static const char kHeader[] = "HTTP/1.1 101 Web Socket Protocol\r\n"; 188 static const char kHeader[] = "HTTP/1.1 101 Web Socket Protocol\r\n";
123 EXPECT_EQ(OK, 189 w1->OnReceivedData(s1.get(), kHeader, sizeof(kHeader) - 1);
124 throttle->OnRead(s1.get(), kHeader, sizeof(kHeader) - 1, NULL));
125 EXPECT_FALSE(callback_s2.have_result()); 190 EXPECT_FALSE(callback_s2.have_result());
126 EXPECT_FALSE(callback_s3.have_result()); 191 EXPECT_FALSE(callback_s3.have_result());
127 EXPECT_FALSE(callback_s4.have_result()); 192 EXPECT_FALSE(callback_s4.have_result());
128 193 EXPECT_FALSE(callback_s5.have_result());
194 EXPECT_FALSE(callback_s6.have_result());
195
196 // Receive rest of handshake response on w1.
197 DLOG(INFO) << "socket1 2";
129 static const char kHeader2[] = 198 static const char kHeader2[] =
130 "Upgrade: WebSocket\r\n" 199 "Upgrade: WebSocket\r\n"
131 "Connection: Upgrade\r\n" 200 "Connection: Upgrade\r\n"
132 "WebSocket-Origin: http://www.google.com\r\n" 201 "WebSocket-Origin: http://www.google.com\r\n"
133 "WebSocket-Location: ws://websocket.chromium.org\r\n" 202 "WebSocket-Location: ws://websocket.chromium.org\r\n"
134 "\r\n"; 203 "\r\n";
135 EXPECT_EQ(OK, 204 w1->OnReceivedData(s1.get(), kHeader2, sizeof(kHeader2) - 1);
136 throttle->OnRead(s1.get(), kHeader2, sizeof(kHeader2) - 1, NULL)); 205 MessageLoopForIO::current()->RunAllPending();
137 MessageLoopForIO::current()->RunAllPending(); 206 // Now, w1 is open.
207 EXPECT_EQ(WebSocketJob::OPEN, w1->state());
208 // So, w2 and w3 can start connecting. w4 needs to wait w2 (1.2.3.4)
138 EXPECT_TRUE(callback_s2.have_result()); 209 EXPECT_TRUE(callback_s2.have_result());
139 EXPECT_TRUE(callback_s3.have_result()); 210 EXPECT_TRUE(callback_s3.have_result());
140 EXPECT_FALSE(callback_s4.have_result()); 211 EXPECT_FALSE(callback_s4.have_result());
141 212 // Address | head -> tail
142 throttle->OnClose(s1.get()); 213 // 1.2.3.4 | w2 w4
214 // 1.2.3.5 | w3
215 // 1.2.3.6 | w4 w5 w6
216
217 // Closing s1 doesn't change waiting queue.
218 DLOG(INFO) << "socket1 close";
219 w1->OnClose(s1.get());
143 MessageLoopForIO::current()->RunAllPending(); 220 MessageLoopForIO::current()->RunAllPending();
144 EXPECT_FALSE(callback_s4.have_result()); 221 EXPECT_FALSE(callback_s4.have_result());
145 s1->DetachDelegate(); 222 s1->DetachDelegate();
146 223 // Address | head -> tail
147 throttle->OnClose(s2.get()); 224 // 1.2.3.4 | w2 w4
225 // 1.2.3.5 | w3
226 // 1.2.3.6 | w4 w5 w6
227
228 // w5 can close while waiting in queue.
229 DLOG(INFO) << "socket5 close";
230 // w5 close() closes SocketStream that change state to STATE_CLOSE, calls
231 // DoLoop(), so OnClose() callback will be called.
232 w5->OnClose(s5.get());
233 MessageLoopForIO::current()->RunAllPending();
234 EXPECT_FALSE(callback_s4.have_result());
235 // Address | head -> tail
236 // 1.2.3.4 | w2 w4
237 // 1.2.3.5 | w3
238 // 1.2.3.6 | w4 w6
239 s5->DetachDelegate();
240
241 // w6 close abnormally (e.g. renderer finishes) while waiting in queue.
242 DLOG(INFO) << "socket6 close abnormally";
243 w6->DetachDelegate();
244 MessageLoopForIO::current()->RunAllPending();
245 EXPECT_FALSE(callback_s4.have_result());
246 // Address | head -> tail
247 // 1.2.3.4 | w2 w4
248 // 1.2.3.5 | w3
249 // 1.2.3.6 | w4
250
251 // Closing s2 kicks w4 to start connecting.
252 DLOG(INFO) << "socket2 close";
253 w2->OnClose(s2.get());
148 MessageLoopForIO::current()->RunAllPending(); 254 MessageLoopForIO::current()->RunAllPending();
149 EXPECT_TRUE(callback_s4.have_result()); 255 EXPECT_TRUE(callback_s4.have_result());
256 // Address | head -> tail
257 // 1.2.3.4 | w4
258 // 1.2.3.5 | w3
259 // 1.2.3.6 | w4
150 s2->DetachDelegate(); 260 s2->DetachDelegate();
151 261
152 throttle->OnClose(s3.get()); 262 DLOG(INFO) << "socket3 close";
263 w3->OnClose(s3.get());
153 MessageLoopForIO::current()->RunAllPending(); 264 MessageLoopForIO::current()->RunAllPending();
154 s3->DetachDelegate(); 265 s3->DetachDelegate();
155 throttle->OnClose(s4.get()); 266 w4->OnClose(s4.get());
156 s4->DetachDelegate(); 267 s4->DetachDelegate();
268 DLOG(INFO) << "Done";
157 } 269 }
158 270
159 } 271 }
OLDNEW
« no previous file with comments | « net/websockets/websocket_throttle.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698