summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authortoyoshim@chromium.org <toyoshim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-06 12:30:07 +0000
committertoyoshim@chromium.org <toyoshim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-06 12:30:07 +0000
commit71a356cbc5fd61fa36e726a0ab613fe760e9256b (patch)
treeb6dc429b48e9b10787a504e0c09181662b5c9547 /net
parent85c1dcebfbb0e3f2696086a6e6ad6156af0afad5 (diff)
downloadchromium_src-71a356cbc5fd61fa36e726a0ab613fe760e9256b.zip
chromium_src-71a356cbc5fd61fa36e726a0ab613fe760e9256b.tar.gz
chromium_src-71a356cbc5fd61fa36e726a0ab613fe760e9256b.tar.bz2
WebSocket: Add connection test on WebSocketJobTest
- Move local test utility classes into anonymous namespace. - Add new connection test. BUG=NONE TEST=net_unittests --gtest_filter=WebSocketJobTest\* Review URL: http://codereview.chromium.org/7193035 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@91550 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/websockets/websocket_job_unittest.cc280
1 files changed, 233 insertions, 47 deletions
diff --git a/net/websockets/websocket_job_unittest.cc b/net/websockets/websocket_job_unittest.cc
index ff20864..e863faf 100644
--- a/net/websockets/websocket_job_unittest.cc
+++ b/net/websockets/websocket_job_unittest.cc
@@ -11,10 +11,16 @@
#include "base/string_split.h"
#include "base/string_util.h"
#include "googleurl/src/gurl.h"
+#include "net/base/completion_callback.h"
#include "net/base/cookie_store.h"
+#include "net/base/mock_host_resolver.h"
#include "net/base/net_errors.h"
+#include "net/base/ssl_config_service.h"
#include "net/base/sys_addrinfo.h"
+#include "net/base/test_completion_callback.h"
#include "net/base/transport_security_state.h"
+#include "net/proxy/proxy_service.h"
+#include "net/socket/socket_test_util.h"
#include "net/socket_stream/socket_stream.h"
#include "net/url_request/url_request_context.h"
#include "net/websockets/websocket_throttle.h"
@@ -22,11 +28,11 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/platform_test.h"
-namespace net {
+namespace {
-class MockSocketStream : public SocketStream {
+class MockSocketStream : public net::SocketStream {
public:
- MockSocketStream(const GURL& url, SocketStream::Delegate* delegate)
+ MockSocketStream(const GURL& url, net::SocketStream::Delegate* delegate)
: SocketStream(url, delegate) {}
virtual ~MockSocketStream() {}
@@ -51,7 +57,7 @@ class MockSocketStream : public SocketStream {
std::string sent_data_;
};
-class MockSocketStreamDelegate : public SocketStream::Delegate {
+class MockSocketStreamDelegate : public net::SocketStream::Delegate {
public:
MockSocketStreamDelegate()
: amount_sent_(0), allow_all_cookies_(true) {}
@@ -60,25 +66,46 @@ class MockSocketStreamDelegate : public SocketStream::Delegate {
}
virtual ~MockSocketStreamDelegate() {}
- virtual void OnConnected(SocketStream* socket,
+ void SetOnConnected(Callback0::Type* callback) {
+ on_connected_.reset(callback);
+ }
+ void SetOnSentData(Callback0::Type* callback) {
+ on_sent_data_.reset(callback);
+ }
+ void SetOnReceivedData(Callback0::Type* callback) {
+ on_received_data_.reset(callback);
+ }
+ void SetOnClose(Callback0::Type* callback) {
+ on_close_.reset(callback);
+ }
+
+ virtual void OnConnected(net::SocketStream* socket,
int max_pending_send_allowed) {
+ if (on_connected_.get())
+ on_connected_->Run();
}
- virtual void OnSentData(SocketStream* socket, int amount_sent) {
+ virtual void OnSentData(net::SocketStream* socket, int amount_sent) {
amount_sent_ += amount_sent;
+ if (on_sent_data_.get())
+ on_sent_data_->Run();
}
- virtual void OnReceivedData(SocketStream* socket,
+ virtual void OnReceivedData(net::SocketStream* socket,
const char* data, int len) {
received_data_ += std::string(data, len);
+ if (on_received_data_.get())
+ on_received_data_->Run();
}
- virtual void OnClose(SocketStream* socket) {
+ virtual void OnClose(net::SocketStream* socket) {
+ if (on_close_.get())
+ on_close_->Run();
}
- virtual bool CanGetCookies(SocketStream* socket, const GURL& url) {
+ virtual bool CanGetCookies(net::SocketStream* socket, const GURL& url) {
return allow_all_cookies_;
}
- virtual bool CanSetCookie(SocketStream* request,
+ virtual bool CanSetCookie(net::SocketStream* request,
const GURL& url,
const std::string& cookie_line,
- CookieOptions* options) {
+ net::CookieOptions* options) {
return allow_all_cookies_;
}
@@ -89,20 +116,24 @@ class MockSocketStreamDelegate : public SocketStream::Delegate {
int amount_sent_;
bool allow_all_cookies_;
std::string received_data_;
+ scoped_ptr<Callback0::Type> on_connected_;
+ scoped_ptr<Callback0::Type> on_sent_data_;
+ scoped_ptr<Callback0::Type> on_received_data_;
+ scoped_ptr<Callback0::Type> on_close_;
};
-class MockCookieStore : public CookieStore {
+class MockCookieStore : public net::CookieStore {
public:
struct Entry {
GURL url;
std::string cookie_line;
- CookieOptions options;
+ net::CookieOptions options;
};
MockCookieStore() {}
virtual bool SetCookieWithOptions(const GURL& url,
const std::string& cookie_line,
- const CookieOptions& options) {
+ const net::CookieOptions& options) {
Entry entry;
entry.url = url;
entry.cookie_line = cookie_line;
@@ -110,8 +141,9 @@ class MockCookieStore : public CookieStore {
entries_.push_back(entry);
return true;
}
- virtual std::string GetCookiesWithOptions(const GURL& url,
- const CookieOptions& options) {
+ virtual std::string GetCookiesWithOptions(
+ const GURL& url,
+ const net::CookieOptions& options) {
std::string result;
for (size_t i = 0; i < entries_.size(); i++) {
Entry &entry = entries_[i];
@@ -125,14 +157,14 @@ class MockCookieStore : public CookieStore {
return result;
}
virtual void GetCookiesWithInfo(const GURL& url,
- const CookieOptions& options,
+ const net::CookieOptions& options,
std::string* cookie_line,
std::vector<CookieInfo>* cookie_infos) {
NOTREACHED();
}
virtual void DeleteCookie(const GURL& url,
const std::string& cookie_name) {}
- virtual CookieMonster* GetCookieMonster() { return NULL; }
+ virtual net::CookieMonster* GetCookieMonster() { return NULL; }
const std::vector<Entry>& entries() const { return entries_; }
@@ -143,13 +175,18 @@ class MockCookieStore : public CookieStore {
std::vector<Entry> entries_;
};
-class MockURLRequestContext : public URLRequestContext {
+class MockSSLConfigService : public net::SSLConfigService {
public:
- explicit MockURLRequestContext(CookieStore* cookie_store) {
+ virtual void GetSSLConfig(net::SSLConfig* config) {};
+};
+
+class MockURLRequestContext : public net::URLRequestContext {
+ public:
+ explicit MockURLRequestContext(net::CookieStore* cookie_store) {
set_cookie_store(cookie_store);
- transport_security_state_ = new TransportSecurityState(std::string());
+ transport_security_state_ = new net::TransportSecurityState(std::string());
set_transport_security_state(transport_security_state_.get());
- TransportSecurityState::DomainState state;
+ net::TransportSecurityState::DomainState state;
state.expiry = base::Time::Now() + base::TimeDelta::FromSeconds(1000);
transport_security_state_->EnableHost("upgrademe.com", state);
}
@@ -158,12 +195,17 @@ class MockURLRequestContext : public URLRequestContext {
friend class base::RefCountedThreadSafe<MockURLRequestContext>;
virtual ~MockURLRequestContext() {}
- scoped_refptr<TransportSecurityState> transport_security_state_;
+ scoped_refptr<net::TransportSecurityState> transport_security_state_;
};
+}
+
+namespace net {
+
class WebSocketJobTest : public PlatformTest {
public:
virtual void SetUp() {
+ stream_type_ = STREAM_INVALID;
cookie_store_ = new MockCookieStore;
context_ = new MockURLRequestContext(cookie_store_.get());
}
@@ -173,10 +215,61 @@ class WebSocketJobTest : public PlatformTest {
websocket_ = NULL;
socket_ = NULL;
}
+ void DoSendRequest() {
+ EXPECT_TRUE(websocket_->SendData(kHandshakeRequestWithoutCookie,
+ kHandshakeRequestWithoutCookieLength));
+ }
+ void DoSendData() {
+ if (received_data().size() == kHandshakeResponseWithoutCookieLength)
+ websocket_->SendData(kDataHello, kDataHelloLength);
+ }
+ void DoSync() {
+ sync_callback_.Run(OK);
+ }
+ int WaitForResult() {
+ return sync_callback_.WaitForResult();
+ }
protected:
- void InitWebSocketJob(const GURL& url, MockSocketStreamDelegate* delegate) {
+ enum StreamType {
+ STREAM_INVALID,
+ STREAM_MOCK_SOCKET,
+ STREAM_SOCKET,
+ STREAM_SPDY_WEBSOCKET,
+ };
+ void InitWebSocketJob(const GURL& url,
+ MockSocketStreamDelegate* delegate,
+ StreamType stream_type) {
+ stream_type_ = stream_type;
websocket_ = new WebSocketJob(delegate);
- socket_ = new MockSocketStream(url, websocket_.get());
+
+ if (stream_type == STREAM_SOCKET ||
+ stream_type == STREAM_SPDY_WEBSOCKET) {
+ ssl_config_service_ = new MockSSLConfigService();
+ context_->set_ssl_config_service(ssl_config_service_);
+ proxy_service_.reset(net::ProxyService::CreateDirect());
+ context_->set_proxy_service(proxy_service_.get());
+ host_resolver_.reset(new net::MockHostResolver);
+ context_->set_host_resolver(host_resolver_.get());
+ }
+
+ switch (stream_type) {
+ case STREAM_INVALID:
+ NOTREACHED();
+ break;
+ case STREAM_MOCK_SOCKET:
+ socket_ = new MockSocketStream(url, websocket_.get());
+ break;
+ case STREAM_SOCKET:
+ socket_ = new SocketStream(url, websocket_.get());
+ socket_factory_.reset(new MockClientSocketFactory);
+ DCHECK(data_.get());
+ socket_factory_->AddSocketDataProvider(data_.get());
+ socket_->SetClientSocketFactory(socket_factory_.get());
+ break;
+ case STREAM_SPDY_WEBSOCKET:
+ // TODO(toyoshim): Support SpdyWebSocketStream.
+ break;
+ }
websocket_->InitSocketStream(socket_.get());
websocket_->set_context(context_.get());
struct addrinfo addr;
@@ -209,28 +302,55 @@ class WebSocketJobTest : public PlatformTest {
SocketStream* GetSocket(SocketStreamJob* job) {
return job->socket_.get();
}
+ const std::string& sent_data() const {
+ DCHECK_EQ(STREAM_MOCK_SOCKET, stream_type_);
+ MockSocketStream* socket =
+ static_cast<MockSocketStream*>(socket_.get());
+ DCHECK(socket);
+ return socket->sent_data();
+ }
+ const std::string& received_data() const {
+ DCHECK_NE(STREAM_INVALID, stream_type_);
+ MockSocketStreamDelegate* delegate =
+ static_cast<MockSocketStreamDelegate*>(websocket_->delegate_);
+ DCHECK(delegate);
+ return delegate->received_data();
+ }
+
void TestSimpleHandshake();
void TestSlowHandshake();
void TestHandshakeWithCookie();
void TestHandshakeWithCookieButNotAllowed();
void TestHSTSUpgrade();
void TestInvalidSendData();
+ void TestConnectByWebSocket();
+ StreamType stream_type_;
scoped_refptr<MockCookieStore> cookie_store_;
scoped_refptr<MockURLRequestContext> context_;
scoped_refptr<WebSocketJob> websocket_;
- scoped_refptr<MockSocketStream> socket_;
+ scoped_refptr<SocketStream> socket_;
+ scoped_ptr<MockClientSocketFactory> socket_factory_;
+ scoped_refptr<OrderedSocketData> data_;
+ TestCompletionCallback sync_callback_;
+ scoped_refptr<MockSSLConfigService> ssl_config_service_;
+ scoped_ptr<net::ProxyService> proxy_service_;
+ scoped_ptr<net::MockHostResolver> host_resolver_;
static const char kHandshakeRequestWithoutCookie[];
static const char kHandshakeRequestWithCookie[];
static const char kHandshakeRequestWithFilteredCookie[];
static const char kHandshakeResponseWithoutCookie[];
static const char kHandshakeResponseWithCookie[];
+ static const char kDataHello[];
+ static const char kDataWorld[];
static const size_t kHandshakeRequestWithoutCookieLength;
static const size_t kHandshakeRequestWithCookieLength;
static const size_t kHandshakeRequestWithFilteredCookieLength;
static const size_t kHandshakeResponseWithoutCookieLength;
static const size_t kHandshakeResponseWithCookieLength;
+ static const size_t kDataHelloLength;
+ static const size_t kDataWorldLength;
};
const char WebSocketJobTest::kHandshakeRequestWithoutCookie[] =
@@ -292,6 +412,10 @@ const char WebSocketJobTest::kHandshakeResponseWithCookie[] =
"\r\n"
"8jKS'y:G*Co,Wxa-";
+const char WebSocketJobTest::kDataHello[] = "Hello, ";
+
+const char WebSocketJobTest::kDataWorld[] = "World!\n";
+
const size_t WebSocketJobTest::kHandshakeRequestWithoutCookieLength =
arraysize(kHandshakeRequestWithoutCookie) - 1;
const size_t WebSocketJobTest::kHandshakeRequestWithCookieLength =
@@ -302,18 +426,20 @@ const size_t WebSocketJobTest::kHandshakeResponseWithoutCookieLength =
arraysize(kHandshakeResponseWithoutCookie) - 1;
const size_t WebSocketJobTest::kHandshakeResponseWithCookieLength =
arraysize(kHandshakeResponseWithCookie) - 1;
+const size_t WebSocketJobTest::kDataHelloLength =
+ arraysize(kDataHello) - 1;
+const size_t WebSocketJobTest::kDataWorldLength =
+ arraysize(kDataWorld) - 1;
void WebSocketJobTest::TestSimpleHandshake() {
GURL url("ws://example.com/demo");
MockSocketStreamDelegate delegate;
- InitWebSocketJob(url, &delegate);
+ InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
SkipToConnecting();
- bool sent = websocket_->SendData(kHandshakeRequestWithoutCookie,
- kHandshakeRequestWithoutCookieLength);
- EXPECT_TRUE(sent);
+ DoSendRequest();
MessageLoop::current()->RunAllPending();
- EXPECT_EQ(kHandshakeRequestWithoutCookie, socket_->sent_data());
+ EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data());
EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
websocket_->OnSentData(socket_.get(),
kHandshakeRequestWithoutCookieLength);
@@ -331,16 +457,14 @@ void WebSocketJobTest::TestSimpleHandshake() {
void WebSocketJobTest::TestSlowHandshake() {
GURL url("ws://example.com/demo");
MockSocketStreamDelegate delegate;
- InitWebSocketJob(url, &delegate);
+ InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
SkipToConnecting();
- bool sent = websocket_->SendData(kHandshakeRequestWithoutCookie,
- kHandshakeRequestWithoutCookieLength);
- EXPECT_TRUE(sent);
+ DoSendRequest();
// We assume request is sent in one data chunk (from WebKit)
// We don't support streaming request.
MessageLoop::current()->RunAllPending();
- EXPECT_EQ(kHandshakeRequestWithoutCookie, socket_->sent_data());
+ EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data());
EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
websocket_->OnSentData(socket_.get(),
kHandshakeRequestWithoutCookieLength);
@@ -379,14 +503,14 @@ void WebSocketJobTest::TestHandshakeWithCookie() {
cookieUrl, "CR-test-httponly=1", cookie_options);
MockSocketStreamDelegate delegate;
- InitWebSocketJob(url, &delegate);
+ InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
SkipToConnecting();
bool sent = websocket_->SendData(kHandshakeRequestWithCookie,
kHandshakeRequestWithCookieLength);
EXPECT_TRUE(sent);
MessageLoop::current()->RunAllPending();
- EXPECT_EQ(kHandshakeRequestWithFilteredCookie, socket_->sent_data());
+ EXPECT_EQ(kHandshakeRequestWithFilteredCookie, sent_data());
EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
websocket_->OnSentData(socket_,
kHandshakeRequestWithFilteredCookieLength);
@@ -423,14 +547,14 @@ void WebSocketJobTest::TestHandshakeWithCookieButNotAllowed() {
MockSocketStreamDelegate delegate;
delegate.set_allow_all_cookies(false);
- InitWebSocketJob(url, &delegate);
+ InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
SkipToConnecting();
bool sent = websocket_->SendData(kHandshakeRequestWithCookie,
kHandshakeRequestWithCookieLength);
EXPECT_TRUE(sent);
MessageLoop::current()->RunAllPending();
- EXPECT_EQ(kHandshakeRequestWithoutCookie, socket_->sent_data());
+ EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data());
EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
websocket_->OnSentData(socket_, kHandshakeRequestWithoutCookieLength);
EXPECT_EQ(kHandshakeRequestWithCookieLength,
@@ -473,29 +597,81 @@ void WebSocketJobTest::TestHSTSUpgrade() {
void WebSocketJobTest::TestInvalidSendData() {
GURL url("ws://example.com/demo");
MockSocketStreamDelegate delegate;
- InitWebSocketJob(url, &delegate);
+ InitWebSocketJob(url, &delegate, STREAM_MOCK_SOCKET);
SkipToConnecting();
- bool sent = websocket_->SendData(kHandshakeRequestWithoutCookie,
- kHandshakeRequestWithoutCookieLength);
- EXPECT_TRUE(sent);
+ DoSendRequest();
// We assume request is sent in one data chunk (from WebKit)
// We don't support streaming request.
MessageLoop::current()->RunAllPending();
- EXPECT_EQ(kHandshakeRequestWithoutCookie, socket_->sent_data());
+ EXPECT_EQ(kHandshakeRequestWithoutCookie, sent_data());
EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
websocket_->OnSentData(socket_.get(),
kHandshakeRequestWithoutCookieLength);
EXPECT_EQ(kHandshakeRequestWithoutCookieLength, delegate.amount_sent());
// We could not send any data until connection is established.
- sent = websocket_->SendData(kHandshakeRequestWithoutCookie,
- kHandshakeRequestWithoutCookieLength);
+ bool sent = websocket_->SendData(kHandshakeRequestWithoutCookie,
+ kHandshakeRequestWithoutCookieLength);
EXPECT_FALSE(sent);
EXPECT_EQ(WebSocketJob::CONNECTING, GetWebSocketJobState());
CloseWebSocketJob();
}
+// Following tests verify cooperation between WebSocketJob and SocketStream.
+// Other former tests use MockSocketStream as SocketStream, so we could not
+// check SocketStream behavior.
+// OrderedSocketData provide socket level verifiation by checking out-going
+// packets in comparison with the MockWrite array and emulating in-coming
+// packets with MockRead array.
+// TODO(toyoshim): Add tests which verify protocol switch and ERR_IO_PENDING.
+
+void WebSocketJobTest::TestConnectByWebSocket() {
+ // This is a test for verifying cooperation between WebSocketJob and
+ // SocketStream in basic situation.
+ MockWrite writes[] = {
+ MockWrite(true,
+ kHandshakeRequestWithoutCookie,
+ kHandshakeRequestWithoutCookieLength,
+ 1),
+ MockWrite(true,
+ kDataHello,
+ kDataHelloLength,
+ 3)
+ };
+ MockRead reads[] = {
+ MockRead(true,
+ kHandshakeResponseWithoutCookie,
+ kHandshakeResponseWithoutCookieLength,
+ 2),
+ MockRead(true,
+ kDataWorld,
+ kDataWorldLength,
+ 4),
+ MockRead(false, 0, 5) // EOF
+ };
+ data_ = (new OrderedSocketData(
+ reads, arraysize(reads), writes, arraysize(writes)));
+
+ GURL url("ws://example.com/demo");
+ MockSocketStreamDelegate delegate;
+ WebSocketJobTest* test = this;
+ delegate.SetOnConnected(
+ NewCallback(test, &WebSocketJobTest::DoSendRequest));
+ delegate.SetOnReceivedData(
+ NewCallback(test, &WebSocketJobTest::DoSendData));
+ delegate.SetOnClose(
+ NewCallback(test, &WebSocketJobTest::DoSync));
+ InitWebSocketJob(url, &delegate, STREAM_SOCKET);
+
+ websocket_->Connect();
+ EXPECT_EQ(OK, WaitForResult());
+ EXPECT_TRUE(data_->at_read_eof());
+ EXPECT_TRUE(data_->at_write_eof());
+ EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState());
+}
+
+// Execute tests in both spdy-disabled mode and spdy-enabled mode.
TEST_F(WebSocketJobTest, SimpleHandshake) {
WebSocketJob::set_websocket_over_spdy_enabled(false);
TestSimpleHandshake();
@@ -556,4 +732,14 @@ TEST_F(WebSocketJobTest, InvalidSendDataSpdyEnabled) {
TestInvalidSendData();
}
+TEST_F(WebSocketJobTest, ConnectByWebSocket) {
+ WebSocketJob::set_websocket_over_spdy_enabled(false);
+ TestConnectByWebSocket();
+}
+
+TEST_F(WebSocketJobTest, ConnectByWebSocketSpdyEnabled) {
+ WebSocketJob::set_websocket_over_spdy_enabled(true);
+ TestConnectByWebSocket();
+}
+
} // namespace net