ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / net / predictor_browsertest.cc
blob94d389ff2ac4065dbbc1863dafd942c65d8286ae
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 "base/base64.h"
6 #include "base/command_line.h"
7 #include "base/json/json_string_value_serializer.h"
8 #include "base/prefs/pref_service.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/net/chrome_net_log.h"
11 #include "chrome/browser/net/predictor.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/test/base/in_process_browser_test.h"
16 #include "chrome/test/base/ui_test_utils.h"
17 #include "content/public/common/content_switches.h"
18 #include "content/public/test/test_utils.h"
19 #include "net/base/host_port_pair.h"
20 #include "net/base/net_errors.h"
21 #include "net/base/net_log.h"
22 #include "net/dns/host_resolver_proc.h"
23 #include "net/dns/mock_host_resolver.h"
24 #include "testing/gmock/include/gmock/gmock.h"
26 using content::BrowserThread;
27 using testing::HasSubstr;
29 namespace {
31 const char kBlinkPreconnectFeature[] = "LinkPreconnect";
32 const char kChromiumHostname[] = "chromium.org";
34 // Records a history of all hostnames for which resolving has been requested,
35 // and immediately fails the resolution requests themselves.
36 class HostResolutionRequestRecorder : public net::HostResolverProc {
37 public:
38 HostResolutionRequestRecorder()
39 : HostResolverProc(NULL),
40 is_waiting_for_hostname_(false) {
43 int Resolve(const std::string& host,
44 net::AddressFamily address_family,
45 net::HostResolverFlags host_resolver_flags,
46 net::AddressList* addrlist,
47 int* os_error) override {
48 BrowserThread::PostTask(
49 BrowserThread::UI,
50 FROM_HERE,
51 base::Bind(&HostResolutionRequestRecorder::AddToHistory,
52 base::Unretained(this),
53 host));
54 return net::ERR_NAME_NOT_RESOLVED;
57 bool HasHostBeenRequested(const std::string& hostname) {
58 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
59 return std::find(requested_hostnames_.begin(),
60 requested_hostnames_.end(),
61 hostname) != requested_hostnames_.end();
64 void WaitUntilHostHasBeenRequested(const std::string& hostname) {
65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
66 DCHECK(!is_waiting_for_hostname_);
67 if (HasHostBeenRequested(hostname))
68 return;
69 waiting_for_hostname_ = hostname;
70 is_waiting_for_hostname_ = true;
71 content::RunMessageLoop();
74 private:
75 ~HostResolutionRequestRecorder() override {}
77 void AddToHistory(const std::string& hostname) {
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
79 requested_hostnames_.push_back(hostname);
80 if (is_waiting_for_hostname_ && waiting_for_hostname_ == hostname) {
81 is_waiting_for_hostname_ = false;
82 waiting_for_hostname_.clear();
83 base::MessageLoop::current()->Quit();
87 // The hostname which WaitUntilHostHasBeenRequested is currently waiting for
88 // to be requested.
89 std::string waiting_for_hostname_;
91 // Whether WaitUntilHostHasBeenRequested is waiting for a hostname to be
92 // requested and thus is running a nested message loop.
93 bool is_waiting_for_hostname_;
95 // A list of hostnames for which resolution has already been requested. Only
96 // to be accessed from the UI thread.
97 std::vector<std::string> requested_hostnames_;
99 DISALLOW_COPY_AND_ASSIGN(HostResolutionRequestRecorder);
102 // Watches the NetLog event stream for a connect event to the provided
103 // host:port pair.
104 class ConnectNetLogObserver : public net::NetLog::ThreadSafeObserver {
105 public:
106 explicit ConnectNetLogObserver(const std::string& host_port_pair)
107 : host_port_pair_(host_port_pair) {
110 ~ConnectNetLogObserver() override {
113 void Attach() {
114 g_browser_process->net_log()->AddThreadSafeObserver(
115 this, net::NetLog::LOG_ALL_BUT_BYTES);
118 void Detach() {
119 if (net_log())
120 net_log()->RemoveThreadSafeObserver(this);
123 void WaitForConnect() {
124 run_loop_.Run();
127 private:
128 void OnAddEntry(const net::NetLog::Entry& entry) override {
129 scoped_ptr<base::Value> param_value(entry.ParametersToValue());
130 base::DictionaryValue* param_dict = NULL;
131 std::string group_name;
133 if (entry.source().type == net::NetLog::SOURCE_CONNECT_JOB &&
134 param_value.get() != NULL &&
135 param_value->GetAsDictionary(&param_dict) &&
136 param_dict != NULL &&
137 param_dict->GetString("group_name", &group_name) &&
138 host_port_pair_ == group_name) {
139 run_loop_.Quit();
143 base::RunLoop run_loop_;
144 const std::string host_port_pair_;
147 } // namespace
149 namespace chrome_browser_net {
151 class PredictorBrowserTest : public InProcessBrowserTest {
152 public:
153 PredictorBrowserTest()
154 : startup_url_("http://host1:1"),
155 referring_url_("http://host2:1"),
156 target_url_("http://host3:1"),
157 host_resolution_request_recorder_(new HostResolutionRequestRecorder) {
160 protected:
161 void SetUpInProcessBrowserTestFixture() override {
162 scoped_host_resolver_proc_.reset(new net::ScopedDefaultHostResolverProc(
163 host_resolution_request_recorder_.get()));
164 InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
167 void SetUpCommandLine(base::CommandLine* command_line) override {
168 command_line->AppendSwitch(
169 switches::kEnableExperimentalWebPlatformFeatures);
170 command_line->AppendSwitchASCII(
171 switches::kEnableBlinkFeatures, kBlinkPreconnectFeature);
174 void TearDownInProcessBrowserTestFixture() override {
175 InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
176 scoped_host_resolver_proc_.reset();
179 void LearnAboutInitialNavigation(const GURL& url) {
180 Predictor* predictor = browser()->profile()->GetNetworkPredictor();
181 BrowserThread::PostTask(BrowserThread::IO,
182 FROM_HERE,
183 base::Bind(&Predictor::LearnAboutInitialNavigation,
184 base::Unretained(predictor),
185 url));
186 content::RunAllPendingInMessageLoop(BrowserThread::IO);
189 void LearnFromNavigation(const GURL& referring_url, const GURL& target_url) {
190 Predictor* predictor = browser()->profile()->GetNetworkPredictor();
191 BrowserThread::PostTask(BrowserThread::IO,
192 FROM_HERE,
193 base::Bind(&Predictor::LearnFromNavigation,
194 base::Unretained(predictor),
195 referring_url,
196 target_url));
197 content::RunAllPendingInMessageLoop(BrowserThread::IO);
200 void PrepareFrameSubresources(const GURL& url) {
201 Predictor* predictor = browser()->profile()->GetNetworkPredictor();
202 predictor->PredictFrameSubresources(url, GURL());
205 void GetListFromPrefsAsString(const char* list_path,
206 std::string* value_as_string) const {
207 PrefService* prefs = browser()->profile()->GetPrefs();
208 const base::ListValue* list_value = prefs->GetList(list_path);
209 JSONStringValueSerializer serializer(value_as_string);
210 serializer.Serialize(*list_value);
213 void WaitUntilHostHasBeenRequested(const std::string& hostname) {
214 host_resolution_request_recorder_->WaitUntilHostHasBeenRequested(hostname);
217 const GURL startup_url_;
218 const GURL referring_url_;
219 const GURL target_url_;
221 private:
222 scoped_refptr<HostResolutionRequestRecorder>
223 host_resolution_request_recorder_;
224 scoped_ptr<net::ScopedDefaultHostResolverProc> scoped_host_resolver_proc_;
227 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, PRE_ShutdownStartupCycle) {
228 // Prepare state that will be serialized on this shut-down and read on next
229 // start-up.
230 LearnAboutInitialNavigation(startup_url_);
231 LearnFromNavigation(referring_url_, target_url_);
234 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, ShutdownStartupCycle) {
235 // Make sure that the Preferences file is actually wiped of all DNS prefetch
236 // related data after start-up.
237 std::string cleared_startup_list;
238 std::string cleared_referral_list;
239 GetListFromPrefsAsString(prefs::kDnsPrefetchingStartupList,
240 &cleared_startup_list);
241 GetListFromPrefsAsString(prefs::kDnsPrefetchingHostReferralList,
242 &cleared_referral_list);
244 EXPECT_THAT(cleared_startup_list, Not(HasSubstr(startup_url_.host())));
245 EXPECT_THAT(cleared_referral_list, Not(HasSubstr(referring_url_.host())));
246 EXPECT_THAT(cleared_referral_list, Not(HasSubstr(target_url_.host())));
248 // But also make sure this data has been first loaded into the Predictor, by
249 // inspecting that the Predictor starts making the expected hostname requests.
250 PrepareFrameSubresources(referring_url_);
251 WaitUntilHostHasBeenRequested(startup_url_.host());
252 WaitUntilHostHasBeenRequested(target_url_.host());
255 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, DnsPrefetch) {
256 ASSERT_TRUE(test_server()->Start());
257 ui_test_utils::NavigateToURL(
258 browser(),
259 GURL(test_server()->GetURL("files/predictor/dns_prefetch.html")));
260 WaitUntilHostHasBeenRequested(kChromiumHostname);
263 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, Preconnect) {
264 ASSERT_TRUE(test_server()->Start());
266 // Create a HTML preconnect reference to the local server in the form
267 // <link rel="preconnect" href="http://test-server/">
268 // and navigate to it as a data URI.
269 GURL preconnect_url = test_server()->GetURL("");
270 std::string preconnect_content =
271 "<link rel=\"preconnect\" href=\"" + preconnect_url.spec() + "\">";
272 std::string encoded;
273 base::Base64Encode(preconnect_content, &encoded);
274 std::string data_uri = "data:text/html;base64," + encoded;
276 net::HostPortPair host_port_pair = net::HostPortPair::FromURL(preconnect_url);
277 ConnectNetLogObserver net_log_observer(host_port_pair.ToString());
278 net_log_observer.Attach();
280 ui_test_utils::NavigateToURL(browser(), GURL(data_uri));
282 net_log_observer.WaitForConnect();
283 net_log_observer.Detach();
286 } // namespace chrome_browser_net