summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-19 20:40:52 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-19 20:40:52 +0000
commita282459003e96df101511c8add34021318cf9a08 (patch)
treec823428164c29afa3ddc3feb36fbf6744faf0186
parent1e5e1dd8d286ca0a786f91802b70273ff2209131 (diff)
downloadchromium_src-a282459003e96df101511c8add34021318cf9a08.zip
chromium_src-a282459003e96df101511c8add34021318cf9a08.tar.gz
chromium_src-a282459003e96df101511c8add34021318cf9a08.tar.bz2
[Sync] Add integration tests for migration cycle
Add integration tests to make sure that the migration cycle doesn't stall. Add way for sync integration tests to turn off notifications. BUG=92928 TEST= Review URL: http://codereview.chromium.org/7669064 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97504 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/automation/testing_automation_provider.cc3
-rw-r--r--chrome/browser/sync/engine/sync_scheduler.cc2
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.cc3
-rw-r--r--chrome/browser/sync/profile_sync_service_harness.cc11
-rw-r--r--chrome/browser/sync/profile_sync_service_harness.h6
-rw-r--r--chrome/test/live_sync/live_sync_test.cc63
-rw-r--r--chrome/test/live_sync/live_sync_test.h8
-rw-r--r--chrome/test/live_sync/migration_errors_test.cc103
8 files changed, 168 insertions, 31 deletions
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc
index e41a701..dbbd3a4 100644
--- a/chrome/browser/automation/testing_automation_provider.cc
+++ b/chrome/browser/automation/testing_automation_provider.cc
@@ -4510,7 +4510,8 @@ void TestingAutomationProvider::SignInToSync(Browser* browser,
}
if (sync_waiter_.get() == NULL) {
sync_waiter_.reset(new ProfileSyncServiceHarness(
- browser->profile(), username, password));
+ browser->profile(), username, password,
+ true /* expected_notifications_enabled */));
} else {
sync_waiter_->SetCredentials(username, password);
}
diff --git a/chrome/browser/sync/engine/sync_scheduler.cc b/chrome/browser/sync/engine/sync_scheduler.cc
index 0409545..993b727 100644
--- a/chrome/browser/sync/engine/sync_scheduler.cc
+++ b/chrome/browser/sync/engine/sync_scheduler.cc
@@ -897,7 +897,7 @@ void SyncScheduler::HandleConsecutiveContinuationError(
TimeDelta length = delay_provider_->GetDelay(
IsBackingOff() ? wait_interval_->length : TimeDelta::FromSeconds(1));
- SVLOG(2) << "In handle continuation error with"
+ SVLOG(2) << "In handle continuation error with "
<< SyncSessionJob::GetPurposeString(old_job.purpose)
<< " job. The time delta(ms) is "
<< length.InMilliseconds();
diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc
index 116164f..efa717b 100644
--- a/chrome/browser/sync/glue/sync_backend_host.cc
+++ b/chrome/browser/sync/glue/sync_backend_host.cc
@@ -355,6 +355,9 @@ void SyncBackendHost::ConfigureDataTypes(
pending_config_mode_state_.get());
}
+ // Cleanup disabled types before starting configuration so that
+ // callers can assume that the data types are cleaned up once
+ // configuration is done.
if (!types_to_remove.empty()) {
sync_thread_.message_loop()->PostTask(
FROM_HERE,
diff --git a/chrome/browser/sync/profile_sync_service_harness.cc b/chrome/browser/sync/profile_sync_service_harness.cc
index 20a75ef..9149723 100644
--- a/chrome/browser/sync/profile_sync_service_harness.cc
+++ b/chrome/browser/sync/profile_sync_service_harness.cc
@@ -95,7 +95,8 @@ bool StateChangeTimeoutEvent::Abort() {
ProfileSyncServiceHarness::ProfileSyncServiceHarness(
Profile* profile,
const std::string& username,
- const std::string& password)
+ const std::string& password,
+ bool expected_notifications_enabled)
: waiting_for_encryption_type_(syncable::UNSPECIFIED),
wait_state_(INITIAL_WAIT_STATE),
profile_(profile),
@@ -103,6 +104,7 @@ ProfileSyncServiceHarness::ProfileSyncServiceHarness(
timestamp_match_partner_(NULL),
username_(username),
password_(password),
+ expected_notifications_enabled_(expected_notifications_enabled),
profile_debug_name_(profile->GetDebugName()) {
if (IsSyncAlreadySetup()) {
service_ = profile_->GetProfileSyncService();
@@ -120,7 +122,9 @@ ProfileSyncServiceHarness* ProfileSyncServiceHarness::CreateAndAttach(
NOTREACHED() << "Profile has never signed into sync.";
return NULL;
}
- return new ProfileSyncServiceHarness(profile, "", "");
+ return new ProfileSyncServiceHarness(
+ profile, "", "",
+ /* expected_notifications_enabled */ true);
}
void ProfileSyncServiceHarness::SetCredentials(const std::string& username,
@@ -616,7 +620,8 @@ bool ProfileSyncServiceHarness::IsSynced() {
bool is_synced = snap &&
snap->num_blocking_conflicting_updates == 0 &&
ServiceIsPushingChanges() &&
- GetStatus().notifications_enabled &&
+ (GetStatus().notifications_enabled ==
+ expected_notifications_enabled_) &&
!service()->HasUnsyncedItems() &&
!snap->has_more_to_sync &&
snap->unsynced_count == 0 &&
diff --git a/chrome/browser/sync/profile_sync_service_harness.h b/chrome/browser/sync/profile_sync_service_harness.h
index 1cdeb60..1179bce 100644
--- a/chrome/browser/sync/profile_sync_service_harness.h
+++ b/chrome/browser/sync/profile_sync_service_harness.h
@@ -32,7 +32,8 @@ class ProfileSyncServiceHarness : public ProfileSyncServiceObserver {
public:
ProfileSyncServiceHarness(Profile* profile,
const std::string& username,
- const std::string& password);
+ const std::string& password,
+ bool expected_notifications_enabled);
virtual ~ProfileSyncServiceHarness();
@@ -271,6 +272,9 @@ class ProfileSyncServiceHarness : public ProfileSyncServiceObserver {
std::string username_;
std::string password_;
+ // The expected value of GetStatus().notifications_enabled.
+ bool expected_notifications_enabled_;
+
// Used for logging.
const std::string profile_debug_name_;
diff --git a/chrome/test/live_sync/live_sync_test.cc b/chrome/test/live_sync/live_sync_test.cc
index 61c6b2c..b258d1c 100644
--- a/chrome/test/live_sync/live_sync_test.cc
+++ b/chrome/test/live_sync/live_sync_test.cc
@@ -112,7 +112,8 @@ LiveSyncTest::LiveSyncTest(TestType test_type)
server_type_(SERVER_TYPE_UNDECIDED),
num_clients_(-1),
use_verifier_(true),
- test_server_handle_(base::kNullProcessHandle) {
+ test_server_handle_(base::kNullProcessHandle),
+ enable_notifications_(true) {
InProcessBrowserTest::set_show_window(true);
sync_datatype_helper::AssociateWithTest(this);
switch (test_type_) {
@@ -270,7 +271,8 @@ bool LiveSyncTest::SetupClients() {
base::StringPrintf(FILE_PATH_LITERAL("Profile%d"), i)));
EXPECT_FALSE(GetProfile(i) == NULL) << "GetProfile(" << i << ") failed.";
clients_.push_back(
- new ProfileSyncServiceHarness(GetProfile(i), username_, password_));
+ new ProfileSyncServiceHarness(GetProfile(i), username_, password_,
+ enable_notifications_));
EXPECT_FALSE(GetClient(i) == NULL) << "GetClient(" << i << ") failed.";
ui_test_utils::WaitForBookmarkModelToLoad(
GetProfile(i)->GetBookmarkModel());
@@ -380,25 +382,27 @@ bool LiveSyncTest::SetUpLocalPythonTestServer() {
cl->AppendSwitchASCII(switches::kSyncServiceURL, sync_service_url);
VLOG(1) << "Started local python test server at " << sync_service_url;
- int xmpp_port = 0;
- if (!sync_server_.server_data().GetInteger("xmpp_port", &xmpp_port)) {
- LOG(ERROR) << "Could not find valid xmpp_port value";
- return false;
- }
- if ((xmpp_port <= 0) || (xmpp_port > kuint16max)) {
- LOG(ERROR) << "Invalid xmpp port: " << xmpp_port;
- return false;
- }
+ if (enable_notifications_) {
+ int xmpp_port = 0;
+ if (!sync_server_.server_data().GetInteger("xmpp_port", &xmpp_port)) {
+ LOG(ERROR) << "Could not find valid xmpp_port value";
+ return false;
+ }
+ if ((xmpp_port <= 0) || (xmpp_port > kuint16max)) {
+ LOG(ERROR) << "Invalid xmpp port: " << xmpp_port;
+ return false;
+ }
- net::HostPortPair xmpp_host_port_pair(sync_server_.host_port_pair());
- xmpp_host_port_pair.set_port(xmpp_port);
- xmpp_port_.reset(new net::ScopedPortException(xmpp_port));
+ net::HostPortPair xmpp_host_port_pair(sync_server_.host_port_pair());
+ xmpp_host_port_pair.set_port(xmpp_port);
+ xmpp_port_.reset(new net::ScopedPortException(xmpp_port));
- if (!cl->HasSwitch(switches::kSyncNotificationHost)) {
- cl->AppendSwitchASCII(switches::kSyncNotificationHost,
- xmpp_host_port_pair.ToString());
- // The local XMPP server only supports insecure connections.
- cl->AppendSwitch(switches::kSyncAllowInsecureXmppConnection);
+ if (!cl->HasSwitch(switches::kSyncNotificationHost)) {
+ cl->AppendSwitchASCII(switches::kSyncNotificationHost,
+ xmpp_host_port_pair.ToString());
+ // The local XMPP server only supports insecure connections.
+ cl->AppendSwitch(switches::kSyncAllowInsecureXmppConnection);
+ }
}
return true;
@@ -489,6 +493,15 @@ void LiveSyncTest::DisableNetwork(Profile* profile) {
net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
}
+void LiveSyncTest::DisableNotifications() {
+ // TODO(akalin): It would be better to assert that the test server
+ // hasn't been started yet. That would require adding an
+ // IsStarted() method to TestServer.
+ ASSERT_TRUE(profiles_.empty());
+ ASSERT_TRUE(clients_.empty());
+ enable_notifications_ = false;
+}
+
bool LiveSyncTest::AwaitQuiescence() {
return ProfileSyncServiceHarness::AwaitQuiescence(clients());
}
@@ -512,24 +525,24 @@ void LiveSyncTest::TriggerMigrationDoneError(
joiner = '&';
}
ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
- ASSERT_EQ(ASCIIToUTF16("Migration: 200"),
- browser()->GetSelectedTabContents()->GetTitle());
+ ASSERT_EQ("Migration: 200",
+ UTF16ToASCII(browser()->GetSelectedTabContents()->GetTitle()));
}
void LiveSyncTest::TriggerBirthdayError() {
ASSERT_TRUE(ServerSupportsErrorTriggering());
std::string path = "chromiumsync/birthdayerror";
ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
- ASSERT_EQ(ASCIIToUTF16("Birthday error"),
- browser()->GetSelectedTabContents()->GetTitle());
+ ASSERT_EQ("Birthday error",
+ UTF16ToASCII(browser()->GetSelectedTabContents()->GetTitle()));
}
void LiveSyncTest::TriggerTransientError() {
ASSERT_TRUE(ServerSupportsErrorTriggering());
std::string path = "chromiumsync/transienterror";
ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
- ASSERT_EQ(ASCIIToUTF16("Transient error"),
- browser()->GetSelectedTabContents()->GetTitle());
+ ASSERT_EQ("Transient error",
+ UTF16ToASCII(browser()->GetSelectedTabContents()->GetTitle()));
}
void LiveSyncTest::SetProxyConfig(net::URLRequestContextGetter* context_getter,
diff --git a/chrome/test/live_sync/live_sync_test.h b/chrome/test/live_sync/live_sync_test.h
index fc5e008..a9c518e 100644
--- a/chrome/test/live_sync/live_sync_test.h
+++ b/chrome/test/live_sync/live_sync_test.h
@@ -126,6 +126,11 @@ class LiveSyncTest : public InProcessBrowserTest {
// Disable outgoing network connections for the given profile.
virtual void DisableNetwork(Profile* profile);
+ // Disable notifications for the current test. Must be called
+ // before the test server is started (i.e., before either of
+ // SetupSync() or SetupClients() is called).
+ void DisableNotifications();
+
// Blocks until all sync clients have completed their mutual sync cycles.
// Returns true if a quiescent state was successfully reached.
bool AwaitQuiescence();
@@ -266,6 +271,9 @@ class LiveSyncTest : public InProcessBrowserTest {
// URLFetcher factory used to contact sync server.
scoped_ptr<URLFetcherFactory> integration_factory_;
+ // Whether or not to use notifications for the current test.
+ bool enable_notifications_;
+
DISALLOW_COPY_AND_ASSIGN(LiveSyncTest);
};
diff --git a/chrome/test/live_sync/migration_errors_test.cc b/chrome/test/live_sync/migration_errors_test.cc
index 6fbeb48..6626ea2 100644
--- a/chrome/test/live_sync/migration_errors_test.cc
+++ b/chrome/test/live_sync/migration_errors_test.cc
@@ -19,6 +19,109 @@ using bookmarks_helper::IndexedURLTitle;
using preferences_helper::BooleanPrefMatches;
using preferences_helper::ChangeBooleanPref;
+// Tests to make sure that the migration cycle works properly,
+// i.e. doesn't stall.
+
+class MigrationCycleTest : public LiveSyncTest {
+ public:
+ MigrationCycleTest() : LiveSyncTest(SINGLE_CLIENT) {}
+ virtual ~MigrationCycleTest() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MigrationCycleTest);
+};
+
+IN_PROC_BROWSER_TEST_F(MigrationCycleTest, PrefsOnly) {
+ if (!ServerSupportsErrorTriggering()) {
+ LOG(WARNING) << "Test skipped in this server environment.";
+ return;
+ }
+
+ DisableNotifications();
+
+ ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
+
+ // Phase 1: Trigger a preference migration on the server.
+ syncable::ModelTypeSet migrate_types;
+ migrate_types.insert(syncable::PREFERENCES);
+ TriggerMigrationDoneError(migrate_types);
+
+ // Phase 2: Modify a pref (to trigger migration) and wait for a sync
+ // cycle.
+ // TODO(akalin): Shouldn't need to wait for full sync cycle; see
+ // 93167.
+ ASSERT_TRUE(BooleanPrefMatches(prefs::kShowHomeButton));
+ ChangeBooleanPref(0, prefs::kShowHomeButton);
+ ASSERT_TRUE(GetClient(0)->AwaitSyncCycleCompletion("Migration"));
+}
+
+// TODO(akalin): Fails due to http://crbug.com/92928.
+IN_PROC_BROWSER_TEST_F(MigrationCycleTest, FAILS_PrefsNigori) {
+ if (!ServerSupportsErrorTriggering()) {
+ LOG(WARNING) << "Test skipped in this server environment.";
+ return;
+ }
+
+ DisableNotifications();
+
+ ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
+
+ // Phase 1: Trigger a preference and nigori migration on the server.
+ {
+ syncable::ModelTypeSet migrate_types;
+ migrate_types.insert(syncable::PREFERENCES);
+ TriggerMigrationDoneError(migrate_types);
+ }
+ {
+ syncable::ModelTypeSet migrate_types;
+ migrate_types.insert(syncable::NIGORI);
+ TriggerMigrationDoneError(migrate_types);
+ }
+
+ // Phase 2: Modify a pref (to trigger migration) and wait for a sync
+ // cycle.
+ // TODO(akalin): Shouldn't need to wait for full sync cycle; see
+ // 93167.
+ ASSERT_TRUE(BooleanPrefMatches(prefs::kShowHomeButton));
+ ChangeBooleanPref(0, prefs::kShowHomeButton);
+ ASSERT_TRUE(GetClient(0)->AwaitSyncCycleCompletion("Migration"));
+}
+
+// TODO(akalin): Fails due to http://crbug.com/92928.
+IN_PROC_BROWSER_TEST_F(MigrationCycleTest, FAILS_BookmarksPrefs) {
+ if (!ServerSupportsErrorTriggering()) {
+ LOG(WARNING) << "Test skipped in this server environment.";
+ return;
+ }
+
+ DisableNotifications();
+
+ ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
+
+ // Phase 1: Trigger a bookmark and preference migration on the
+ // server.
+ {
+ syncable::ModelTypeSet migrate_types;
+ migrate_types.insert(syncable::BOOKMARKS);
+ TriggerMigrationDoneError(migrate_types);
+ }
+ {
+ syncable::ModelTypeSet migrate_types;
+ migrate_types.insert(syncable::PREFERENCES);
+ TriggerMigrationDoneError(migrate_types);
+ }
+
+ // Phase 2: Modify a bookmark (to trigger migration) and wait for a
+ // sync cycle.
+ // TODO(akalin): Shouldn't need to wait for full sync cycle; see
+ // 93167.
+ ASSERT_TRUE(AddURL(0, IndexedURLTitle(0), GURL(IndexedURL(0))) != NULL);
+ ASSERT_TRUE(GetClient(0)->AwaitSyncCycleCompletion("Migration"));
+}
+
+// TODO(akalin): Add tests where the migration trigger is a poll or a
+// nudge from notifications.
+
class MigrationErrorsTest : public LiveSyncTest {
public:
MigrationErrorsTest() : LiveSyncTest(TWO_CLIENT) {}