summaryrefslogtreecommitdiffstats
path: root/net/websockets/websocket_throttle_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/websockets/websocket_throttle_unittest.cc')
-rw-r--r--net/websockets/websocket_throttle_unittest.cc166
1 files changed, 166 insertions, 0 deletions
diff --git a/net/websockets/websocket_throttle_unittest.cc b/net/websockets/websocket_throttle_unittest.cc
new file mode 100644
index 0000000..3757a0b
--- /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();
+}
+
+}