OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 #include "chrome/test/live_sync/live_sync_test.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "base/basictypes.h" | |
10 #include "base/command_line.h" | |
11 #include "base/message_loop.h" | |
12 #include "base/path_service.h" | |
13 #include "base/stringprintf.h" | |
14 #include "base/string_util.h" | |
15 #include "base/synchronization/waitable_event.h" | |
16 #include "base/task.h" | |
17 #include "base/test/test_timeouts.h" | |
18 #include "base/threading/platform_thread.h" | |
19 #include "base/utf_string_conversions.h" | |
20 #include "base/values.h" | |
21 #include "chrome/browser/password_manager/encryptor.h" | |
22 #include "chrome/browser/profiles/profile.h" | |
23 #include "chrome/browser/profiles/profile_manager.h" | |
24 #include "chrome/browser/sync/notifier/p2p_notifier.h" | |
25 #include "chrome/browser/sync/profile_sync_service_harness.h" | |
26 #include "chrome/browser/ui/browser.h" | |
27 #include "chrome/browser/ui/browser_list.h" | |
28 #include "chrome/common/chrome_paths.h" | |
29 #include "chrome/common/chrome_switches.h" | |
30 #include "chrome/test/base/testing_browser_process.h" | |
31 #include "chrome/test/base/ui_test_utils.h" | |
32 #include "chrome/test/live_sync/sync_datatype_helper.h" | |
33 #include "content/browser/browser_thread.h" | |
34 #include "content/browser/tab_contents/tab_contents.h" | |
35 #include "content/common/url_fetcher.h" | |
36 #include "content/test/test_url_fetcher_factory.h" | |
37 #include "googleurl/src/gurl.h" | |
38 #include "net/base/escape.h" | |
39 #include "net/base/network_change_notifier.h" | |
40 #include "net/proxy/proxy_config.h" | |
41 #include "net/proxy/proxy_config_service_fixed.h" | |
42 #include "net/proxy/proxy_service.h" | |
43 #include "net/test/test_server.h" | |
44 #include "net/url_request/url_request_context.h" | |
45 #include "net/url_request/url_request_context_getter.h" | |
46 #include "net/url_request/url_request_status.h" | |
47 | |
48 namespace switches { | |
49 const char kPasswordFileForTest[] = "password-file-for-test"; | |
50 const char kSyncUserForTest[] = "sync-user-for-test"; | |
51 const char kSyncPasswordForTest[] = "sync-password-for-test"; | |
52 const char kSyncServerCommandLine[] = "sync-server-command-line"; | |
53 } | |
54 | |
55 namespace { | |
56 // The URLs for different calls in the Google Accounts programmatic login API. | |
57 const char kClientLoginUrl[] = "https://www.google.com/accounts/ClientLogin"; | |
58 const char kGetUserInfoUrl[] = "https://www.google.com/accounts/GetUserInfo"; | |
59 const char kIssueAuthTokenUrl[] = | |
60 "https://www.google.com/accounts/IssueAuthToken"; | |
61 const char kSearchDomainCheckUrl[] = | |
62 "https://www.google.com/searchdomaincheck?format=domain&type=chrome"; | |
63 } | |
64 | |
65 // Helper class that checks whether a sync test server is running or not. | |
66 class SyncServerStatusChecker : public URLFetcher::Delegate { | |
67 public: | |
68 SyncServerStatusChecker() : running_(false) {} | |
69 | |
70 virtual void OnURLFetchComplete(const URLFetcher* source, | |
71 const GURL& url, | |
72 const net::URLRequestStatus& status, | |
73 int response_code, | |
74 const net::ResponseCookies& cookies, | |
75 const std::string& data) { | |
76 running_ = (status.status() == net::URLRequestStatus::SUCCESS && | |
77 response_code == 200 && data.find("ok") == 0); | |
78 MessageLoop::current()->Quit(); | |
79 } | |
80 | |
81 bool running() const { return running_; } | |
82 | |
83 private: | |
84 bool running_; | |
85 }; | |
86 | |
87 class SetProxyConfigTask : public Task { | |
88 public: | |
89 SetProxyConfigTask(base::WaitableEvent* done, | |
90 net::URLRequestContextGetter* url_request_context_getter, | |
91 const net::ProxyConfig& proxy_config) | |
92 : done_(done), | |
93 url_request_context_getter_(url_request_context_getter), | |
94 proxy_config_(proxy_config) { | |
95 } | |
96 | |
97 void Run() { | |
98 net::ProxyService* proxy_service = | |
99 url_request_context_getter_->GetURLRequestContext()->proxy_service(); | |
100 proxy_service->ResetConfigService( | |
101 new net::ProxyConfigServiceFixed(proxy_config_)); | |
102 done_->Signal(); | |
103 } | |
104 | |
105 private: | |
106 base::WaitableEvent* done_; | |
107 net::URLRequestContextGetter* url_request_context_getter_; | |
108 net::ProxyConfig proxy_config_; | |
109 }; | |
110 | |
111 LiveSyncTest::LiveSyncTest(TestType test_type) | |
112 : sync_server_(net::TestServer::TYPE_SYNC, FilePath()), | |
113 test_type_(test_type), | |
114 server_type_(SERVER_TYPE_UNDECIDED), | |
115 num_clients_(-1), | |
116 use_verifier_(true), | |
117 test_server_handle_(base::kNullProcessHandle) { | |
118 InProcessBrowserTest::set_show_window(true); | |
119 sync_datatype_helper::AssociateWithTest(this); | |
120 switch (test_type_) { | |
121 case SINGLE_CLIENT: { | |
122 num_clients_ = 1; | |
123 break; | |
124 } | |
125 case TWO_CLIENT: { | |
126 num_clients_ = 2; | |
127 break; | |
128 } | |
129 case MULTIPLE_CLIENT: { | |
130 num_clients_ = 3; | |
131 break; | |
132 } | |
133 case MANY_CLIENT: { | |
134 num_clients_ = 10; | |
135 break; | |
136 } | |
137 } | |
138 } | |
139 | |
140 LiveSyncTest::~LiveSyncTest() {} | |
141 | |
142 void LiveSyncTest::SetUp() { | |
143 CommandLine* cl = CommandLine::ForCurrentProcess(); | |
144 if (cl->HasSwitch(switches::kPasswordFileForTest)) { | |
145 ReadPasswordFile(); | |
146 } else if (cl->HasSwitch(switches::kSyncUserForTest) && | |
147 cl->HasSwitch(switches::kSyncPasswordForTest)) { | |
148 username_ = cl->GetSwitchValueASCII(switches::kSyncUserForTest); | |
149 password_ = cl->GetSwitchValueASCII(switches::kSyncPasswordForTest); | |
150 } else { | |
151 SetupMockGaiaResponses(); | |
152 } | |
153 | |
154 if (!cl->HasSwitch(switches::kSyncServiceURL) && | |
155 !cl->HasSwitch(switches::kSyncServerCommandLine)) { | |
156 // If neither a sync server URL nor a sync server command line is | |
157 // provided, start up a local python sync test server and point Chrome | |
158 // to its URL. This is the most common configuration, and the only | |
159 // one that makes sense for most developers. | |
160 server_type_ = LOCAL_PYTHON_SERVER; | |
161 } else if (cl->HasSwitch(switches::kSyncServiceURL) && | |
162 cl->HasSwitch(switches::kSyncServerCommandLine)) { | |
163 // If a sync server URL and a sync server command line are provided, | |
164 // start up a local sync server by running the command line. Chrome | |
165 // will connect to the server at the URL that was provided. | |
166 server_type_ = LOCAL_LIVE_SERVER; | |
167 } else if (cl->HasSwitch(switches::kSyncServiceURL) && | |
168 !cl->HasSwitch(switches::kSyncServerCommandLine)) { | |
169 // If a sync server URL is provided, but not a server command line, | |
170 // it is assumed that the server is already running. Chrome will | |
171 // automatically connect to it at the URL provided. There is nothing | |
172 // to do here. | |
173 server_type_ = EXTERNAL_LIVE_SERVER; | |
174 } else { | |
175 // If a sync server command line is provided, but not a server URL, | |
176 // we flag an error. | |
177 LOG(FATAL) << "Can't figure out how to run a server."; | |
178 } | |
179 | |
180 if (username_.empty() || password_.empty()) | |
181 LOG(FATAL) << "Cannot run sync tests without GAIA credentials."; | |
182 | |
183 // Mock the Mac Keychain service. The real Keychain can block on user input. | |
184 #if defined(OS_MACOSX) | |
185 Encryptor::UseMockKeychain(true); | |
186 #endif | |
187 | |
188 // Yield control back to the InProcessBrowserTest framework. | |
189 InProcessBrowserTest::SetUp(); | |
190 } | |
191 | |
192 void LiveSyncTest::TearDown() { | |
193 // Allow the InProcessBrowserTest framework to perform its tear down. | |
194 InProcessBrowserTest::TearDown(); | |
195 | |
196 // Stop the local python test server. This is a no-op if one wasn't started. | |
197 TearDownLocalPythonTestServer(); | |
198 | |
199 // Stop the local sync test server. This is a no-op if one wasn't started. | |
200 TearDownLocalTestServer(); | |
201 } | |
202 | |
203 void LiveSyncTest::SetUpCommandLine(CommandLine* cl) { | |
204 AddTestSwitches(cl); | |
205 AddOptionalTypesToCommandLine(cl); | |
206 } | |
207 | |
208 void LiveSyncTest::AddTestSwitches(CommandLine* cl) { | |
209 // TODO(rsimha): Until we implement a fake Tango server against which tests | |
210 // can run, we need to set the --sync-notification-method to "p2p". | |
211 if (!cl->HasSwitch(switches::kSyncNotificationMethod)) | |
212 cl->AppendSwitchASCII(switches::kSyncNotificationMethod, "p2p"); | |
213 | |
214 // Disable non-essential access of external network resources. | |
215 if (!cl->HasSwitch(switches::kDisableBackgroundNetworking)) | |
216 cl->AppendSwitch(switches::kDisableBackgroundNetworking); | |
217 } | |
218 | |
219 void LiveSyncTest::AddOptionalTypesToCommandLine(CommandLine* cl) { | |
220 // TODO(sync): Remove this once sessions sync is enabled by default. | |
221 if (!cl->HasSwitch(switches::kEnableSyncSessions)) | |
222 cl->AppendSwitch(switches::kEnableSyncSessions); | |
223 } | |
224 | |
225 // static | |
226 Profile* LiveSyncTest::MakeProfile(const FilePath::StringType name) { | |
227 FilePath path; | |
228 PathService::Get(chrome::DIR_USER_DATA, &path); | |
229 path = path.Append(name); | |
230 | |
231 if (!file_util::PathExists(path)) | |
232 CHECK(file_util::CreateDirectory(path)); | |
233 | |
234 return Profile::CreateProfile(path); | |
235 } | |
236 | |
237 Profile* LiveSyncTest::GetProfile(int index) { | |
238 if (profiles_.empty()) | |
239 LOG(FATAL) << "SetupClients() has not yet been called."; | |
240 if (index < 0 || index >= static_cast<int>(profiles_.size())) | |
241 LOG(FATAL) << "GetProfile(): Index is out of bounds."; | |
242 return profiles_[index]; | |
243 } | |
244 | |
245 Browser* LiveSyncTest::GetBrowser(int index) { | |
246 if (browsers_.empty()) | |
247 LOG(FATAL) << "SetupClients() has not yet been called."; | |
248 if (index < 0 || index >= static_cast<int>(browsers_.size())) | |
249 LOG(FATAL) << "GetBrowser(): Index is out of bounds."; | |
250 return browsers_[index]; | |
251 } | |
252 | |
253 ProfileSyncServiceHarness* LiveSyncTest::GetClient(int index) { | |
254 if (clients_.empty()) | |
255 LOG(FATAL) << "SetupClients() has not yet been called."; | |
256 if (index < 0 || index >= static_cast<int>(clients_.size())) | |
257 LOG(FATAL) << "GetClient(): Index is out of bounds."; | |
258 return clients_[index]; | |
259 } | |
260 | |
261 Profile* LiveSyncTest::verifier() { | |
262 if (verifier_.get() == NULL) | |
263 LOG(FATAL) << "SetupClients() has not yet been called."; | |
264 return verifier_.get(); | |
265 } | |
266 | |
267 void LiveSyncTest::DisableVerifier() { | |
268 use_verifier_ = false; | |
269 } | |
270 | |
271 bool LiveSyncTest::SetupClients() { | |
272 if (num_clients_ <= 0) | |
273 LOG(FATAL) << "num_clients_ incorrectly initialized."; | |
274 if (!profiles_.empty() || !browsers_.empty() || !clients_.empty()) | |
275 LOG(FATAL) << "SetupClients() has already been called."; | |
276 | |
277 // Start up a sync test server if one is needed. | |
278 SetUpTestServerIfRequired(); | |
279 | |
280 // Create the required number of sync profiles, browsers and clients. | |
281 for (int i = 0; i < num_clients_; ++i) { | |
282 profiles_.push_back(MakeProfile( | |
283 base::StringPrintf(FILE_PATH_LITERAL("Profile%d"), i))); | |
284 EXPECT_FALSE(GetProfile(i) == NULL) << "GetProfile(" << i << ") failed."; | |
285 | |
286 browsers_.push_back(Browser::Create(GetProfile(i))); | |
287 EXPECT_FALSE(GetBrowser(i) == NULL) << "GetBrowser(" << i << ") failed."; | |
288 | |
289 clients_.push_back( | |
290 new ProfileSyncServiceHarness(GetProfile(i), username_, password_)); | |
291 EXPECT_FALSE(GetClient(i) == NULL) << "GetClient(" << i << ") failed."; | |
292 | |
293 ui_test_utils::WaitForBookmarkModelToLoad( | |
294 GetProfile(i)->GetBookmarkModel()); | |
295 } | |
296 | |
297 // Create the verifier profile. | |
298 verifier_.reset(MakeProfile(FILE_PATH_LITERAL("Verifier"))); | |
299 ui_test_utils::WaitForBookmarkModelToLoad(verifier()->GetBookmarkModel()); | |
300 return (verifier_.get() != NULL); | |
301 } | |
302 | |
303 bool LiveSyncTest::SetupSync() { | |
304 // Create sync profiles and clients if they haven't already been created. | |
305 if (profiles_.empty()) { | |
306 if (!SetupClients()) | |
307 LOG(FATAL) << "SetupClients() failed."; | |
308 } | |
309 | |
310 // Sync each of the profiles. | |
311 for (int i = 0; i < num_clients_; ++i) { | |
312 if (!GetClient(i)->SetupSync()) | |
313 LOG(FATAL) << "SetupSync() failed."; | |
314 } | |
315 | |
316 return true; | |
317 } | |
318 | |
319 void LiveSyncTest::CleanUpOnMainThread() { | |
320 // Close all browser windows. | |
321 BrowserList::CloseAllBrowsers(); | |
322 ui_test_utils::RunAllPendingInMessageLoop(); | |
323 | |
324 // All browsers should be closed at this point, or else we could see memory | |
325 // corruption in QuitBrowser(). | |
326 CHECK_EQ(0U, BrowserList::size()); | |
327 | |
328 profiles_.reset(); | |
329 clients_.reset(); | |
330 verifier_.reset(NULL); | |
331 } | |
332 | |
333 void LiveSyncTest::SetUpInProcessBrowserTestFixture() { | |
334 // We don't take a reference to |resolver|, but mock_host_resolver_override_ | |
335 // does, so effectively assumes ownership. | |
336 net::RuleBasedHostResolverProc* resolver = | |
337 new net::RuleBasedHostResolverProc(host_resolver()); | |
338 resolver->AllowDirectLookup("*.google.com"); | |
339 // On Linux, we use Chromium's NSS implementation which uses the following | |
340 // hosts for certificate verification. Without these overrides, running the | |
341 // integration tests on Linux causes error as we make external DNS lookups. | |
342 resolver->AllowDirectLookup("*.thawte.com"); | |
343 resolver->AllowDirectLookup("*.geotrust.com"); | |
344 resolver->AllowDirectLookup("*.gstatic.com"); | |
345 mock_host_resolver_override_.reset( | |
346 new net::ScopedDefaultHostResolverProc(resolver)); | |
347 } | |
348 | |
349 void LiveSyncTest::TearDownInProcessBrowserTestFixture() { | |
350 mock_host_resolver_override_.reset(); | |
351 } | |
352 | |
353 void LiveSyncTest::ReadPasswordFile() { | |
354 CommandLine* cl = CommandLine::ForCurrentProcess(); | |
355 password_file_ = cl->GetSwitchValuePath(switches::kPasswordFileForTest); | |
356 if (password_file_.empty()) | |
357 LOG(FATAL) << "Can't run live server test without specifying --" | |
358 << switches::kPasswordFileForTest << "=<filename>"; | |
359 std::string file_contents; | |
360 file_util::ReadFileToString(password_file_, &file_contents); | |
361 ASSERT_NE(file_contents, "") << "Password file \"" | |
362 << password_file_.value() << "\" does not exist."; | |
363 std::vector<std::string> tokens; | |
364 std::string delimiters = "\r\n"; | |
365 Tokenize(file_contents, delimiters, &tokens); | |
366 ASSERT_EQ(2U, tokens.size()) << "Password file \"" | |
367 << password_file_.value() | |
368 << "\" must contain exactly two lines of text."; | |
369 username_ = tokens[0]; | |
370 password_ = tokens[1]; | |
371 } | |
372 | |
373 void LiveSyncTest::SetupMockGaiaResponses() { | |
374 username_ = "user@gmail.com"; | |
375 password_ = "password"; | |
376 factory_.reset(new URLFetcherFactory()); | |
377 fake_factory_.reset(new FakeURLFetcherFactory(factory_.get())); | |
378 fake_factory_->SetFakeResponse(kClientLoginUrl, "SID=sid\nLSID=lsid", true); | |
379 fake_factory_->SetFakeResponse(kGetUserInfoUrl, "email=user@gmail.com", true); | |
380 fake_factory_->SetFakeResponse(kIssueAuthTokenUrl, "auth", true); | |
381 fake_factory_->SetFakeResponse(kSearchDomainCheckUrl, ".google.com", true); | |
382 } | |
383 | |
384 // Start up a local sync server based on the value of server_type_, which | |
385 // was determined from the command line parameters. | |
386 void LiveSyncTest::SetUpTestServerIfRequired() { | |
387 if (server_type_ == LOCAL_PYTHON_SERVER) { | |
388 if (!SetUpLocalPythonTestServer()) | |
389 LOG(FATAL) << "Failed to set up local python sync and XMPP servers"; | |
390 } else if (server_type_ == LOCAL_LIVE_SERVER) { | |
391 // Using mock gaia credentials requires the use of a mock XMPP server. | |
392 if (username_ == "user@gmail.com" && !SetUpLocalPythonTestServer()) | |
393 LOG(FATAL) << "Failed to set up local python XMPP server"; | |
394 if (!SetUpLocalTestServer()) | |
395 LOG(FATAL) << "Failed to set up local test server"; | |
396 } else if (server_type_ == EXTERNAL_LIVE_SERVER) { | |
397 // Nothing to do; we'll just talk to the URL we were given. | |
398 } else { | |
399 LOG(FATAL) << "Don't know which server environment to run test in."; | |
400 } | |
401 } | |
402 | |
403 bool LiveSyncTest::SetUpLocalPythonTestServer() { | |
404 EXPECT_TRUE(sync_server_.Start()) | |
405 << "Could not launch local python test server."; | |
406 | |
407 CommandLine* cl = CommandLine::ForCurrentProcess(); | |
408 if (server_type_ == LOCAL_PYTHON_SERVER) { | |
409 std::string sync_service_url = sync_server_.GetURL("chromiumsync").spec(); | |
410 cl->AppendSwitchASCII(switches::kSyncServiceURL, sync_service_url); | |
411 VLOG(1) << "Started local python sync server at " << sync_service_url; | |
412 } | |
413 | |
414 int xmpp_port = 0; | |
415 if (!sync_server_.server_data().GetInteger("xmpp_port", &xmpp_port)) { | |
416 LOG(ERROR) << "Could not find valid xmpp_port value"; | |
417 return false; | |
418 } | |
419 if ((xmpp_port <= 0) || (xmpp_port > kuint16max)) { | |
420 LOG(ERROR) << "Invalid xmpp port: " << xmpp_port; | |
421 return false; | |
422 } | |
423 | |
424 net::HostPortPair xmpp_host_port_pair(sync_server_.host_port_pair()); | |
425 xmpp_host_port_pair.set_port(xmpp_port); | |
426 xmpp_port_.reset(new net::ScopedPortException(xmpp_port)); | |
427 | |
428 if (!cl->HasSwitch(switches::kSyncNotificationHost)) { | |
429 cl->AppendSwitchASCII(switches::kSyncNotificationHost, | |
430 xmpp_host_port_pair.ToString()); | |
431 // The local XMPP server only supports insecure connections. | |
432 cl->AppendSwitch(switches::kSyncAllowInsecureXmppConnection); | |
433 } | |
434 VLOG(1) << "Started local python XMPP server at " | |
435 << xmpp_host_port_pair.ToString(); | |
436 | |
437 return true; | |
438 } | |
439 | |
440 bool LiveSyncTest::SetUpLocalTestServer() { | |
441 CommandLine* cl = CommandLine::ForCurrentProcess(); | |
442 CommandLine::StringType server_cmdline_string = cl->GetSwitchValueNative( | |
443 switches::kSyncServerCommandLine); | |
444 CommandLine::StringVector server_cmdline_vector; | |
445 CommandLine::StringType delimiters(FILE_PATH_LITERAL(" ")); | |
446 Tokenize(server_cmdline_string, delimiters, &server_cmdline_vector); | |
447 CommandLine server_cmdline(server_cmdline_vector); | |
448 base::LaunchOptions options; | |
449 #if defined(OS_WIN) | |
450 options.start_hidden = true; | |
451 #endif | |
452 if (!base::LaunchProcess(server_cmdline, options, &test_server_handle_)) | |
453 LOG(ERROR) << "Could not launch local test server."; | |
454 | |
455 const int kMaxWaitTime = TestTimeouts::action_max_timeout_ms(); | |
456 const int kNumIntervals = 15; | |
457 if (WaitForTestServerToStart(kMaxWaitTime, kNumIntervals)) { | |
458 VLOG(1) << "Started local test server at " | |
459 << cl->GetSwitchValueASCII(switches::kSyncServiceURL) << "."; | |
460 return true; | |
461 } else { | |
462 LOG(ERROR) << "Could not start local test server at " | |
463 << cl->GetSwitchValueASCII(switches::kSyncServiceURL) << "."; | |
464 return false; | |
465 } | |
466 } | |
467 | |
468 bool LiveSyncTest::TearDownLocalPythonTestServer() { | |
469 if (!sync_server_.Stop()) { | |
470 LOG(ERROR) << "Could not stop local python test server."; | |
471 return false; | |
472 } | |
473 xmpp_port_.reset(); | |
474 return true; | |
475 } | |
476 | |
477 bool LiveSyncTest::TearDownLocalTestServer() { | |
478 if (test_server_handle_ != base::kNullProcessHandle) { | |
479 EXPECT_TRUE(base::KillProcess(test_server_handle_, 0, false)) | |
480 << "Could not stop local test server."; | |
481 base::CloseProcessHandle(test_server_handle_); | |
482 test_server_handle_ = base::kNullProcessHandle; | |
483 } | |
484 return true; | |
485 } | |
486 | |
487 bool LiveSyncTest::WaitForTestServerToStart(int time_ms, int intervals) { | |
488 for (int i = 0; i < intervals; ++i) { | |
489 if (IsTestServerRunning()) | |
490 return true; | |
491 base::PlatformThread::Sleep(time_ms / intervals); | |
492 } | |
493 return false; | |
494 } | |
495 | |
496 bool LiveSyncTest::IsTestServerRunning() { | |
497 CommandLine* cl = CommandLine::ForCurrentProcess(); | |
498 std::string sync_url = cl->GetSwitchValueASCII(switches::kSyncServiceURL); | |
499 GURL sync_url_status(sync_url.append("/healthz")); | |
500 SyncServerStatusChecker delegate; | |
501 URLFetcher fetcher(sync_url_status, URLFetcher::GET, &delegate); | |
502 fetcher.set_request_context(Profile::Deprecated::GetDefaultRequestContext()); | |
503 fetcher.Start(); | |
504 ui_test_utils::RunMessageLoop(); | |
505 return delegate.running(); | |
506 } | |
507 | |
508 void LiveSyncTest::EnableNetwork(Profile* profile) { | |
509 SetProxyConfig(profile->GetRequestContext(), | |
510 net::ProxyConfig::CreateDirect()); | |
511 // TODO(rsimha): Remove this line once http://crbug.com/53857 is fixed. | |
512 net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
513 } | |
514 | |
515 void LiveSyncTest::DisableNetwork(Profile* profile) { | |
516 // Set the current proxy configuration to a nonexistent proxy to effectively | |
517 // disable networking. | |
518 net::ProxyConfig config; | |
519 config.proxy_rules().ParseFromString("http=127.0.0.1:0"); | |
520 SetProxyConfig(profile->GetRequestContext(), config); | |
521 // TODO(rsimha): Remove this line once http://crbug.com/53857 is fixed. | |
522 net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
523 } | |
524 | |
525 bool LiveSyncTest::EnableEncryption(int index, syncable::ModelType type) { | |
526 return GetClient(index)->EnableEncryptionForType(type); | |
527 } | |
528 | |
529 bool LiveSyncTest::IsEncrypted(int index, syncable::ModelType type) { | |
530 return GetClient(index)->IsTypeEncrypted(type); | |
531 } | |
532 | |
533 bool LiveSyncTest::AwaitQuiescence() { | |
534 return ProfileSyncServiceHarness::AwaitQuiescence(clients()); | |
535 } | |
536 | |
537 bool LiveSyncTest::ServerSupportsNotificationControl() const { | |
538 EXPECT_NE(SERVER_TYPE_UNDECIDED, server_type_); | |
539 | |
540 // Supported only if we're using the python testserver. | |
541 return server_type_ == LOCAL_PYTHON_SERVER; | |
542 } | |
543 | |
544 void LiveSyncTest::DisableNotifications() { | |
545 ASSERT_TRUE(ServerSupportsNotificationControl()); | |
546 std::string path = "chromiumsync/disablenotifications"; | |
547 ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path)); | |
548 ASSERT_EQ("Notifications disabled", | |
549 UTF16ToASCII(browser()->GetSelectedTabContents()->GetTitle())); | |
550 } | |
551 | |
552 void LiveSyncTest::EnableNotifications() { | |
553 ASSERT_TRUE(ServerSupportsNotificationControl()); | |
554 std::string path = "chromiumsync/enablenotifications"; | |
555 ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path)); | |
556 ASSERT_EQ("Notifications enabled", | |
557 UTF16ToASCII(browser()->GetSelectedTabContents()->GetTitle())); | |
558 } | |
559 | |
560 void LiveSyncTest::TriggerNotification( | |
561 const syncable::ModelTypeSet& changed_types) { | |
562 ASSERT_TRUE(ServerSupportsNotificationControl()); | |
563 const std::string& data = | |
564 sync_notifier::P2PNotificationData("from_server", | |
565 sync_notifier::NOTIFY_ALL, | |
566 changed_types).ToString(); | |
567 const std::string& path = | |
568 std::string("chromiumsync/sendnotification?channel=") + | |
569 sync_notifier::kSyncP2PNotificationChannel + "&data=" + data; | |
570 ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path)); | |
571 ASSERT_EQ("Notification sent", | |
572 UTF16ToASCII(browser()->GetSelectedTabContents()->GetTitle())); | |
573 } | |
574 | |
575 bool LiveSyncTest::ServerSupportsErrorTriggering() const { | |
576 EXPECT_NE(SERVER_TYPE_UNDECIDED, server_type_); | |
577 | |
578 // Supported only if we're using the python testserver. | |
579 return server_type_ == LOCAL_PYTHON_SERVER; | |
580 } | |
581 | |
582 void LiveSyncTest::TriggerMigrationDoneError( | |
583 const syncable::ModelTypeSet& model_types) { | |
584 ASSERT_TRUE(ServerSupportsErrorTriggering()); | |
585 std::string path = "chromiumsync/migrate"; | |
586 char joiner = '?'; | |
587 for (syncable::ModelTypeSet::const_iterator it = model_types.begin(); | |
588 it != model_types.end(); ++it) { | |
589 path.append(base::StringPrintf("%ctype=%d", joiner, | |
590 syncable::GetExtensionFieldNumberFromModelType(*it))); | |
591 joiner = '&'; | |
592 } | |
593 ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path)); | |
594 ASSERT_EQ("Migration: 200", | |
595 UTF16ToASCII(browser()->GetSelectedTabContents()->GetTitle())); | |
596 } | |
597 | |
598 void LiveSyncTest::TriggerBirthdayError() { | |
599 ASSERT_TRUE(ServerSupportsErrorTriggering()); | |
600 std::string path = "chromiumsync/birthdayerror"; | |
601 ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path)); | |
602 ASSERT_EQ("Birthday error", | |
603 UTF16ToASCII(browser()->GetSelectedTabContents()->GetTitle())); | |
604 } | |
605 | |
606 void LiveSyncTest::TriggerTransientError() { | |
607 ASSERT_TRUE(ServerSupportsErrorTriggering()); | |
608 std::string path = "chromiumsync/transienterror"; | |
609 ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path)); | |
610 ASSERT_EQ("Transient error", | |
611 UTF16ToASCII(browser()->GetSelectedTabContents()->GetTitle())); | |
612 } | |
613 | |
614 void LiveSyncTest::TriggerSetSyncTabs() { | |
615 ASSERT_TRUE(ServerSupportsErrorTriggering()); | |
616 std::string path = "chromiumsync/synctabs"; | |
617 ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path)); | |
618 ASSERT_EQ("Sync Tabs", | |
619 UTF16ToASCII(browser()->GetSelectedTabContents()->GetTitle())); | |
620 } | |
621 | |
622 void LiveSyncTest::SetProxyConfig(net::URLRequestContextGetter* context_getter, | |
623 const net::ProxyConfig& proxy_config) { | |
624 base::WaitableEvent done(false, false); | |
625 BrowserThread::PostTask( | |
626 BrowserThread::IO, | |
627 FROM_HERE, | |
628 new SetProxyConfigTask(&done, | |
629 context_getter, | |
630 proxy_config)); | |
631 done.Wait(); | |
632 } | |
OLD | NEW |