NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / ui / webui / net_internals / net_internals_ui_browsertest.cc
blob6c8e5b34ba1b23f901910b70d855262eb9219447
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/file_util.h"
11 #include "base/files/file_path.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/io_thread.h"
17 #include "chrome/browser/net/chrome_net_log.h"
18 #include "chrome/browser/prerender/prerender_manager.h"
19 #include "chrome/browser/prerender/prerender_manager_factory.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/tabs/tab_strip_model.h"
23 #include "chrome/browser/ui/webui/net_internals/net_internals_ui.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/test/base/ui_test_utils.h"
26 #include "content/public/browser/render_view_host.h"
27 #include "content/public/browser/web_contents.h"
28 #include "content/public/browser/web_ui_message_handler.h"
29 #include "net/base/address_list.h"
30 #include "net/base/net_errors.h"
31 #include "net/base/net_log.h"
32 #include "net/base/net_log_logger.h"
33 #include "net/dns/host_cache.h"
34 #include "net/dns/host_resolver.h"
35 #include "net/dns/mock_host_resolver.h"
36 #include "net/http/http_network_session.h"
37 #include "net/http/http_pipelined_host_capability.h"
38 #include "net/http/http_transaction_factory.h"
39 #include "net/url_request/url_request_context.h"
40 #include "net/url_request/url_request_context_getter.h"
41 #include "testing/gtest/include/gtest/gtest.h"
42 #include "url/gurl.h"
44 using content::BrowserThread;
45 using content::WebUIMessageHandler;
47 namespace {
49 // Called on IO thread. Adds an entry to the cache for the specified hostname.
50 // Either |net_error| must be net::OK, or |address| must be NULL.
51 void AddCacheEntryOnIOThread(net::URLRequestContextGetter* context_getter,
52 const std::string& hostname,
53 const std::string& ip_literal,
54 int net_error,
55 int expire_days_from_now) {
56 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
57 net::URLRequestContext* context = context_getter->GetURLRequestContext();
58 net::HostCache* cache = context->host_resolver()->GetHostCache();
59 ASSERT_TRUE(cache);
61 net::HostCache::Key key(hostname, net::ADDRESS_FAMILY_UNSPECIFIED, 0);
62 base::TimeDelta ttl = base::TimeDelta::FromDays(expire_days_from_now);
64 net::AddressList address_list;
65 if (net_error == net::OK) {
66 // If |net_error| does not indicate an error, convert |ip_literal| to a
67 // net::AddressList, so it can be used with the cache.
68 int rv = net::ParseAddressList(ip_literal, hostname, &address_list);
69 ASSERT_EQ(net::OK, rv);
70 } else {
71 ASSERT_TRUE(ip_literal.empty());
74 // Add entry to the cache.
75 cache->Set(net::HostCache::Key(hostname, net::ADDRESS_FAMILY_UNSPECIFIED, 0),
76 net::HostCache::Entry(net_error, address_list),
77 base::TimeTicks::Now(),
78 ttl);
81 // Called on IO thread. Adds an entry to the list of known HTTP pipelining
82 // hosts.
83 void AddDummyHttpPipelineFeedbackOnIOThread(
84 net::URLRequestContextGetter* context_getter,
85 const std::string& hostname,
86 int port,
87 net::HttpPipelinedHostCapability capability) {
88 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
89 net::URLRequestContext* context = context_getter->GetURLRequestContext();
90 net::HttpNetworkSession* http_network_session =
91 context->http_transaction_factory()->GetSession();
92 base::WeakPtr<net::HttpServerProperties> http_server_properties =
93 http_network_session->http_server_properties();
94 net::HostPortPair origin(hostname, port);
95 http_server_properties->SetPipelineCapability(origin, capability);
98 // Called on IO thread. Adds an entry to the list of known HTTP pipelining
99 // hosts.
100 void EnableHttpPipeliningOnIOThread(
101 net::URLRequestContextGetter* context_getter, bool enable) {
102 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
103 net::URLRequestContext* context = context_getter->GetURLRequestContext();
104 net::HttpNetworkSession* http_network_session =
105 context->http_transaction_factory()->GetSession();
106 http_network_session->set_http_pipelining_enabled(enable);
109 } // namespace
111 ////////////////////////////////////////////////////////////////////////////////
112 // NetInternalsTest::MessageHandler
113 ////////////////////////////////////////////////////////////////////////////////
115 // Class to handle messages from the renderer needed by certain tests.
116 class NetInternalsTest::MessageHandler : public content::WebUIMessageHandler {
117 public:
118 explicit MessageHandler(NetInternalsTest* net_internals_test);
120 private:
121 virtual void RegisterMessages() OVERRIDE;
123 // Runs NetInternalsTest.callback with the given value.
124 void RunJavascriptCallback(base::Value* value);
126 // Takes a string and provides the corresponding URL from the test server,
127 // which must already have been started.
128 void GetTestServerURL(const base::ListValue* list_value);
130 // Called on UI thread. Adds an entry to the cache for the specified
131 // hostname by posting a task to the IO thread. Takes the host name,
132 // ip address, net error code, and expiration time in days from now
133 // as parameters. If the error code indicates failure, the ip address
134 // must be an empty string.
135 void AddCacheEntry(const base::ListValue* list_value);
137 // Opens the given URL in a new tab.
138 void LoadPage(const base::ListValue* list_value);
140 // Opens a page in a new tab that prerenders the given URL.
141 void PrerenderPage(const base::ListValue* list_value);
143 // Navigates to the prerender in the background tab. This assumes that
144 // there is a "Click()" function in the background tab which will navigate
145 // there, and that the background tab exists at slot 1.
146 void NavigateToPrerender(const base::ListValue* list_value);
148 // Creates an incognito browser. Once creation is complete, passes a
149 // message to the Javascript test harness.
150 void CreateIncognitoBrowser(const base::ListValue* list_value);
152 // Closes an incognito browser created with CreateIncognitoBrowser.
153 void CloseIncognitoBrowser(const base::ListValue* list_value);
155 // Takes in a boolean and enables/disabled HTTP pipelining accordingly.
156 void EnableHttpPipelining(const base::ListValue* list_value);
158 // Called on UI thread. Adds an entry to the list of known HTTP pipelining
159 // hosts.
160 void AddDummyHttpPipelineFeedback(const base::ListValue* list_value);
162 // Creates a simple log with a NetLogLogger, and returns it to the
163 // Javascript callback.
164 void GetNetLogLoggerLog(const base::ListValue* list_value);
166 Browser* browser() { return net_internals_test_->browser(); }
168 NetInternalsTest* net_internals_test_;
169 Browser* incognito_browser_;
171 DISALLOW_COPY_AND_ASSIGN(MessageHandler);
174 NetInternalsTest::MessageHandler::MessageHandler(
175 NetInternalsTest* net_internals_test)
176 : net_internals_test_(net_internals_test),
177 incognito_browser_(NULL) {
180 void NetInternalsTest::MessageHandler::RegisterMessages() {
181 web_ui()->RegisterMessageCallback("getTestServerURL",
182 base::Bind(&NetInternalsTest::MessageHandler::GetTestServerURL,
183 base::Unretained(this)));
184 web_ui()->RegisterMessageCallback("addCacheEntry",
185 base::Bind(&NetInternalsTest::MessageHandler::AddCacheEntry,
186 base::Unretained(this)));
187 web_ui()->RegisterMessageCallback("loadPage",
188 base::Bind(&NetInternalsTest::MessageHandler::LoadPage,
189 base::Unretained(this)));
190 web_ui()->RegisterMessageCallback("prerenderPage",
191 base::Bind(&NetInternalsTest::MessageHandler::PrerenderPage,
192 base::Unretained(this)));
193 web_ui()->RegisterMessageCallback("navigateToPrerender",
194 base::Bind(&NetInternalsTest::MessageHandler::NavigateToPrerender,
195 base::Unretained(this)));
196 web_ui()->RegisterMessageCallback("createIncognitoBrowser",
197 base::Bind(&NetInternalsTest::MessageHandler::CreateIncognitoBrowser,
198 base::Unretained(this)));
199 web_ui()->RegisterMessageCallback("closeIncognitoBrowser",
200 base::Bind(&NetInternalsTest::MessageHandler::CloseIncognitoBrowser,
201 base::Unretained(this)));
202 web_ui()->RegisterMessageCallback("enableHttpPipelining",
203 base::Bind(&NetInternalsTest::MessageHandler::EnableHttpPipelining,
204 base::Unretained(this)));
205 web_ui()->RegisterMessageCallback("addDummyHttpPipelineFeedback",
206 base::Bind(
207 &NetInternalsTest::MessageHandler::AddDummyHttpPipelineFeedback,
208 base::Unretained(this)));
209 web_ui()->RegisterMessageCallback("getNetLogLoggerLog",
210 base::Bind(
211 &NetInternalsTest::MessageHandler::GetNetLogLoggerLog,
212 base::Unretained(this)));
215 void NetInternalsTest::MessageHandler::RunJavascriptCallback(
216 base::Value* value) {
217 web_ui()->CallJavascriptFunction("NetInternalsTest.callback", *value);
220 void NetInternalsTest::MessageHandler::GetTestServerURL(
221 const base::ListValue* list_value) {
222 ASSERT_TRUE(net_internals_test_->StartTestServer());
223 std::string path;
224 ASSERT_TRUE(list_value->GetString(0, &path));
225 GURL url = net_internals_test_->test_server()->GetURL(path);
226 scoped_ptr<base::Value> url_value(base::Value::CreateStringValue(url.spec()));
227 RunJavascriptCallback(url_value.get());
230 void NetInternalsTest::MessageHandler::AddCacheEntry(
231 const base::ListValue* list_value) {
232 std::string hostname;
233 std::string ip_literal;
234 double net_error;
235 double expire_days_from_now;
236 ASSERT_TRUE(list_value->GetString(0, &hostname));
237 ASSERT_TRUE(list_value->GetString(1, &ip_literal));
238 ASSERT_TRUE(list_value->GetDouble(2, &net_error));
239 ASSERT_TRUE(list_value->GetDouble(3, &expire_days_from_now));
240 ASSERT_TRUE(browser());
242 BrowserThread::PostTask(
243 BrowserThread::IO, FROM_HERE,
244 base::Bind(&AddCacheEntryOnIOThread,
245 make_scoped_refptr(browser()->profile()->GetRequestContext()),
246 hostname,
247 ip_literal,
248 static_cast<int>(net_error),
249 static_cast<int>(expire_days_from_now)));
252 void NetInternalsTest::MessageHandler::LoadPage(
253 const base::ListValue* list_value) {
254 std::string url;
255 ASSERT_TRUE(list_value->GetString(0, &url));
256 LOG(WARNING) << "url: [" << url << "]";
257 ui_test_utils::NavigateToURLWithDisposition(
258 browser(),
259 GURL(url),
260 NEW_BACKGROUND_TAB,
261 ui_test_utils::BROWSER_TEST_NONE);
264 void NetInternalsTest::MessageHandler::PrerenderPage(
265 const base::ListValue* list_value) {
266 std::string prerender_url;
267 ASSERT_TRUE(list_value->GetString(0, &prerender_url));
268 GURL loader_url =
269 net_internals_test_->CreatePrerenderLoaderUrl(GURL(prerender_url));
270 ui_test_utils::NavigateToURLWithDisposition(
271 browser(),
272 GURL(loader_url),
273 NEW_BACKGROUND_TAB,
274 ui_test_utils::BROWSER_TEST_NONE);
277 void NetInternalsTest::MessageHandler::NavigateToPrerender(
278 const base::ListValue* list_value) {
279 std::string url;
280 ASSERT_TRUE(list_value->GetString(0, &url));
281 content::RenderViewHost* host =
282 browser()->tab_strip_model()->GetWebContentsAt(1)->GetRenderViewHost();
283 host->ExecuteJavascriptInWebFrame(
284 base::string16(),
285 base::ASCIIToUTF16(base::StringPrintf("Click('%s')", url.c_str())));
288 void NetInternalsTest::MessageHandler::CreateIncognitoBrowser(
289 const base::ListValue* list_value) {
290 ASSERT_FALSE(incognito_browser_);
291 incognito_browser_ = net_internals_test_->CreateIncognitoBrowser();
293 // Tell the test harness that creation is complete.
294 base::StringValue command_value("onIncognitoBrowserCreatedForTest");
295 web_ui()->CallJavascriptFunction("g_browser.receive", command_value);
298 void NetInternalsTest::MessageHandler::CloseIncognitoBrowser(
299 const base::ListValue* list_value) {
300 ASSERT_TRUE(incognito_browser_);
301 incognito_browser_->tab_strip_model()->CloseAllTabs();
302 // Closing all a Browser's tabs will ultimately result in its destruction,
303 // thought it may not have been destroyed yet.
304 incognito_browser_ = NULL;
307 void NetInternalsTest::MessageHandler::EnableHttpPipelining(
308 const base::ListValue* list_value) {
309 bool enable;
310 ASSERT_TRUE(list_value->GetBoolean(0, &enable));
311 BrowserThread::PostTask(
312 BrowserThread::IO, FROM_HERE,
313 base::Bind(&EnableHttpPipeliningOnIOThread,
314 make_scoped_refptr(browser()->profile()->GetRequestContext()),
315 enable));
318 void NetInternalsTest::MessageHandler::AddDummyHttpPipelineFeedback(
319 const base::ListValue* list_value) {
320 std::string hostname;
321 double port;
322 std::string raw_capability;
323 net::HttpPipelinedHostCapability capability;
324 ASSERT_TRUE(list_value->GetString(0, &hostname));
325 ASSERT_TRUE(list_value->GetDouble(1, &port));
326 ASSERT_TRUE(list_value->GetString(2, &raw_capability));
327 if (raw_capability == "capable") {
328 capability = net::PIPELINE_CAPABLE;
329 } else if (raw_capability == "incapable") {
330 capability = net::PIPELINE_INCAPABLE;
331 } else {
332 FAIL() << "Unexpected capability string: " << raw_capability;
334 BrowserThread::PostTask(
335 BrowserThread::IO, FROM_HERE,
336 base::Bind(&AddDummyHttpPipelineFeedbackOnIOThread,
337 make_scoped_refptr(browser()->profile()->GetRequestContext()),
338 hostname,
339 static_cast<int>(port),
340 capability));
343 void NetInternalsTest::MessageHandler::GetNetLogLoggerLog(
344 const base::ListValue* list_value) {
345 base::ScopedTempDir temp_directory;
346 ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
347 base::FilePath temp_file;
348 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_directory.path(),
349 &temp_file));
350 FILE* temp_file_handle = base::OpenFile(temp_file, "w");
351 ASSERT_TRUE(temp_file_handle);
353 scoped_ptr<base::Value> constants(NetInternalsUI::GetConstants());
354 scoped_ptr<net::NetLogLogger> net_log_logger(new net::NetLogLogger(
355 temp_file_handle, *constants));
356 net_log_logger->StartObserving(g_browser_process->net_log());
357 g_browser_process->net_log()->AddGlobalEntry(
358 net::NetLog::TYPE_NETWORK_IP_ADDRESSES_CHANGED);
359 net::BoundNetLog bound_net_log = net::BoundNetLog::Make(
360 g_browser_process->net_log(),
361 net::NetLog::SOURCE_URL_REQUEST);
362 bound_net_log.BeginEvent(net::NetLog::TYPE_REQUEST_ALIVE);
363 net_log_logger->StopObserving();
364 net_log_logger.reset();
366 std::string log_contents;
367 ASSERT_TRUE(base::ReadFileToString(temp_file, &log_contents));
368 ASSERT_GT(log_contents.length(), 0u);
370 scoped_ptr<base::Value> log_contents_value(
371 new base::StringValue(log_contents));
372 RunJavascriptCallback(log_contents_value.get());
375 ////////////////////////////////////////////////////////////////////////////////
376 // NetInternalsTest
377 ////////////////////////////////////////////////////////////////////////////////
379 NetInternalsTest::NetInternalsTest()
380 : test_server_started_(false) {
381 message_handler_.reset(new MessageHandler(this));
384 NetInternalsTest::~NetInternalsTest() {
387 void NetInternalsTest::SetUpCommandLine(CommandLine* command_line) {
388 WebUIBrowserTest::SetUpCommandLine(command_line);
389 // Needed to test the prerender view.
390 command_line->AppendSwitchASCII(switches::kPrerenderMode,
391 switches::kPrerenderModeSwitchValueEnabled);
394 void NetInternalsTest::SetUpOnMainThread() {
395 WebUIBrowserTest::SetUpOnMainThread();
396 // Increase the memory allowed in a prerendered page above normal settings,
397 // as debug builds use more memory and often go over the usual limit.
398 Profile* profile = browser()->profile();
399 prerender::PrerenderManager* prerender_manager =
400 prerender::PrerenderManagerFactory::GetForProfile(profile);
401 prerender_manager->mutable_config().max_bytes = 1000 * 1024 * 1024;
404 content::WebUIMessageHandler* NetInternalsTest::GetMockMessageHandler() {
405 return message_handler_.get();
408 GURL NetInternalsTest::CreatePrerenderLoaderUrl(
409 const GURL& prerender_url) {
410 EXPECT_TRUE(StartTestServer());
411 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
412 replacement_text.push_back(
413 make_pair("REPLACE_WITH_PRERENDER_URL", prerender_url.spec()));
414 std::string replacement_path;
415 EXPECT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
416 "files/prerender/prerender_loader.html",
417 replacement_text,
418 &replacement_path));
419 GURL url_loader = test_server()->GetURL(replacement_path);
420 return url_loader;
423 bool NetInternalsTest::StartTestServer() {
424 if (test_server_started_)
425 return true;
426 test_server_started_ = test_server()->Start();
427 return test_server_started_;