diff options
author | ukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-17 07:29:54 +0000 |
---|---|---|
committer | ukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-17 07:29:54 +0000 |
commit | b4384a798aef3f2e52c34d733a9af2db792c6c1d (patch) | |
tree | f0bdc9e8f054e23481ac619cb38238ed59584626 /net/websockets/websocket_throttle_unittest.cc | |
parent | ea477c25a06ac425257f1a94081aaca98929ab0f (diff) | |
download | chromium_src-b4384a798aef3f2e52c34d733a9af2db792c6c1d.zip chromium_src-b4384a798aef3f2e52c34d733a9af2db792c6c1d.tar.gz chromium_src-b4384a798aef3f2e52c34d733a9af2db792c6c1d.tar.bz2 |
Refactor WebSocket throttling feature.
Protocol specific handling should be done in SocketStreamJob subclasss,
so websocket throttling should be handled in WebSocketJob.
Review URL: http://codereview.chromium.org/669157
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41818 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/websockets/websocket_throttle_unittest.cc')
-rw-r--r-- | net/websockets/websocket_throttle_unittest.cc | 160 |
1 files changed, 136 insertions, 24 deletions
diff --git a/net/websockets/websocket_throttle_unittest.cc b/net/websockets/websocket_throttle_unittest.cc index 55276e9..d568292 100644 --- a/net/websockets/websocket_throttle_unittest.cc +++ b/net/websockets/websocket_throttle_unittest.cc @@ -10,6 +10,7 @@ #include "net/base/sys_addrinfo.h" #include "net/base/test_completion_callback.h" #include "net/socket_stream/socket_stream.h" +#include "net/websockets/websocket_job.h" #include "net/websockets/websocket_throttle.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -66,94 +67,205 @@ class WebSocketThrottleTest : public PlatformTest { }; TEST_F(WebSocketThrottleTest, Throttle) { - WebSocketThrottle::Init(); DummySocketStreamDelegate delegate; - WebSocketThrottle* throttle = Singleton<WebSocketThrottle>::get(); - - EXPECT_EQ(throttle, - SocketStreamThrottle::GetSocketStreamThrottleForScheme("ws")); - EXPECT_EQ(throttle, - SocketStreamThrottle::GetSocketStreamThrottleForScheme("wss")); - // For host1: 1.2.3.4, 1.2.3.5, 1.2.3.6 struct addrinfo* addr = AddAddr(1, 2, 3, 4, NULL); addr = AddAddr(1, 2, 3, 5, addr); addr = AddAddr(1, 2, 3, 6, addr); + scoped_refptr<WebSocketJob> w1 = new WebSocketJob(&delegate); scoped_refptr<SocketStream> s1 = - new SocketStream(GURL("ws://host1/"), &delegate); + new SocketStream(GURL("ws://host1/"), w1.get()); + w1->InitSocketStream(s1.get()); WebSocketThrottleTest::SetAddressList(s1, addr); DeleteAddrInfo(addr); + DLOG(INFO) << "socket1"; TestCompletionCallback callback_s1; - EXPECT_EQ(OK, throttle->OnStartOpenConnection(s1, &callback_s1)); + // Trying to open connection to host1 will start without wait. + EXPECT_EQ(OK, w1->OnStartOpenConnection(s1, &callback_s1)); + + // Now connecting to host1, so waiting queue looks like + // Address | head -> tail + // 1.2.3.4 | w1 + // 1.2.3.5 | w1 + // 1.2.3.6 | w1 // For host2: 1.2.3.4 addr = AddAddr(1, 2, 3, 4, NULL); + scoped_refptr<WebSocketJob> w2 = new WebSocketJob(&delegate); scoped_refptr<SocketStream> s2 = - new SocketStream(GURL("ws://host2/"), &delegate); + new SocketStream(GURL("ws://host2/"), w2.get()); + w2->InitSocketStream(s2.get()); WebSocketThrottleTest::SetAddressList(s2, addr); DeleteAddrInfo(addr); + DLOG(INFO) << "socket2"; TestCompletionCallback callback_s2; - EXPECT_EQ(ERR_IO_PENDING, throttle->OnStartOpenConnection(s2, &callback_s2)); + // Trying to open connection to host2 will wait for w1. + EXPECT_EQ(ERR_IO_PENDING, w2->OnStartOpenConnection(s2, &callback_s2)); + // Now waiting queue looks like + // Address | head -> tail + // 1.2.3.4 | w1 w2 + // 1.2.3.5 | w1 + // 1.2.3.6 | w1 // For host3: 1.2.3.5 addr = AddAddr(1, 2, 3, 5, NULL); + scoped_refptr<WebSocketJob> w3 = new WebSocketJob(&delegate); scoped_refptr<SocketStream> s3 = - new SocketStream(GURL("ws://host3/"), &delegate); + new SocketStream(GURL("ws://host3/"), w3.get()); + w3->InitSocketStream(s3.get()); WebSocketThrottleTest::SetAddressList(s3, addr); DeleteAddrInfo(addr); + DLOG(INFO) << "socket3"; TestCompletionCallback callback_s3; - EXPECT_EQ(ERR_IO_PENDING, throttle->OnStartOpenConnection(s3, &callback_s3)); + // Trying to open connection to host3 will wait for w1. + EXPECT_EQ(ERR_IO_PENDING, w3->OnStartOpenConnection(s3, &callback_s3)); + // Address | head -> tail + // 1.2.3.4 | w1 w2 + // 1.2.3.5 | w1 w3 + // 1.2.3.6 | w1 // For host4: 1.2.3.4, 1.2.3.6 addr = AddAddr(1, 2, 3, 4, NULL); addr = AddAddr(1, 2, 3, 6, addr); + scoped_refptr<WebSocketJob> w4 = new WebSocketJob(&delegate); scoped_refptr<SocketStream> s4 = - new SocketStream(GURL("ws://host4/"), &delegate); + new SocketStream(GURL("ws://host4/"), w4.get()); + w4->InitSocketStream(s4.get()); WebSocketThrottleTest::SetAddressList(s4, addr); DeleteAddrInfo(addr); + DLOG(INFO) << "socket4"; TestCompletionCallback callback_s4; - EXPECT_EQ(ERR_IO_PENDING, throttle->OnStartOpenConnection(s4, &callback_s4)); + // Trying to open connection to host4 will wait for w1, w2. + EXPECT_EQ(ERR_IO_PENDING, w4->OnStartOpenConnection(s4, &callback_s4)); + // Address | head -> tail + // 1.2.3.4 | w1 w2 w4 + // 1.2.3.5 | w1 w3 + // 1.2.3.6 | w1 w4 + + // For host5: 1.2.3.6 + addr = AddAddr(1, 2, 3, 6, NULL); + scoped_refptr<WebSocketJob> w5 = new WebSocketJob(&delegate); + scoped_refptr<SocketStream> s5 = + new SocketStream(GURL("ws://host5/"), w5.get()); + w5->InitSocketStream(s5.get()); + WebSocketThrottleTest::SetAddressList(s5, addr); + DeleteAddrInfo(addr); + + DLOG(INFO) << "socket5"; + TestCompletionCallback callback_s5; + // Trying to open connection to host5 will wait for w1, w4 + EXPECT_EQ(ERR_IO_PENDING, w5->OnStartOpenConnection(s5, &callback_s5)); + // Address | head -> tail + // 1.2.3.4 | w1 w2 w4 + // 1.2.3.5 | w1 w3 + // 1.2.3.6 | w1 w4 w5 + + // For host6: 1.2.3.6 + addr = AddAddr(1, 2, 3, 6, NULL); + scoped_refptr<WebSocketJob> w6 = new WebSocketJob(&delegate); + scoped_refptr<SocketStream> s6 = + new SocketStream(GURL("ws://host6/"), w6.get()); + w6->InitSocketStream(s6.get()); + WebSocketThrottleTest::SetAddressList(s6, addr); + DeleteAddrInfo(addr); + DLOG(INFO) << "socket6"; + TestCompletionCallback callback_s6; + // Trying to open connection to host6 will wait for w1, w4, w5 + EXPECT_EQ(ERR_IO_PENDING, w6->OnStartOpenConnection(s6, &callback_s6)); + // Address | head -> tail + // 1.2.3.4 | w1 w2 w4 + // 1.2.3.5 | w1 w3 + // 1.2.3.6 | w1 w4 w5 w6 + + // Receive partial response on w1, still connecting. + DLOG(INFO) << "socket1 1"; static const char kHeader[] = "HTTP/1.1 101 Web Socket Protocol\r\n"; - EXPECT_EQ(OK, - throttle->OnRead(s1.get(), kHeader, sizeof(kHeader) - 1, NULL)); + w1->OnReceivedData(s1.get(), kHeader, sizeof(kHeader) - 1); EXPECT_FALSE(callback_s2.have_result()); EXPECT_FALSE(callback_s3.have_result()); EXPECT_FALSE(callback_s4.have_result()); + EXPECT_FALSE(callback_s5.have_result()); + EXPECT_FALSE(callback_s6.have_result()); + // Receive rest of handshake response on w1. + DLOG(INFO) << "socket1 2"; static const char kHeader2[] = "Upgrade: WebSocket\r\n" "Connection: Upgrade\r\n" "WebSocket-Origin: http://www.google.com\r\n" "WebSocket-Location: ws://websocket.chromium.org\r\n" "\r\n"; - EXPECT_EQ(OK, - throttle->OnRead(s1.get(), kHeader2, sizeof(kHeader2) - 1, NULL)); + w1->OnReceivedData(s1.get(), kHeader2, sizeof(kHeader2) - 1); MessageLoopForIO::current()->RunAllPending(); + // Now, w1 is open. + EXPECT_EQ(WebSocketJob::OPEN, w1->state()); + // So, w2 and w3 can start connecting. w4 needs to wait w2 (1.2.3.4) EXPECT_TRUE(callback_s2.have_result()); EXPECT_TRUE(callback_s3.have_result()); EXPECT_FALSE(callback_s4.have_result()); + // Address | head -> tail + // 1.2.3.4 | w2 w4 + // 1.2.3.5 | w3 + // 1.2.3.6 | w4 w5 w6 - throttle->OnClose(s1.get()); + // Closing s1 doesn't change waiting queue. + DLOG(INFO) << "socket1 close"; + w1->OnClose(s1.get()); MessageLoopForIO::current()->RunAllPending(); EXPECT_FALSE(callback_s4.have_result()); s1->DetachDelegate(); + // Address | head -> tail + // 1.2.3.4 | w2 w4 + // 1.2.3.5 | w3 + // 1.2.3.6 | w4 w5 w6 + + // w5 can close while waiting in queue. + DLOG(INFO) << "socket5 close"; + // w5 close() closes SocketStream that change state to STATE_CLOSE, calls + // DoLoop(), so OnClose() callback will be called. + w5->OnClose(s5.get()); + MessageLoopForIO::current()->RunAllPending(); + EXPECT_FALSE(callback_s4.have_result()); + // Address | head -> tail + // 1.2.3.4 | w2 w4 + // 1.2.3.5 | w3 + // 1.2.3.6 | w4 w6 + s5->DetachDelegate(); + + // w6 close abnormally (e.g. renderer finishes) while waiting in queue. + DLOG(INFO) << "socket6 close abnormally"; + w6->DetachDelegate(); + MessageLoopForIO::current()->RunAllPending(); + EXPECT_FALSE(callback_s4.have_result()); + // Address | head -> tail + // 1.2.3.4 | w2 w4 + // 1.2.3.5 | w3 + // 1.2.3.6 | w4 - throttle->OnClose(s2.get()); + // Closing s2 kicks w4 to start connecting. + DLOG(INFO) << "socket2 close"; + w2->OnClose(s2.get()); MessageLoopForIO::current()->RunAllPending(); EXPECT_TRUE(callback_s4.have_result()); + // Address | head -> tail + // 1.2.3.4 | w4 + // 1.2.3.5 | w3 + // 1.2.3.6 | w4 s2->DetachDelegate(); - throttle->OnClose(s3.get()); + DLOG(INFO) << "socket3 close"; + w3->OnClose(s3.get()); MessageLoopForIO::current()->RunAllPending(); s3->DetachDelegate(); - throttle->OnClose(s4.get()); + w4->OnClose(s4.get()); s4->DetachDelegate(); + DLOG(INFO) << "Done"; } } |