Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: net/websockets/websocket_end_to_end_test.cc

Issue 722343003: Add end to end tests for WebSockets in net/websockets/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Disable the tests on Android. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/net.gypi ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // End-to-end tests for WebSocket. Usage guidelines:
6 // There are at least 4 sets of end-to-end tests in the source tree:
7 // 1) Blink layout tests. These are easy to write, and efficient because the
8 // client and server processes are both re-used. They are easy to write as
9 // they are just Javascript. They should be used for the majority of
10 // functional tests.
11 // 2) Browser tests in //chrome/browser/net/websocket_browsertest.cc. These
12 // are inefficient because both the server and client are restarted for each
13 // test. They are also hard to write and hard to debug. They should generally
14 // only be used for testing UI-related features.
15 // 3) PPAPI tests in //chrome/test/ppapi/ppapi_browsertest.cc. These are
16 // very hard to write and debug, and should only be used for verifying the
17 // operation of the Pepper API.
18 // 4) These tests. They are somewhat inefficient because the server is restarted
19 // for each test. They are well-suited for tests which require special server
20 // configurations.
21 //
22 // Tests should generally not be duplicated in the different places, except for
23 // regression tests and basic smoke tests.
24
tyoshino (SeeGerritForStatus) 2015/01/05 08:45:48 string
Adam Rice 2015/01/06 12:27:15 Done.
25 #include "base/callback.h"
26 #include "base/memory/scoped_ptr.h"
27 #include "base/run_loop.h"
28 #include "net/base/auth.h"
29 #include "net/base/network_delegate.h"
30 #include "net/base/test_data_directory.h"
tyoshino (SeeGerritForStatus) 2015/01/05 08:47:29 net/proxy/proxy_service.h
Adam Rice 2015/01/06 12:27:15 Done.
31 #include "net/test/spawned_test_server/spawned_test_server.h"
32 #include "net/url_request/url_request_test_util.h"
33 #include "net/websockets/websocket_channel.h"
34 #include "net/websockets/websocket_event_interface.h"
35 #include "testing/gtest/include/gtest/gtest.h"
36 #include "url/origin.h"
37
38 namespace net {
39
40 namespace {
41
42 static const char kEchoServer[] = "echo-with-no-extension";
43
44 // An implementation of WebSocketEventInterface that waits for and records the
45 // results of the connect.
46 class ConnectTestingEventInterface : public WebSocketEventInterface {
47 public:
48 ConnectTestingEventInterface() : fail_(true) {}
49
50 void WaitForResponse() {
51 quit_closure_ = run_loop_.QuitClosure();
tyoshino (SeeGerritForStatus) 2015/01/05 08:45:48 quit_closure_ is initialized here to make DCHECK o
Adam Rice 2015/01/06 12:27:15 No, it was a mistake. I misunderstood the API of R
52 run_loop_.Run();
53 }
54
tyoshino (SeeGerritForStatus) 2015/01/05 08:45:48 explain that this variable is used for storing sev
Adam Rice 2015/01/06 12:27:15 I decided that setting fail_ in OnDropChannel() wa
55 bool fail() const { return fail_; }
56
57 // Only set if the handshake failed, otherwise empty.
58 // Failure messages appear on the console and are checked by the layout tests,
59 // so they are expected to stay reasonably stable across versions.
60 std::string failure_message() const { return failure_message_; }
61
62 std::string selected_subprotocol() const { return selected_subprotocol_; }
63
64 std::string extensions() const { return extensions_; }
65
66 ChannelState OnAddChannelResponse(bool fail,
67 const std::string& selected_subprotocol,
68 const std::string& extensions) override {
69 fail_ = fail;
70 selected_subprotocol_ = selected_subprotocol;
71 extensions_ = extensions;
72 QuitNestedEventLoop();
73 return fail ? CHANNEL_DELETED : CHANNEL_ALIVE;
74 }
75
76 ChannelState OnDataFrame(bool fin,
77 WebSocketMessageType type,
78 const std::vector<char>& data) override {
79 return CHANNEL_ALIVE;
80 }
81
82 ChannelState OnFlowControl(int64 quota) override { return CHANNEL_ALIVE; }
83
84 ChannelState OnClosingHandshake() override { return CHANNEL_ALIVE; }
85
86 ChannelState OnDropChannel(bool was_clean,
87 uint16 code,
88 const std::string& reason) override {
89 fail_ = !was_clean;
90 QuitNestedEventLoop();
91 return CHANNEL_DELETED;
92 }
93
94 ChannelState OnFailChannel(const std::string& message) override {
95 fail_ = true;
96 failure_message_ = message;
97 QuitNestedEventLoop();
98 return CHANNEL_DELETED;
99 }
100
101 ChannelState OnStartOpeningHandshake(
102 scoped_ptr<WebSocketHandshakeRequestInfo> request) override {
103 return CHANNEL_ALIVE;
104 }
105
106 ChannelState OnFinishOpeningHandshake(
107 scoped_ptr<WebSocketHandshakeResponseInfo> response) override {
108 return CHANNEL_ALIVE;
109 }
110
111 ChannelState OnSSLCertificateError(
112 scoped_ptr<SSLErrorCallbacks> ssl_error_callbacks,
113 const GURL& url,
114 const SSLInfo& ssl_info,
115 bool fatal) override {
116 ssl_error_callbacks->CancelSSLRequest(ERR_SSL_PROTOCOL_ERROR, &ssl_info);
tyoshino (SeeGerritForStatus) 2015/01/05 08:45:48 I'm a little worried about CancelSSLRequest() bein
Adam Rice 2015/01/06 12:27:15 I'm not 100% sure. I decided to call it via the Po
117 return CHANNEL_ALIVE;
118 }
119
120 private:
121 void QuitNestedEventLoop() {
122 DCHECK(!quit_closure_.is_null());
123 quit_closure_.Run();
124 }
125 bool fail_;
126 std::string selected_subprotocol_;
127 std::string extensions_;
128 std::string failure_message_;
129 base::RunLoop run_loop_;
130 base::Closure quit_closure_;
131
132 DISALLOW_COPY_AND_ASSIGN(ConnectTestingEventInterface);
133 };
134
135 class WebSocketEndToEndTest : public ::testing::Test {
136 protected:
137 WebSocketEndToEndTest()
138 : event_interface_(new ConnectTestingEventInterface),
139 network_delegate_(new TestNetworkDelegate),
140 context_(true),
141 channel_(make_scoped_ptr(event_interface_), &context_),
142 origin_("http://localhost"),
143 initialised_context_(false) {}
144
145 void InitialiseContext() {
146 context_.set_network_delegate(network_delegate_.get());
147 context_.Init();
148 initialised_context_ = true;
149 }
150
151 bool ConnectAndWait(const GURL& socket_url) {
152 if (!initialised_context_) {
153 InitialiseContext();
154 }
155 channel_.SendAddChannelRequest(GURL(socket_url), sub_protocols_, origin_);
156 event_interface_->WaitForResponse();
157 return !event_interface_->fail();
158 }
159
160 ConnectTestingEventInterface* event_interface_; // owned by channel_
161 scoped_ptr<TestNetworkDelegate> network_delegate_;
162 TestURLRequestContext context_;
163 WebSocketChannel channel_;
164 std::vector<std::string> sub_protocols_;
165 url::Origin origin_;
tyoshino (SeeGerritForStatus) 2015/01/05 08:45:48 how about making sub_protocols_ and origin_ local
Adam Rice 2015/01/06 12:27:15 Done.
166 bool initialised_context_;
167 };
168
169 // None of these tests work on Android.
170 // TODO(ricea): Make these tests work on Android. See crbug.com/441711.
171 #if defined(OS_ANDROID)
172 #define DISABLED_ON_ANDROID(test) DISABLED_##test
173 #else
174 #define DISABLED_ON_ANDROID(test) test
175 #endif
176
177 // Basic test of connectivity. If this test fails, nothing else can be expected
178 // to work.
179 TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(BasicSmokeTest)) {
180 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
181 SpawnedTestServer::kLocalhost,
182 GetWebSocketTestDataDirectory());
183 ASSERT_TRUE(ws_server.Start());
184 EXPECT_TRUE(ConnectAndWait(ws_server.GetURL(kEchoServer)));
185 }
186
187 // Test for issue crbug.com/433695 "Unencrypted WebSocket connection via
188 // authenticated proxy times out"
189 // TODO(ricea): Enable this when the issue is fixed.
190 TEST_F(WebSocketEndToEndTest, DISABLED_HttpsProxyUnauthedFails) {
191 SpawnedTestServer proxy_server(SpawnedTestServer::TYPE_BASIC_AUTH_PROXY,
192 SpawnedTestServer::kLocalhost,
193 base::FilePath());
194 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
195 SpawnedTestServer::kLocalhost,
196 GetWebSocketTestDataDirectory());
197 ASSERT_TRUE(proxy_server.StartInBackground());
198 ASSERT_TRUE(ws_server.StartInBackground());
199 ASSERT_TRUE(proxy_server.BlockUntilStarted());
200 ASSERT_TRUE(ws_server.BlockUntilStarted());
201 std::string proxy_config =
202 "https=" + proxy_server.host_port_pair().ToString();
203 scoped_ptr<ProxyService> proxy_service(
204 ProxyService::CreateFixed(proxy_config));
205 ASSERT_TRUE(proxy_service);
206 context_.set_proxy_service(proxy_service.get());
207 EXPECT_FALSE(ConnectAndWait(ws_server.GetURL(kEchoServer)));
208 EXPECT_EQ("Proxy authentication failed", event_interface_->failure_message());
209 }
210
211 TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HttpsWssProxyUnauthedFails)) {
212 SpawnedTestServer proxy_server(SpawnedTestServer::TYPE_BASIC_AUTH_PROXY,
213 SpawnedTestServer::kLocalhost,
214 base::FilePath());
215 SpawnedTestServer wss_server(SpawnedTestServer::TYPE_WSS,
216 SpawnedTestServer::kLocalhost,
217 GetWebSocketTestDataDirectory());
218 ASSERT_TRUE(proxy_server.StartInBackground());
219 ASSERT_TRUE(wss_server.StartInBackground());
220 ASSERT_TRUE(proxy_server.BlockUntilStarted());
221 ASSERT_TRUE(wss_server.BlockUntilStarted());
222 std::string proxy_config =
223 "https=" + proxy_server.host_port_pair().ToString();
224 scoped_ptr<ProxyService> proxy_service(
225 ProxyService::CreateFixed(proxy_config));
226 ASSERT_TRUE(proxy_service);
227 context_.set_proxy_service(proxy_service.get());
228 EXPECT_FALSE(ConnectAndWait(wss_server.GetURL(kEchoServer)));
229 EXPECT_EQ("Proxy authentication failed", event_interface_->failure_message());
230 }
231
232 // Regression test for crbug/426736 "WebSocket connections not using configured
233 // system HTTPS Proxy".
234 TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HttpsProxyUsed)) {
235 SpawnedTestServer proxy_server(SpawnedTestServer::TYPE_BASIC_AUTH_PROXY,
236 SpawnedTestServer::kLocalhost,
237 base::FilePath());
238 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
239 SpawnedTestServer::kLocalhost,
240 GetWebSocketTestDataDirectory());
241 ASSERT_TRUE(proxy_server.StartInBackground());
242 ASSERT_TRUE(ws_server.StartInBackground());
243 ASSERT_TRUE(proxy_server.BlockUntilStarted());
244 ASSERT_TRUE(ws_server.BlockUntilStarted());
245 std::string proxy_config = "https=" +
246 proxy_server.host_port_pair().ToString() + ";" +
247 "http=" + proxy_server.host_port_pair().ToString();
248 scoped_ptr<ProxyService> proxy_service(
249 ProxyService::CreateFixed(proxy_config));
250 context_.set_proxy_service(proxy_service.get());
251 InitialiseContext();
252
253 // The test server doesn't have an unauthenticated proxy mode. WebSockets
254 // cannot provide auth information that isn't already cached, so it's
255 // necessary to preflight an HTTP request to authenticate against the proxy.
256 std::string scheme("http");
257 GURL::Replacements replacements;
258 replacements.SetSchemeStr(scheme);
259 // It doesn't matter what the URL is, as long as it is an HTTP navigation.
260 GURL http_page =
261 ws_server.GetURL("connect_check.html").ReplaceComponents(replacements);
262 TestDelegate delegate;
263 delegate.set_credentials(
264 AuthCredentials(base::ASCIIToUTF16("foo"), base::ASCIIToUTF16("bar")));
265 {
266 scoped_ptr<URLRequest> request(
267 context_.CreateRequest(http_page, DEFAULT_PRIORITY, &delegate, NULL));
268 request->Start();
269 // TestDelegate exits the message loop when the request completes by
270 // default.
271 base::RunLoop().Run();
272 EXPECT_TRUE(delegate.auth_required_called());
273 }
274
275 int previous_observed_before_proxy_headers_sent_callbacks =
276 network_delegate_->observed_before_proxy_headers_sent_callbacks();
277 EXPECT_TRUE(ConnectAndWait(ws_server.GetURL(kEchoServer)));
278 EXPECT_EQ(previous_observed_before_proxy_headers_sent_callbacks + 1,
279 network_delegate_->observed_before_proxy_headers_sent_callbacks());
tyoshino (SeeGerritForStatus) 2015/01/05 08:45:48 what does this expectations add? reading the varia
Adam Rice 2015/01/06 12:27:15 It works because of a bug. I'm still looking for a
Adam Rice 2015/01/06 15:48:43 I found a way to do it. PTAL.
280 }
281
282 } // namespace
283
284 } // namespace net
OLDNEW
« no previous file with comments | « net/net.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698