| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/url_request/url_request_unittest.h" |
| 13 #include "net/websockets/websocket_job.h" | 14 #include "net/websockets/websocket_job.h" |
| 14 #include "net/websockets/websocket_throttle.h" | 15 #include "net/websockets/websocket_throttle.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 16 #include "testing/platform_test.h" | 17 #include "testing/platform_test.h" |
| 17 | 18 |
| 18 class DummySocketStreamDelegate : public net::SocketStream::Delegate { | 19 class DummySocketStreamDelegate : public net::SocketStream::Delegate { |
| 19 public: | 20 public: |
| 20 DummySocketStreamDelegate() {} | 21 DummySocketStreamDelegate() {} |
| 21 virtual ~DummySocketStreamDelegate() {} | 22 virtual ~DummySocketStreamDelegate() {} |
| 22 virtual void OnConnected( | 23 virtual void OnConnected( |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 for (struct addrinfo* a = head; a != NULL; a = next) { | 58 for (struct addrinfo* a = head; a != NULL; a = next) { |
| 58 next = a->ai_next; | 59 next = a->ai_next; |
| 59 delete [] a->ai_addr; | 60 delete [] a->ai_addr; |
| 60 delete a; | 61 delete a; |
| 61 } | 62 } |
| 62 } | 63 } |
| 63 | 64 |
| 64 static void MockSocketStreamConnect( | 65 static void MockSocketStreamConnect( |
| 65 SocketStream* socket, struct addrinfo* head) { | 66 SocketStream* socket, struct addrinfo* head) { |
| 66 socket->CopyAddrInfo(head); | 67 socket->CopyAddrInfo(head); |
| 68 // Initialize |proxy_info_|. |
| 69 socket->proxy_info_.UseDirect(); |
| 67 // In SocketStream::Connect(), it adds reference to socket, which is | 70 // In SocketStream::Connect(), it adds reference to socket, which is |
| 68 // balanced with SocketStream::Finish() that is finally called from | 71 // balanced with SocketStream::Finish() that is finally called from |
| 69 // SocketStream::Close() or SocketStream::DetachDelegate(), when | 72 // SocketStream::Close() or SocketStream::DetachDelegate(), when |
| 70 // next_state_ is not STATE_NONE. | 73 // next_state_ is not STATE_NONE. |
| 71 // If next_state_ is STATE_NONE, SocketStream::Close() or | 74 // If next_state_ is STATE_NONE, SocketStream::Close() or |
| 72 // SocketStream::DetachDelegate() won't call SocketStream::Finish(), | 75 // SocketStream::DetachDelegate() won't call SocketStream::Finish(), |
| 73 // so Release() won't be called. Thus, we don't need socket->AddRef() | 76 // so Release() won't be called. Thus, we don't need socket->AddRef() |
| 74 // here. | 77 // here. |
| 75 DCHECK_EQ(socket->next_state_, SocketStream::STATE_NONE); | 78 DCHECK_EQ(socket->next_state_, SocketStream::STATE_NONE); |
| 76 } | 79 } |
| 77 }; | 80 }; |
| 78 | 81 |
| 79 TEST_F(WebSocketThrottleTest, Throttle) { | 82 TEST_F(WebSocketThrottleTest, Throttle) { |
| 83 scoped_refptr<URLRequestContext> context(new TestURLRequestContext); |
| 80 DummySocketStreamDelegate delegate; | 84 DummySocketStreamDelegate delegate; |
| 81 | 85 |
| 82 // For host1: 1.2.3.4, 1.2.3.5, 1.2.3.6 | 86 // For host1: 1.2.3.4, 1.2.3.5, 1.2.3.6 |
| 83 struct addrinfo* addr = AddAddr(1, 2, 3, 4, NULL); | 87 struct addrinfo* addr = AddAddr(1, 2, 3, 4, NULL); |
| 84 addr = AddAddr(1, 2, 3, 5, addr); | 88 addr = AddAddr(1, 2, 3, 5, addr); |
| 85 addr = AddAddr(1, 2, 3, 6, addr); | 89 addr = AddAddr(1, 2, 3, 6, addr); |
| 86 scoped_refptr<WebSocketJob> w1(new WebSocketJob(&delegate)); | 90 scoped_refptr<WebSocketJob> w1(new WebSocketJob(&delegate)); |
| 87 scoped_refptr<SocketStream> s1( | 91 scoped_refptr<SocketStream> s1( |
| 88 new SocketStream(GURL("ws://host1/"), w1.get())); | 92 new SocketStream(GURL("ws://host1/"), w1.get())); |
| 93 s1->set_context(context.get()); |
| 89 w1->InitSocketStream(s1.get()); | 94 w1->InitSocketStream(s1.get()); |
| 90 WebSocketThrottleTest::MockSocketStreamConnect(s1, addr); | 95 WebSocketThrottleTest::MockSocketStreamConnect(s1, addr); |
| 91 DeleteAddrInfo(addr); | 96 DeleteAddrInfo(addr); |
| 92 | 97 |
| 93 DVLOG(1) << "socket1"; | 98 DVLOG(1) << "socket1"; |
| 94 TestCompletionCallback callback_s1; | 99 TestCompletionCallback callback_s1; |
| 95 // Trying to open connection to host1 will start without wait. | 100 // Trying to open connection to host1 will start without wait. |
| 96 EXPECT_EQ(OK, w1->OnStartOpenConnection(s1, &callback_s1)); | 101 EXPECT_EQ(OK, w1->OnStartOpenConnection(s1, &callback_s1)); |
| 97 | 102 |
| 98 // Now connecting to host1, so waiting queue looks like | 103 // Now connecting to host1, so waiting queue looks like |
| 99 // Address | head -> tail | 104 // Address | head -> tail |
| 100 // 1.2.3.4 | w1 | 105 // 1.2.3.4 | w1 |
| 101 // 1.2.3.5 | w1 | 106 // 1.2.3.5 | w1 |
| 102 // 1.2.3.6 | w1 | 107 // 1.2.3.6 | w1 |
| 103 | 108 |
| 104 // For host2: 1.2.3.4 | 109 // For host2: 1.2.3.4 |
| 105 addr = AddAddr(1, 2, 3, 4, NULL); | 110 addr = AddAddr(1, 2, 3, 4, NULL); |
| 106 scoped_refptr<WebSocketJob> w2(new WebSocketJob(&delegate)); | 111 scoped_refptr<WebSocketJob> w2(new WebSocketJob(&delegate)); |
| 107 scoped_refptr<SocketStream> s2( | 112 scoped_refptr<SocketStream> s2( |
| 108 new SocketStream(GURL("ws://host2/"), w2.get())); | 113 new SocketStream(GURL("ws://host2/"), w2.get())); |
| 114 s2->set_context(context.get()); |
| 109 w2->InitSocketStream(s2.get()); | 115 w2->InitSocketStream(s2.get()); |
| 110 WebSocketThrottleTest::MockSocketStreamConnect(s2, addr); | 116 WebSocketThrottleTest::MockSocketStreamConnect(s2, addr); |
| 111 DeleteAddrInfo(addr); | 117 DeleteAddrInfo(addr); |
| 112 | 118 |
| 113 DVLOG(1) << "socket2"; | 119 DVLOG(1) << "socket2"; |
| 114 TestCompletionCallback callback_s2; | 120 TestCompletionCallback callback_s2; |
| 115 // Trying to open connection to host2 will wait for w1. | 121 // Trying to open connection to host2 will wait for w1. |
| 116 EXPECT_EQ(ERR_IO_PENDING, w2->OnStartOpenConnection(s2, &callback_s2)); | 122 EXPECT_EQ(ERR_IO_PENDING, w2->OnStartOpenConnection(s2, &callback_s2)); |
| 117 // Now waiting queue looks like | 123 // Now waiting queue looks like |
| 118 // Address | head -> tail | 124 // Address | head -> tail |
| 119 // 1.2.3.4 | w1 w2 | 125 // 1.2.3.4 | w1 w2 |
| 120 // 1.2.3.5 | w1 | 126 // 1.2.3.5 | w1 |
| 121 // 1.2.3.6 | w1 | 127 // 1.2.3.6 | w1 |
| 122 | 128 |
| 123 // For host3: 1.2.3.5 | 129 // For host3: 1.2.3.5 |
| 124 addr = AddAddr(1, 2, 3, 5, NULL); | 130 addr = AddAddr(1, 2, 3, 5, NULL); |
| 125 scoped_refptr<WebSocketJob> w3(new WebSocketJob(&delegate)); | 131 scoped_refptr<WebSocketJob> w3(new WebSocketJob(&delegate)); |
| 126 scoped_refptr<SocketStream> s3( | 132 scoped_refptr<SocketStream> s3( |
| 127 new SocketStream(GURL("ws://host3/"), w3.get())); | 133 new SocketStream(GURL("ws://host3/"), w3.get())); |
| 134 s3->set_context(context.get()); |
| 128 w3->InitSocketStream(s3.get()); | 135 w3->InitSocketStream(s3.get()); |
| 129 WebSocketThrottleTest::MockSocketStreamConnect(s3, addr); | 136 WebSocketThrottleTest::MockSocketStreamConnect(s3, addr); |
| 130 DeleteAddrInfo(addr); | 137 DeleteAddrInfo(addr); |
| 131 | 138 |
| 132 DVLOG(1) << "socket3"; | 139 DVLOG(1) << "socket3"; |
| 133 TestCompletionCallback callback_s3; | 140 TestCompletionCallback callback_s3; |
| 134 // Trying to open connection to host3 will wait for w1. | 141 // Trying to open connection to host3 will wait for w1. |
| 135 EXPECT_EQ(ERR_IO_PENDING, w3->OnStartOpenConnection(s3, &callback_s3)); | 142 EXPECT_EQ(ERR_IO_PENDING, w3->OnStartOpenConnection(s3, &callback_s3)); |
| 136 // Address | head -> tail | 143 // Address | head -> tail |
| 137 // 1.2.3.4 | w1 w2 | 144 // 1.2.3.4 | w1 w2 |
| 138 // 1.2.3.5 | w1 w3 | 145 // 1.2.3.5 | w1 w3 |
| 139 // 1.2.3.6 | w1 | 146 // 1.2.3.6 | w1 |
| 140 | 147 |
| 141 // For host4: 1.2.3.4, 1.2.3.6 | 148 // For host4: 1.2.3.4, 1.2.3.6 |
| 142 addr = AddAddr(1, 2, 3, 4, NULL); | 149 addr = AddAddr(1, 2, 3, 4, NULL); |
| 143 addr = AddAddr(1, 2, 3, 6, addr); | 150 addr = AddAddr(1, 2, 3, 6, addr); |
| 144 scoped_refptr<WebSocketJob> w4(new WebSocketJob(&delegate)); | 151 scoped_refptr<WebSocketJob> w4(new WebSocketJob(&delegate)); |
| 145 scoped_refptr<SocketStream> s4( | 152 scoped_refptr<SocketStream> s4( |
| 146 new SocketStream(GURL("ws://host4/"), w4.get())); | 153 new SocketStream(GURL("ws://host4/"), w4.get())); |
| 154 s4->set_context(context.get()); |
| 147 w4->InitSocketStream(s4.get()); | 155 w4->InitSocketStream(s4.get()); |
| 148 WebSocketThrottleTest::MockSocketStreamConnect(s4, addr); | 156 WebSocketThrottleTest::MockSocketStreamConnect(s4, addr); |
| 149 DeleteAddrInfo(addr); | 157 DeleteAddrInfo(addr); |
| 150 | 158 |
| 151 DVLOG(1) << "socket4"; | 159 DVLOG(1) << "socket4"; |
| 152 TestCompletionCallback callback_s4; | 160 TestCompletionCallback callback_s4; |
| 153 // Trying to open connection to host4 will wait for w1, w2. | 161 // Trying to open connection to host4 will wait for w1, w2. |
| 154 EXPECT_EQ(ERR_IO_PENDING, w4->OnStartOpenConnection(s4, &callback_s4)); | 162 EXPECT_EQ(ERR_IO_PENDING, w4->OnStartOpenConnection(s4, &callback_s4)); |
| 155 // Address | head -> tail | 163 // Address | head -> tail |
| 156 // 1.2.3.4 | w1 w2 w4 | 164 // 1.2.3.4 | w1 w2 w4 |
| 157 // 1.2.3.5 | w1 w3 | 165 // 1.2.3.5 | w1 w3 |
| 158 // 1.2.3.6 | w1 w4 | 166 // 1.2.3.6 | w1 w4 |
| 159 | 167 |
| 160 // For host5: 1.2.3.6 | 168 // For host5: 1.2.3.6 |
| 161 addr = AddAddr(1, 2, 3, 6, NULL); | 169 addr = AddAddr(1, 2, 3, 6, NULL); |
| 162 scoped_refptr<WebSocketJob> w5(new WebSocketJob(&delegate)); | 170 scoped_refptr<WebSocketJob> w5(new WebSocketJob(&delegate)); |
| 163 scoped_refptr<SocketStream> s5( | 171 scoped_refptr<SocketStream> s5( |
| 164 new SocketStream(GURL("ws://host5/"), w5.get())); | 172 new SocketStream(GURL("ws://host5/"), w5.get())); |
| 173 s5->set_context(context.get()); |
| 165 w5->InitSocketStream(s5.get()); | 174 w5->InitSocketStream(s5.get()); |
| 166 WebSocketThrottleTest::MockSocketStreamConnect(s5, addr); | 175 WebSocketThrottleTest::MockSocketStreamConnect(s5, addr); |
| 167 DeleteAddrInfo(addr); | 176 DeleteAddrInfo(addr); |
| 168 | 177 |
| 169 DVLOG(1) << "socket5"; | 178 DVLOG(1) << "socket5"; |
| 170 TestCompletionCallback callback_s5; | 179 TestCompletionCallback callback_s5; |
| 171 // Trying to open connection to host5 will wait for w1, w4 | 180 // Trying to open connection to host5 will wait for w1, w4 |
| 172 EXPECT_EQ(ERR_IO_PENDING, w5->OnStartOpenConnection(s5, &callback_s5)); | 181 EXPECT_EQ(ERR_IO_PENDING, w5->OnStartOpenConnection(s5, &callback_s5)); |
| 173 // Address | head -> tail | 182 // Address | head -> tail |
| 174 // 1.2.3.4 | w1 w2 w4 | 183 // 1.2.3.4 | w1 w2 w4 |
| 175 // 1.2.3.5 | w1 w3 | 184 // 1.2.3.5 | w1 w3 |
| 176 // 1.2.3.6 | w1 w4 w5 | 185 // 1.2.3.6 | w1 w4 w5 |
| 177 | 186 |
| 178 // For host6: 1.2.3.6 | 187 // For host6: 1.2.3.6 |
| 179 addr = AddAddr(1, 2, 3, 6, NULL); | 188 addr = AddAddr(1, 2, 3, 6, NULL); |
| 180 scoped_refptr<WebSocketJob> w6(new WebSocketJob(&delegate)); | 189 scoped_refptr<WebSocketJob> w6(new WebSocketJob(&delegate)); |
| 181 scoped_refptr<SocketStream> s6( | 190 scoped_refptr<SocketStream> s6( |
| 182 new SocketStream(GURL("ws://host6/"), w6.get())); | 191 new SocketStream(GURL("ws://host6/"), w6.get())); |
| 192 s6->set_context(context.get()); |
| 183 w6->InitSocketStream(s6.get()); | 193 w6->InitSocketStream(s6.get()); |
| 184 WebSocketThrottleTest::MockSocketStreamConnect(s6, addr); | 194 WebSocketThrottleTest::MockSocketStreamConnect(s6, addr); |
| 185 DeleteAddrInfo(addr); | 195 DeleteAddrInfo(addr); |
| 186 | 196 |
| 187 DVLOG(1) << "socket6"; | 197 DVLOG(1) << "socket6"; |
| 188 TestCompletionCallback callback_s6; | 198 TestCompletionCallback callback_s6; |
| 189 // Trying to open connection to host6 will wait for w1, w4, w5 | 199 // Trying to open connection to host6 will wait for w1, w4, w5 |
| 190 EXPECT_EQ(ERR_IO_PENDING, w6->OnStartOpenConnection(s6, &callback_s6)); | 200 EXPECT_EQ(ERR_IO_PENDING, w6->OnStartOpenConnection(s6, &callback_s6)); |
| 191 // Address | head -> tail | 201 // Address | head -> tail |
| 192 // 1.2.3.4 | w1 w2 w4 | 202 // 1.2.3.4 | w1 w2 w4 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 w3->OnClose(s3.get()); | 284 w3->OnClose(s3.get()); |
| 275 MessageLoopForIO::current()->RunAllPending(); | 285 MessageLoopForIO::current()->RunAllPending(); |
| 276 s3->DetachDelegate(); | 286 s3->DetachDelegate(); |
| 277 w4->OnClose(s4.get()); | 287 w4->OnClose(s4.get()); |
| 278 s4->DetachDelegate(); | 288 s4->DetachDelegate(); |
| 279 DVLOG(1) << "Done"; | 289 DVLOG(1) << "Done"; |
| 280 MessageLoopForIO::current()->RunAllPending(); | 290 MessageLoopForIO::current()->RunAllPending(); |
| 281 } | 291 } |
| 282 | 292 |
| 283 TEST_F(WebSocketThrottleTest, NoThrottleForDuplicateAddress) { | 293 TEST_F(WebSocketThrottleTest, NoThrottleForDuplicateAddress) { |
| 294 scoped_refptr<URLRequestContext> context(new TestURLRequestContext); |
| 284 DummySocketStreamDelegate delegate; | 295 DummySocketStreamDelegate delegate; |
| 285 | 296 |
| 286 // For localhost: 127.0.0.1, 127.0.0.1 | 297 // For localhost: 127.0.0.1, 127.0.0.1 |
| 287 struct addrinfo* addr = AddAddr(127, 0, 0, 1, NULL); | 298 struct addrinfo* addr = AddAddr(127, 0, 0, 1, NULL); |
| 288 addr = AddAddr(127, 0, 0, 1, addr); | 299 addr = AddAddr(127, 0, 0, 1, addr); |
| 289 scoped_refptr<WebSocketJob> w1(new WebSocketJob(&delegate)); | 300 scoped_refptr<WebSocketJob> w1(new WebSocketJob(&delegate)); |
| 290 scoped_refptr<SocketStream> s1( | 301 scoped_refptr<SocketStream> s1( |
| 291 new SocketStream(GURL("ws://localhost/"), w1.get())); | 302 new SocketStream(GURL("ws://localhost/"), w1.get())); |
| 303 s1->set_context(context.get()); |
| 292 w1->InitSocketStream(s1.get()); | 304 w1->InitSocketStream(s1.get()); |
| 293 WebSocketThrottleTest::MockSocketStreamConnect(s1, addr); | 305 WebSocketThrottleTest::MockSocketStreamConnect(s1, addr); |
| 294 DeleteAddrInfo(addr); | 306 DeleteAddrInfo(addr); |
| 295 | 307 |
| 296 DVLOG(1) << "socket1"; | 308 DVLOG(1) << "socket1"; |
| 297 TestCompletionCallback callback_s1; | 309 TestCompletionCallback callback_s1; |
| 298 // Trying to open connection to localhost will start without wait. | 310 // Trying to open connection to localhost will start without wait. |
| 299 EXPECT_EQ(OK, w1->OnStartOpenConnection(s1, &callback_s1)); | 311 EXPECT_EQ(OK, w1->OnStartOpenConnection(s1, &callback_s1)); |
| 300 | 312 |
| 301 DVLOG(1) << "socket1 close"; | 313 DVLOG(1) << "socket1 close"; |
| 302 w1->OnClose(s1.get()); | 314 w1->OnClose(s1.get()); |
| 303 s1->DetachDelegate(); | 315 s1->DetachDelegate(); |
| 304 DVLOG(1) << "Done"; | 316 DVLOG(1) << "Done"; |
| 305 MessageLoopForIO::current()->RunAllPending(); | 317 MessageLoopForIO::current()->RunAllPending(); |
| 306 } | 318 } |
| 307 | 319 |
| 308 } | 320 } |
| OLD | NEW |