Move Webstore URL concepts to //extensions and out
[chromium-blink-merge.git] / chrome / browser / net / sdch_browsertest.cc
blob0401b252bf14fe3be4910e1e5a523c9c39b3f030
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.
5 // End-to-end SDCH tests. Uses the embedded test server to return SDCH
6 // results
8 #include "base/base64.h"
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/command_line.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/path_service.h"
15 #include "base/run_loop.h"
16 #include "base/strings/string_tokenizer.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h"
19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/browsing_data/browsing_data_helper.h"
21 #include "chrome/browser/browsing_data/browsing_data_remover.h"
22 #include "chrome/browser/browsing_data/browsing_data_remover_test_util.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/profiles/profile_manager.h"
25 #include "chrome/browser/ui/browser.h"
26 #include "chrome/browser/ui/browser_tabstrip.h"
27 #include "chrome/browser/ui/browser_window.h"
28 #include "chrome/browser/ui/tabs/tab_strip_model.h"
29 #include "chrome/common/chrome_paths.h"
30 #include "chrome/test/base/in_process_browser_test.h"
31 #include "content/public/browser/browser_thread.h"
32 #include "content/public/common/content_switches.h"
33 #include "content/public/test/browser_test_utils.h"
34 #include "content/public/test/test_utils.h"
35 #include "crypto/sha2.h"
36 #include "net/base/sdch_manager.h"
37 #include "net/http/http_response_headers.h"
38 #include "net/test/embedded_test_server/embedded_test_server.h"
39 #include "net/test/embedded_test_server/http_request.h"
40 #include "net/test/embedded_test_server/http_response.h"
41 #include "net/url_request/url_fetcher.h"
42 #include "net/url_request/url_fetcher_delegate.h"
43 #include "net/url_request/url_request_context.h"
44 #include "net/url_request/url_request_context_getter.h"
45 #include "sdch/open-vcdiff/src/google/vcencoder.h"
46 #include "testing/gtest/include/gtest/gtest.h"
48 #if defined(OS_CHROMEOS)
49 #include "chromeos/chromeos_switches.h"
50 #endif
52 namespace {
54 typedef std::vector<net::test_server::HttpRequest> RequestVector;
55 typedef std::map<std::string, std::string> HttpRequestHeaderMap;
57 // Credit Alfred, Lord Tennyson
58 static const char kSampleData[] = "<html><body><pre>"
59 "There lies the port; the vessel puffs her sail:\n"
60 "There gloom the dark, broad seas. My mariners,\n"
61 "Souls that have toil'd, and wrought, and thought with me—\n"
62 "That ever with a frolic welcome took\n"
63 "The thunder and the sunshine, and opposed\n"
64 "Free hearts, free foreheads—you and I are old;\n"
65 "Old age hath yet his honour and his toil;\n"
66 "Death closes all: but something ere the end,\n"
67 "Some work of noble note, may yet be done,\n"
68 "Not unbecoming men that strove with Gods.\n"
69 "The lights begin to twinkle from the rocks:\n"
70 "The long day wanes: the slow moon climbs: the deep\n"
71 "Moans round with many voices. Come, my friends,\n"
72 "'T is not too late to seek a newer world.\n"
73 "Push off, and sitting well in order smite\n"
74 "The sounding furrows; for my purpose holds\n"
75 "To sail beyond the sunset, and the baths\n"
76 "Of all the western stars, until I die.\n"
77 "It may be that the gulfs will wash us down:\n"
78 "It may be we shall touch the Happy Isles,\n"
79 "And see the great Achilles, whom we knew.\n"
80 "Tho' much is taken, much abides; and tho'\n"
81 "We are not now that strength which in old days\n"
82 "Moved earth and heaven, that which we are, we are;\n"
83 "One equal temper of heroic hearts,\n"
84 "Made weak by time and fate, but strong in will\n"
85 "To strive, to seek, to find, and not to yield.\n"
86 "</pre></body></html>";
88 // Random selection of lines from above, to allow some encoding, but
89 // not a trivial encoding.
90 static const char kDictionaryContents[] =
91 "The thunder and the sunshine, and opposed\n"
92 "To sail beyond the sunset, and the baths\n"
93 "Of all the western stars, until I die.\n"
94 "Made weak by time and fate, but strong in will\n"
95 "Moans round with many voices. Come, my friends,\n"
96 "The lights begin to twinkle from the rocks:";
98 static const char kDictionaryURLPath[] = "/dict";
99 static const char kDataURLPath[] = "/data";
101 // Scans in a case-insensitive way for |header| in |map|,
102 // returning true if found and setting |*value| to the value
103 // of that header. Does not handle multiple instances of the same
104 // header.
105 bool GetRequestHeader(const HttpRequestHeaderMap& map,
106 const char* header,
107 std::string* value) {
108 for (HttpRequestHeaderMap::const_iterator it = map.begin();
109 it != map.end(); ++it) {
110 if (!base::strcasecmp(it->first.c_str(), header)) {
111 *value = it->second;
112 return true;
115 return false;
118 // Do a URL-safe base64 encoding. See the SDCH spec "Dictionary Identifier"
119 // section, and RFC 3548 section 4.
120 void SafeBase64Encode(const std::string& input_value, std::string* output) {
121 DCHECK(output);
122 base::Base64Encode(input_value, output);
123 std::replace(output->begin(), output->end(), '+', '-');
124 std::replace(output->begin(), output->end(), '/', '_');
127 // Class that bundles responses for an EmbeddedTestServer().
128 // Dictionary is at <domain>/dict, data at <domain>/data.
129 // The data is sent SDCH encoded if that's allowed by protoocol.
130 class SdchResponseHandler {
131 public:
132 // Do initial preparation so that SDCH requests can be handled.
133 explicit SdchResponseHandler(std::string domain)
134 : cache_sdch_response_(false),
135 weak_ptr_factory_(this) {
136 // Dictionary
137 sdch_dictionary_contents_ = "Domain: ";
138 sdch_dictionary_contents_ += domain;
139 sdch_dictionary_contents_ += "\n\n";
140 sdch_dictionary_contents_ += kDictionaryContents;
142 // Dictionary hash for client and server.
143 char binary_hash[32];
144 crypto::SHA256HashString(sdch_dictionary_contents_, binary_hash,
145 sizeof(binary_hash));
146 SafeBase64Encode(std::string(&binary_hash[0], 6), &dictionary_client_hash_);
147 SafeBase64Encode(std::string(&binary_hash[6], 6), &dictionary_server_hash_);
149 // Encoded response.
150 open_vcdiff::HashedDictionary vcdiff_dictionary(
151 kDictionaryContents, strlen(kDictionaryContents));
152 bool result = vcdiff_dictionary.Init();
153 DCHECK(result);
154 open_vcdiff::VCDiffStreamingEncoder encoder(&vcdiff_dictionary, 0, false);
155 encoded_data_ = dictionary_server_hash_;
156 encoded_data_ += '\0';
157 result = encoder.StartEncoding(&encoded_data_);
158 DCHECK(result);
159 result = encoder.EncodeChunk(
160 kSampleData, strlen(kSampleData), &encoded_data_);
161 DCHECK(result);
162 result = encoder.FinishEncoding(&encoded_data_);
163 DCHECK(result);
166 static bool ClientIsAdvertisingSdchEncoding(const HttpRequestHeaderMap& map) {
167 std::string value;
168 if (!GetRequestHeader(map, "accept-encoding", &value))
169 return false;
170 base::StringTokenizer tokenizer(value, " ,");
171 while (tokenizer.GetNext()) {
172 if (base::strcasecmp(tokenizer.token().c_str(), "sdch"))
173 return true;
175 return false;
178 bool ShouldRespondWithSdchEncoding(const HttpRequestHeaderMap& map) {
179 std::string value;
180 if (!GetRequestHeader(map, "avail-dictionary", &value))
181 return false;
182 return value == dictionary_client_hash_;
185 scoped_ptr<net::test_server::HttpResponse> HandleRequest(
186 const net::test_server::HttpRequest& request) {
187 request_vector_.push_back(request);
189 scoped_ptr<net::test_server::BasicHttpResponse> response(
190 new net::test_server::BasicHttpResponse);
191 if (request.relative_url == kDataURLPath) {
192 if (ShouldRespondWithSdchEncoding(request.headers)) {
193 // Note that chrome doesn't advertise accepting SDCH encoding
194 // for POSTs (because the meta-refresh hack would break a POST),
195 // but that's not for the server to enforce.
196 DCHECK_NE(encoded_data_, "");
197 response->set_content_type("text/html");
198 response->set_content(encoded_data_);
199 response->AddCustomHeader("Content-Encoding", "sdch");
200 // We allow tests to set caching on the sdch response,
201 // so that we can force an encoded response with no
202 // dictionary.
203 if (cache_sdch_response_)
204 response->AddCustomHeader("Cache-Control", "max-age=3600");
205 else
206 response->AddCustomHeader("Cache-Control", "no-store");
207 } else {
208 response->set_content_type("text/plain");
209 response->set_content(kSampleData);
210 if (ClientIsAdvertisingSdchEncoding(request.headers))
211 response->AddCustomHeader("Get-Dictionary", kDictionaryURLPath);
212 // We never cache the plain data response, to make it
213 // easy to refresh after we get the dictionary.
214 response->AddCustomHeader("Cache-Control", "no-store");
216 } else {
217 DCHECK_EQ(request.relative_url, kDictionaryURLPath);
218 DCHECK_NE(sdch_dictionary_contents_, "");
219 response->set_content_type("application/x-sdch-dictionary");
220 response->set_content(sdch_dictionary_contents_);
222 std::vector<base::Closure> callbacks;
223 callbacks.swap(callback_vector_);
224 for (std::vector<base::Closure>::iterator it = callbacks.begin();
225 it != callbacks.end(); ++it) {
226 it->Run();
228 return response.PassAs<net::test_server::HttpResponse>();
231 void WaitAndGetRequestVector(int num_requests,
232 base::Closure callback,
233 RequestVector* v) {
234 DCHECK_LT(0, num_requests);
235 if (static_cast<size_t>(num_requests) > request_vector_.size()) {
236 callback_vector_.push_back(
237 base::Bind(&SdchResponseHandler::WaitAndGetRequestVector,
238 weak_ptr_factory_.GetWeakPtr(), num_requests,
239 callback, v));
240 return;
242 *v = request_vector_;
243 content::BrowserThread::PostTask(
244 content::BrowserThread::UI, FROM_HERE, callback);
247 void set_cache_sdch_response(bool cache_sdch_response) {
248 cache_sdch_response_ = cache_sdch_response;
251 private:
252 bool cache_sdch_response_;
253 std::string encoded_data_;
254 std::string sdch_dictionary_contents_;
255 std::string dictionary_client_hash_;
256 std::string dictionary_server_hash_;
257 RequestVector request_vector_;
258 std::vector<base::Closure> callback_vector_;
259 base::WeakPtrFactory<SdchResponseHandler> weak_ptr_factory_;
262 class SdchBrowserTest : public InProcessBrowserTest, net::URLFetcherDelegate {
263 public:
264 static const char kTestHost[];
266 SdchBrowserTest()
267 : response_handler_(kTestHost),
268 url_request_context_getter_(NULL),
269 url_fetch_complete_(false),
270 waiting_(false) {}
272 // Helper functions for fetching data.
274 void FetchUrlDetailed(GURL url, net::URLRequestContextGetter* getter) {
275 url_fetch_complete_ = false;
276 fetcher_.reset(net::URLFetcher::Create(url, net::URLFetcher::GET, this));
277 fetcher_->SetRequestContext(getter);
278 fetcher_->Start();
279 if (!url_fetch_complete_) {
280 waiting_ = true;
281 content::RunMessageLoop();
282 waiting_ = false;
284 CHECK(url_fetch_complete_);
287 void FetchUrl(GURL url) {
288 FetchUrlDetailed(url, url_request_context_getter_.get());
291 const net::URLRequestStatus& FetcherStatus() const {
292 return fetcher_->GetStatus();
295 int FetcherResponseCode() const {
296 return (fetcher_->GetStatus().status() == net::URLRequestStatus::SUCCESS ?
297 fetcher_->GetResponseCode() : 0);
300 const net::HttpResponseHeaders* FetcherResponseHeaders() const {
301 return (fetcher_->GetStatus().status() == net::URLRequestStatus::SUCCESS ?
302 fetcher_->GetResponseHeaders() : NULL);
305 std::string FetcherResponseContents() const {
306 std::string contents;
307 if (fetcher_->GetStatus().status() == net::URLRequestStatus::SUCCESS)
308 CHECK(fetcher_->GetResponseAsString(&contents));
309 return contents;
312 // Get the data from the server. Return value is success/failure of the
313 // data operation, |*sdch_encoding_used| indicates whether or not the
314 // data was retrieved with sdch encoding.
315 // This is done through FetchUrl(), so the various helper functions
316 // will have valid status if it returns successfully.
317 bool GetDataDetailed(net::URLRequestContextGetter* getter,
318 bool* sdch_encoding_used) {
319 FetchUrlDetailed(
320 GURL(base::StringPrintf(
321 "http://%s:%d%s", kTestHost, test_server_port(), kDataURLPath)),
322 getter);
323 EXPECT_EQ(net::URLRequestStatus::SUCCESS, FetcherStatus().status())
324 << "Error code is " << FetcherStatus().error();
325 EXPECT_EQ(200, FetcherResponseCode());
326 EXPECT_EQ(kSampleData, FetcherResponseContents());
328 if (net::URLRequestStatus::SUCCESS != FetcherStatus().status() ||
329 200 != FetcherResponseCode()) {
330 *sdch_encoding_used = false;
331 return false;
334 *sdch_encoding_used =
335 FetcherResponseHeaders()->HasHeaderValue("Content-Encoding", "sdch");
337 if (FetcherResponseContents() != kSampleData)
338 return false;
340 return true;
343 bool GetData(bool* sdch_encoding_used) {
344 return GetDataDetailed(url_request_context_getter_.get(),
345 sdch_encoding_used);
348 // Client information and control.
350 int GetNumberOfDictionaryFetches(Profile* profile) {
351 int fetches = -1;
352 base::RunLoop run_loop;
353 content::BrowserThread::PostTaskAndReply(
354 content::BrowserThread::IO, FROM_HERE,
355 base::Bind(&SdchBrowserTest::GetNumberOfDictionaryFetchesOnIOThread,
356 base::Unretained(profile->GetRequestContext()),
357 &fetches),
358 run_loop.QuitClosure());
359 run_loop.Run();
360 DCHECK_NE(-1, fetches);
361 return fetches;
364 void BrowsingDataRemoveAndWait(int remove_mask) {
365 BrowsingDataRemover* remover = BrowsingDataRemover::CreateForPeriod(
366 browser()->profile(), BrowsingDataRemover::LAST_HOUR);
367 BrowsingDataRemoverCompletionObserver completion_observer(remover);
368 remover->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB);
369 completion_observer.BlockUntilCompletion();
372 // Something of a cheat; nuke the dictionaries off the SdchManager without
373 // touching the cache (which browsing data remover would do).
374 void NukeSdchDictionaries() {
375 base::RunLoop run_loop;
376 content::BrowserThread::PostTaskAndReply(
377 content::BrowserThread::IO, FROM_HERE,
378 base::Bind(&SdchBrowserTest::NukeSdchDictionariesOnIOThread,
379 url_request_context_getter_),
380 run_loop.QuitClosure());
381 run_loop.Run();
384 // Create a second browser based on a second profile to work within
385 // multi-profile.
386 bool SetupSecondBrowser() {
387 base::FilePath user_data_dir;
388 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
390 if (!second_profile_data_dir_.CreateUniqueTempDirUnderPath(user_data_dir))
391 return false;
393 second_profile_ = g_browser_process->profile_manager()->GetProfile(
394 second_profile_data_dir_.path());
395 if (!second_profile_) return false;
397 second_browser_ = new Browser(Browser::CreateParams(
398 second_profile_, browser()->host_desktop_type()));
399 if (!second_browser_) return false;
401 chrome::AddSelectedTabWithURL(second_browser_,
402 GURL(url::kAboutBlankURL),
403 content::PAGE_TRANSITION_AUTO_TOPLEVEL);
404 content::WaitForLoadStop(
405 second_browser_->tab_strip_model()->GetActiveWebContents());
406 second_browser_->window()->Show();
408 return true;
411 Browser* second_browser() { return second_browser_; }
413 // Server information and control.
415 void WaitAndGetTestVector(int num_requests, RequestVector* result) {
416 base::RunLoop run_loop;
417 content::BrowserThread::PostTask(
418 content::BrowserThread::IO, FROM_HERE,
419 base::Bind(&SdchResponseHandler::WaitAndGetRequestVector,
420 base::Unretained(&response_handler_),
421 num_requests,
422 run_loop.QuitClosure(),
423 result));
424 run_loop.Run();
427 int test_server_port() { return test_server_.port(); }
429 void SetSdchCacheability(bool cache_sdch_response) {
430 base::RunLoop run_loop;
431 content::BrowserThread::PostTaskAndReply(
432 content::BrowserThread::IO, FROM_HERE,
433 base::Bind(&SdchResponseHandler::set_cache_sdch_response,
434 base::Unretained(&response_handler_),
435 cache_sdch_response),
436 run_loop.QuitClosure());
437 run_loop.Run();
440 // Helper function for common test pattern.
442 // This function gets the data, confirms that the initial sending of the
443 // data included a dictionary advertisement, that that advertisement
444 // resulted in queueing a dictionary fetch, forces that fetch to
445 // go through, and confirms that a follow-on data load uses SDCH
446 // encoding. Returns true if the entire sequence of events occurred.
447 bool ForceSdchDictionaryLoad(Browser* browser) {
448 bool sdch_encoding_used = true;
449 bool data_gotten = GetDataDetailed(
450 browser->profile()->GetRequestContext(), &sdch_encoding_used);
451 EXPECT_TRUE(data_gotten);
452 if (!data_gotten) return false;
453 EXPECT_FALSE(sdch_encoding_used);
455 // Confirm that we were told to get the dictionary
456 const net::HttpResponseHeaders* headers = FetcherResponseHeaders();
457 std::string value;
458 bool have_dict_header =
459 headers->EnumerateHeader(NULL, "Get-Dictionary", &value);
460 EXPECT_TRUE(have_dict_header);
461 if (!have_dict_header) return false;
463 // If the above didn't result in a dictionary fetch being queued, the
464 // rest of the test will time out. Avoid that.
465 int num_fetches = GetNumberOfDictionaryFetches(browser->profile());
466 EXPECT_EQ(1, num_fetches);
467 if (1 != num_fetches) return false;
469 // Wait until the dictionary fetch actually happens.
470 RequestVector request_vector;
471 WaitAndGetTestVector(2, &request_vector);
472 EXPECT_EQ(request_vector[1].relative_url, kDictionaryURLPath);
473 if (request_vector[1].relative_url != kDictionaryURLPath) return false;
475 // Do a round trip to the server ignoring the encoding, presuming
476 // that if we've gotten data to this thread, the dictionary's made
477 // it into the SdchManager.
478 data_gotten = GetDataDetailed(
479 browser->profile()->GetRequestContext(), &sdch_encoding_used);
480 EXPECT_TRUE(data_gotten);
481 if (!data_gotten) return false;
483 // Now data fetches should be SDCH encoded.
484 sdch_encoding_used = false;
485 data_gotten = GetDataDetailed(
486 browser->profile()->GetRequestContext(), &sdch_encoding_used);
487 EXPECT_TRUE(data_gotten);
488 EXPECT_TRUE(sdch_encoding_used);
490 if (!data_gotten || !sdch_encoding_used) return false;
492 // Confirm the request vector looks at this point as expected.
493 WaitAndGetTestVector(4, &request_vector);
494 EXPECT_EQ(4u, request_vector.size());
495 EXPECT_EQ(request_vector[2].relative_url, kDataURLPath);
496 EXPECT_EQ(request_vector[3].relative_url, kDataURLPath);
497 return (4u == request_vector.size() &&
498 request_vector[2].relative_url == kDataURLPath &&
499 request_vector[3].relative_url == kDataURLPath);
502 private:
503 static void NukeSdchDictionariesOnIOThread(
504 net::URLRequestContextGetter* context_getter) {
505 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
506 net::SdchManager* sdch_manager =
507 context_getter->GetURLRequestContext()->sdch_manager();
508 DCHECK(sdch_manager);
509 sdch_manager->ClearData();
512 static void GetNumberOfDictionaryFetchesOnIOThread(
513 net::URLRequestContextGetter* url_request_context_getter,
514 int* result) {
515 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
516 net::SdchManager* sdch_manager =
517 url_request_context_getter->GetURLRequestContext()->sdch_manager();
518 DCHECK(sdch_manager);
519 *result = sdch_manager->GetFetchesCountForTesting();
522 // InProcessBrowserTest
523 virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE {
524 command_line->AppendSwitchASCII(
525 switches::kHostResolverRules,
526 "MAP " + std::string(kTestHost) + " 127.0.0.1");
527 #if defined(OS_CHROMEOS)
528 command_line->AppendSwitch(
529 chromeos::switches::kIgnoreUserProfileMappingForTests);
530 #endif
533 virtual void SetUpOnMainThread() OVERRIDE {
534 test_server_.RegisterRequestHandler(
535 base::Bind(&SdchResponseHandler::HandleRequest,
536 base::Unretained(&response_handler_)));
537 CHECK(test_server_.InitializeAndWaitUntilReady());
538 url_request_context_getter_ = browser()->profile()->GetRequestContext();
541 virtual void TearDownOnMainThread() OVERRIDE {
542 CHECK(test_server_.ShutdownAndWaitUntilComplete());
545 // URLFetcherDelegate
546 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE {
547 url_fetch_complete_ = true;
548 if (waiting_)
549 base::MessageLoopForUI::current()->Quit();
552 SdchResponseHandler response_handler_;
553 net::test_server::EmbeddedTestServer test_server_;
554 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
555 scoped_ptr<net::URLFetcher> fetcher_;
556 bool url_fetch_complete_;
557 bool waiting_;
558 base::ScopedTempDir second_profile_data_dir_;
559 Profile* second_profile_;
560 Browser* second_browser_;
563 const char SdchBrowserTest::kTestHost[] = "our.test.host.com";
565 // Confirm that after getting a dictionary, calling the browsing
566 // data remover renders it unusable. Also (in calling
567 // ForceSdchDictionaryLoad()) servers as a smoke test for SDCH.
568 IN_PROC_BROWSER_TEST_F(SdchBrowserTest, BrowsingDataRemover) {
569 ASSERT_TRUE(ForceSdchDictionaryLoad(browser()));
571 // Confirm browsing data remover without removing the cache leaves
572 // SDCH alone.
573 BrowsingDataRemoveAndWait(BrowsingDataRemover::REMOVE_ALL &
574 ~BrowsingDataRemover::REMOVE_CACHE);
575 bool sdch_encoding_used = false;
576 ASSERT_TRUE(GetData(&sdch_encoding_used));
577 EXPECT_TRUE(sdch_encoding_used);
579 // Confirm browsing data remover removing the cache clears SDCH state.
580 BrowsingDataRemoveAndWait(BrowsingDataRemover::REMOVE_CACHE);
581 sdch_encoding_used = false;
582 ASSERT_TRUE(GetData(&sdch_encoding_used));
583 EXPECT_FALSE(sdch_encoding_used);
586 // Confirm dictionaries not visible in other profiles.
587 IN_PROC_BROWSER_TEST_F(SdchBrowserTest, Isolation) {
588 ASSERT_TRUE(ForceSdchDictionaryLoad(browser()));
589 ASSERT_TRUE(SetupSecondBrowser());
591 // Data fetches from incognito or separate profiles should not be SDCH
592 // encoded.
593 bool sdch_encoding_used = true;
594 Browser* incognito_browser = CreateIncognitoBrowser();
595 EXPECT_TRUE(GetDataDetailed(
596 incognito_browser->profile()->GetRequestContext(),
597 &sdch_encoding_used));
598 EXPECT_FALSE(sdch_encoding_used);
600 sdch_encoding_used = true;
601 EXPECT_TRUE(GetDataDetailed(
602 second_browser()->profile()->GetRequestContext(), &sdch_encoding_used));
603 EXPECT_FALSE(sdch_encoding_used);
606 // Confirm a dictionary loaded in incognito isn't visible in the main profile.
607 IN_PROC_BROWSER_TEST_F(SdchBrowserTest, ReverseIsolation) {
608 Browser* incognito_browser = CreateIncognitoBrowser();
609 ASSERT_TRUE(ForceSdchDictionaryLoad(incognito_browser));
611 // Data fetches on main browser should not be SDCH encoded.
612 bool sdch_encoding_used = true;
613 ASSERT_TRUE(GetData(&sdch_encoding_used));
614 EXPECT_FALSE(sdch_encoding_used);
617 } // namespace