Index: net/websockets/websocket_throttle_unittest.cc |
diff --git a/net/websockets/websocket_throttle_unittest.cc b/net/websockets/websocket_throttle_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3757a0bdb228d72f4efd1d23a51af8ffe6d93c6c |
--- /dev/null |
+++ b/net/websockets/websocket_throttle_unittest.cc |
@@ -0,0 +1,166 @@ |
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "build/build_config.h" |
+ |
+#if defined(OS_WIN) |
+#include <ws2tcpip.h> |
+#else |
+#include <netdb.h> |
+#endif |
+ |
+#include <string> |
+ |
+#include "base/message_loop.h" |
+#include "googleurl/src/gurl.h" |
+#include "net/base/address_list.h" |
+#include "net/base/test_completion_callback.h" |
+#include "net/socket_stream/socket_stream.h" |
+#include "net/websockets/websocket_throttle.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "testing/platform_test.h" |
+ |
+class DummySocketStreamDelegate : public net::SocketStream::Delegate { |
+ public: |
+ DummySocketStreamDelegate() {} |
+ virtual ~DummySocketStreamDelegate() {} |
+ virtual void OnConnected( |
+ net::SocketStream* socket, int max_pending_send_allowed) {} |
+ virtual void OnSentData(net::SocketStream* socket, int amount_sent) {} |
+ virtual void OnReceivedData(net::SocketStream* socket, |
+ const char* data, int len) {} |
+ virtual void OnClose(net::SocketStream* socket) {} |
+}; |
+ |
+namespace net { |
+ |
+class WebSocketThrottleTest : public PlatformTest { |
+ protected: |
+ struct addrinfo *AddAddr(int a1, int a2, int a3, int a4, |
+ struct addrinfo* next) { |
+ struct addrinfo* addrinfo = new struct addrinfo; |
+ memset(addrinfo, 0, sizeof(struct addrinfo)); |
+ addrinfo->ai_family = AF_INET; |
+ int addrlen = sizeof(struct sockaddr_in); |
+ addrinfo->ai_addrlen = addrlen; |
+ addrinfo->ai_addr = reinterpret_cast<sockaddr*>(new char[addrlen]); |
+ memset(addrinfo->ai_addr, 0, sizeof(addrlen)); |
+ struct sockaddr_in* addr = |
+ reinterpret_cast<sockaddr_in*>(addrinfo->ai_addr); |
+ int addrint = ((a1 & 0xff) << 24) | |
+ ((a2 & 0xff) << 16) | |
+ ((a3 & 0xff) << 8) | |
+ ((a4 & 0xff)); |
+ memcpy(&addr->sin_addr, &addrint, sizeof(int)); |
+ addrinfo->ai_next = next; |
+ return addrinfo; |
+ } |
+ void DeleteAddrInfo(struct addrinfo* head) { |
+ if (!head) |
+ return; |
+ struct addrinfo* next; |
+ for (struct addrinfo* a = head; a != NULL; a = next) { |
+ next = a->ai_next; |
+ delete [] a->ai_addr; |
+ delete a; |
+ } |
+ } |
+ |
+ static void SetAddressList(SocketStream* socket, struct addrinfo* head) { |
+ socket->CopyAddrInfo(head); |
+ } |
+}; |
+ |
+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<SocketStream> s1 = |
+ new SocketStream(GURL("ws://host1/"), &delegate); |
+ WebSocketThrottleTest::SetAddressList(s1, addr); |
+ DeleteAddrInfo(addr); |
+ |
+ TestCompletionCallback callback_s1; |
+ EXPECT_EQ(OK, throttle->OnStartOpenConnection(s1, &callback_s1)); |
+ |
+ // For host2: 1.2.3.4 |
+ addr = AddAddr(1, 2, 3, 4, NULL); |
+ scoped_refptr<SocketStream> s2 = |
+ new SocketStream(GURL("ws://host2/"), &delegate); |
+ WebSocketThrottleTest::SetAddressList(s2, addr); |
+ DeleteAddrInfo(addr); |
+ |
+ TestCompletionCallback callback_s2; |
+ EXPECT_EQ(ERR_IO_PENDING, throttle->OnStartOpenConnection(s2, &callback_s2)); |
+ |
+ // For host3: 1.2.3.5 |
+ addr = AddAddr(1, 2, 3, 5, NULL); |
+ scoped_refptr<SocketStream> s3 = |
+ new SocketStream(GURL("ws://host3/"), &delegate); |
+ WebSocketThrottleTest::SetAddressList(s3, addr); |
+ DeleteAddrInfo(addr); |
+ |
+ TestCompletionCallback callback_s3; |
+ EXPECT_EQ(ERR_IO_PENDING, throttle->OnStartOpenConnection(s3, &callback_s3)); |
+ |
+ // 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<SocketStream> s4 = |
+ new SocketStream(GURL("ws://host4/"), &delegate); |
+ WebSocketThrottleTest::SetAddressList(s4, addr); |
+ DeleteAddrInfo(addr); |
+ |
+ TestCompletionCallback callback_s4; |
+ EXPECT_EQ(ERR_IO_PENDING, throttle->OnStartOpenConnection(s4, &callback_s4)); |
+ |
+ 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)); |
+ EXPECT_FALSE(callback_s2.have_result()); |
+ EXPECT_FALSE(callback_s3.have_result()); |
+ EXPECT_FALSE(callback_s4.have_result()); |
+ |
+ 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)); |
+ MessageLoopForIO::current()->RunAllPending(); |
+ EXPECT_TRUE(callback_s2.have_result()); |
+ EXPECT_TRUE(callback_s3.have_result()); |
+ EXPECT_FALSE(callback_s4.have_result()); |
+ |
+ throttle->OnClose(s1.get()); |
+ MessageLoopForIO::current()->RunAllPending(); |
+ EXPECT_FALSE(callback_s4.have_result()); |
+ s1->DetachDelegate(); |
+ |
+ throttle->OnClose(s2.get()); |
+ MessageLoopForIO::current()->RunAllPending(); |
+ EXPECT_TRUE(callback_s4.have_result()); |
+ s2->DetachDelegate(); |
+ |
+ throttle->OnClose(s3.get()); |
+ MessageLoopForIO::current()->RunAllPending(); |
+ s3->DetachDelegate(); |
+ throttle->OnClose(s4.get()); |
+ s4->DetachDelegate(); |
+} |
+ |
+} |