diff options
author | zea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-04 14:41:38 +0000 |
---|---|---|
committer | zea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-04 14:41:38 +0000 |
commit | 52af9bc3801fac7b1b258861716c807790e4e42f (patch) | |
tree | 0997e75bd774e2873e7a05bce62c5a52758a0ef2 | |
parent | c4855a524f0c6e07aeb451c7be28f661e2ca11b0 (diff) | |
download | chromium_src-52af9bc3801fac7b1b258861716c807790e4e42f.zip chromium_src-52af9bc3801fac7b1b258861716c807790e4e42f.tar.gz chromium_src-52af9bc3801fac7b1b258861716c807790e4e42f.tar.bz2 |
Session sync integration tests. Left out many client for now, since even
without doing anything in the test it was timing out.
BUG=30519
TEST=self
Review URL: http://codereview.chromium.org/4158009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65051 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/dom_ui/foreign_session_handler.cc | 2 | ||||
-rw-r--r-- | chrome/browser/sessions/session_service.h | 2 | ||||
-rw-r--r-- | chrome/browser/sessions/session_service_test_helper.h | 1 | ||||
-rw-r--r-- | chrome/browser/sessions/session_types.cc | 2 | ||||
-rw-r--r-- | chrome/browser/sessions/session_types.h | 2 | ||||
-rw-r--r-- | chrome/browser/sync/glue/session_model_associator.cc | 38 | ||||
-rw-r--r-- | chrome/browser/sync/glue/session_model_associator.h | 4 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service_session_unittest.cc | 2 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 7 | ||||
-rw-r--r-- | chrome/test/live_sync/live_sessions_sync_test.h | 418 | ||||
-rw-r--r-- | chrome/test/live_sync/live_sync_test.cc | 5 | ||||
-rw-r--r-- | chrome/test/live_sync/multiple_client_live_sessions_sync_test.cc | 33 | ||||
-rw-r--r-- | chrome/test/live_sync/single_client_live_sessions_sync_test.cc | 30 | ||||
-rw-r--r-- | chrome/test/live_sync/two_client_live_sessions_sync_test.cc | 62 |
14 files changed, 588 insertions, 20 deletions
diff --git a/chrome/browser/dom_ui/foreign_session_handler.cc b/chrome/browser/dom_ui/foreign_session_handler.cc index e35d8e5..d0ceabc 100644 --- a/chrome/browser/dom_ui/foreign_session_handler.cc +++ b/chrome/browser/dom_ui/foreign_session_handler.cc @@ -142,7 +142,7 @@ void ForeignSessionHandler::GetForeignSessions( // TODO(zea): sessionTag is per client, it might be better per window. window_data->SetString("sessionTag", - foreign_session->foreign_tession_tag); + foreign_session->foreign_session_tag); window_data->SetInteger("sessionId", entry->id); // Give ownership to |list_value|. diff --git a/chrome/browser/sessions/session_service.h b/chrome/browser/sessions/session_service.h index 96bb27c..8dedb8d 100644 --- a/chrome/browser/sessions/session_service.h +++ b/chrome/browser/sessions/session_service.h @@ -240,7 +240,7 @@ class SessionService : public BaseSessionService, SessionCommand* CreatePinnedStateCommand(const SessionID& tab_id, bool is_pinned); - // Callback form the backend for getting the commands from the previous + // Callback from the backend for getting the commands from the previous // or save file. Converts the commands in SessionWindows and notifies // the real callback. void OnGotSessionCommands( diff --git a/chrome/browser/sessions/session_service_test_helper.h b/chrome/browser/sessions/session_service_test_helper.h index c0caa7e..062bb1c 100644 --- a/chrome/browser/sessions/session_service_test_helper.h +++ b/chrome/browser/sessions/session_service_test_helper.h @@ -63,6 +63,7 @@ class SessionServiceTestHelper { size_t nav_count); void set_service(SessionService* service) { service_ = service; } + SessionService* ReleaseService() { return service_.release(); } SessionService* service() { return service_.get(); } SessionBackend* backend(); diff --git a/chrome/browser/sessions/session_types.cc b/chrome/browser/sessions/session_types.cc index 995a9a2..2ebfbb1 100644 --- a/chrome/browser/sessions/session_types.cc +++ b/chrome/browser/sessions/session_types.cc @@ -110,7 +110,7 @@ SessionWindow::~SessionWindow() { // ForeignSession -------------------------------------------------------------- -ForeignSession::ForeignSession() : foreign_tession_tag("invalid") { +ForeignSession::ForeignSession() : foreign_session_tag("invalid") { } ForeignSession::~ForeignSession() { diff --git a/chrome/browser/sessions/session_types.h b/chrome/browser/sessions/session_types.h index 119392a..4f84246 100644 --- a/chrome/browser/sessions/session_types.h +++ b/chrome/browser/sessions/session_types.h @@ -185,7 +185,7 @@ struct ForeignSession { ~ForeignSession(); // Unique tag for each session. - std::string foreign_tession_tag; + std::string foreign_session_tag; std::vector<SessionWindow*> windows; }; diff --git a/chrome/browser/sync/glue/session_model_associator.cc b/chrome/browser/sync/glue/session_model_associator.cc index 961bfc7..b4666f8 100644 --- a/chrome/browser/sync/glue/session_model_associator.cc +++ b/chrome/browser/sync/glue/session_model_associator.cc @@ -192,7 +192,9 @@ bool SessionModelAssociator::GetSessionData( // Build vector of sessions from specifics data for (std::vector<const sync_pb::SessionSpecifics*>::const_iterator i = specifics_.begin(); i != specifics_.end(); ++i) { - AppendForeignSessionFromSpecifics(*i, sessions); + // Only include sessions with open windows. + if ((*i)->session_window_size() > 0) + AppendForeignSessionFromSpecifics(*i, sessions); } return true; @@ -202,7 +204,7 @@ void SessionModelAssociator::AppendForeignSessionFromSpecifics( const sync_pb::SessionSpecifics* specifics, std::vector<ForeignSession*>* session) { ForeignSession* foreign_session = new ForeignSession(); - foreign_session->foreign_tession_tag = specifics->session_tag(); + foreign_session->foreign_session_tag = specifics->session_tag(); session->insert(session->end(), foreign_session); for (int i = 0; i < specifics->session_window_size(); i++) { const sync_pb::SessionWindow* window = &specifics->session_window(i); @@ -386,24 +388,16 @@ bool SessionModelAssociator::WindowHasNoTabsToSync( void SessionModelAssociator::OnGotSession(int handle, std::vector<SessionWindow*>* windows) { - sync_pb::SessionSpecifics session; + sync_pb::SessionSpecifics specifics; // Set the tag, then iterate through the vector of windows, extracting the // window data, along with the tabs data and tab navigation data to populate // the session specifics. - session.set_session_tag(GetCurrentMachineTag()); - for (std::vector<SessionWindow*>::const_iterator i = windows->begin(); - i != windows->end(); ++i) { - const SessionWindow* window = *i; - if (WindowHasNoTabsToSync(window)) { - continue; - } - sync_pb::SessionWindow* session_window = session.add_session_window(); - PopulateSessionSpecificsWindow(window, session_window); - } + specifics.set_session_tag(GetCurrentMachineTag()); + FillSpecificsFromSessions(windows, &specifics); bool has_nodes = false; if (!SyncModelHasUserCreatedNodes(&has_nodes)) return; - if (session.session_window_size() == 0 && has_nodes) + if (specifics.session_window_size() == 0 && has_nodes) return; sync_api::WriteTransaction trans( sync_service_->backend()->GetUserShareHandle()); @@ -412,7 +406,21 @@ void SessionModelAssociator::OnGotSession(int handle, LOG(ERROR) << kNoSessionsFolderError; return; } - UpdateSyncModel(&session, &trans, &root); + UpdateSyncModel(&specifics, &trans, &root); +} + +void SessionModelAssociator::FillSpecificsFromSessions( + std::vector<SessionWindow*>* windows, + sync_pb::SessionSpecifics* session) { + for (std::vector<SessionWindow*>::const_iterator i = windows->begin(); + i != windows->end(); ++i) { + const SessionWindow* window = *i; + if (WindowHasNoTabsToSync(window)) { + continue; + } + sync_pb::SessionWindow* session_window = session->add_session_window(); + PopulateSessionSpecificsWindow(window, session_window); + } } void SessionModelAssociator::AppendSessionTabNavigation( diff --git a/chrome/browser/sync/glue/session_model_associator.h b/chrome/browser/sync/glue/session_model_associator.h index ac7a234..89d30be 100644 --- a/chrome/browser/sync/glue/session_model_associator.h +++ b/chrome/browser/sync/glue/session_model_associator.h @@ -129,6 +129,10 @@ class SessionModelAssociator : public PerDataTypeAssociatorInterface< // Builds sessions from buffered specifics data bool GetSessionData(std::vector<ForeignSession*>* sessions); + // Helper method to generate session specifics from session windows. + void FillSpecificsFromSessions(std::vector<SessionWindow*>* windows, + sync_pb::SessionSpecifics* session); + // Helper method for converting session specifics to windows. void AppendForeignSessionFromSpecifics( const sync_pb::SessionSpecifics* specifics, diff --git a/chrome/browser/sync/profile_sync_service_session_unittest.cc b/chrome/browser/sync/profile_sync_service_session_unittest.cc index 77790e4..fc0757e 100644 --- a/chrome/browser/sync/profile_sync_service_session_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_session_unittest.cc @@ -314,7 +314,7 @@ TEST_F(ProfileSyncServiceSessionTest, WriteForeignSessionToNode) { ASSERT_EQ(1U, foreign_sessions[0]->windows.size()); ASSERT_EQ(1U, foreign_sessions[0]->windows[0]->tabs.size()); ASSERT_EQ(1U, foreign_sessions[0]->windows[0]->tabs[0]->navigations.size()); - ASSERT_EQ(foreign_sessions[0]->foreign_tession_tag, machine_tag); + ASSERT_EQ(foreign_sessions[0]->foreign_session_tag, machine_tag); ASSERT_EQ(1, foreign_sessions[0]->windows[0]->selected_tab_index); ASSERT_EQ(1, foreign_sessions[0]->windows[0]->type); ASSERT_EQ(13, foreign_sessions[0]->windows[0]->tabs[0]->tab_visual_index); diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index f9b5505..e0b99dd 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -2676,6 +2676,9 @@ 'browser/autofill/autofill_common_test.cc', 'browser/autofill/autofill_common_test.h', 'browser/password_manager/password_form_data.cc', + 'browser/sessions/session_backend.cc', + 'browser/sessions/session_service_test_helper.cc', + 'browser/sync/glue/session_model_associator.cc', 'test/bookmark_load_observer.h', 'test/in_process_browser_test.cc', 'test/in_process_browser_test.h', @@ -2686,6 +2689,7 @@ 'test/live_sync/live_bookmarks_sync_test.h', 'test/live_sync/live_passwords_sync_test.h', 'test/live_sync/live_preferences_sync_test.h', + 'test/live_sync/live_sessions_sync_test.h', 'test/live_sync/live_sync_test.cc', 'test/live_sync/live_sync_test.h', 'test/live_sync/many_client_live_bookmarks_sync_test.cc', @@ -2694,13 +2698,16 @@ 'test/live_sync/multiple_client_live_bookmarks_sync_test.cc', 'test/live_sync/multiple_client_live_passwords_sync_test.cc', 'test/live_sync/multiple_client_live_preferences_sync_test.cc', + 'test/live_sync/multiple_client_live_sessions_sync_test.cc', 'test/live_sync/single_client_live_bookmarks_sync_test.cc', 'test/live_sync/single_client_live_passwords_sync_test.cc', 'test/live_sync/single_client_live_preferences_sync_test.cc', + 'test/live_sync/single_client_live_sessions_sync_test.cc', 'test/live_sync/two_client_live_autofill_sync_test.cc', 'test/live_sync/two_client_live_bookmarks_sync_test.cc', 'test/live_sync/two_client_live_preferences_sync_test.cc', 'test/live_sync/two_client_live_passwords_sync_test.cc', + 'test/live_sync/two_client_live_sessions_sync_test.cc', 'test/test_notification_tracker.cc', 'test/test_notification_tracker.h', 'test/testing_browser_process.h', diff --git a/chrome/test/live_sync/live_sessions_sync_test.h b/chrome/test/live_sync/live_sessions_sync_test.h new file mode 100644 index 0000000..48c9d63 --- /dev/null +++ b/chrome/test/live_sync/live_sessions_sync_test.h @@ -0,0 +1,418 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_TEST_LIVE_SYNC_LIVE_SESSIONS_SYNC_TEST_H_ +#define CHROME_TEST_LIVE_SYNC_LIVE_SESSIONS_SYNC_TEST_H_ +#pragma once + +#include <algorithm> +#include <vector> + +#include "base/compiler_specific.h" +#include "base/scoped_vector.h" +#include "base/ref_counted.h" +#include "base/waitable_event.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_window.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/renderer_host/render_view_host_delegate.h" +#include "chrome/browser/sessions/base_session_service.h" +#include "chrome/browser/sessions/session_service_test_helper.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/test/live_sync/live_sync_test.h" +#include "chrome/test/ui_test_utils.h" +#include "googleurl/src/gurl.h" +#include "webkit/glue/window_open_disposition.h" + +// Helper for accessing session service internals. +class TestSessionService + : public SessionServiceTestHelper, + public base::RefCountedThreadSafe<TestSessionService> { + public: + TestSessionService() + : SessionServiceTestHelper(), + done_saving_(false, false), + got_windows_(false, false), + profile_(NULL), + window_bounds_(0, 1, 2, 3) {} + TestSessionService(SessionService * service, + Profile* profile) + : SessionServiceTestHelper(service), + done_saving_(false, false), + got_windows_(false, false), + profile_(profile), + window_bounds_(0, 1, 2, 3) {} + + void SetUp() { + ASSERT_TRUE(service()) << "SetUp() called without setting SessionService"; + ASSERT_TRUE(profile_); + service()->SetWindowType(window_id_, Browser::TYPE_NORMAL); + service()->SetWindowBounds(window_id_, window_bounds_, false); + } + + // Trigger saving the current session commands to file. + void Save() { + service()->Save(); + } + + // Synchronously reads the contents of the current session. + std::vector<SessionWindow*>* ReadWindows() { + // The session backend will post the callback as a task to whatever thread + // called it. In our case, we don't want the main test thread to have tasks + // posted to, so we perform the actual call to session service from the same + // thread the work will be done on (backend_thread aka file thread). As a + // result, it will directly call back, instead of posting a task, and we can + // block on that callback. + BrowserThread::PostTask( + BrowserThread::FILE, + FROM_HERE, + NewRunnableMethod(this, &TestSessionService::DoReadWindows)); + + // Wait for callback to happen. + got_windows_.Wait(); + + // By the time we reach here we've received the windows, so return them. + return windows_; + } + + // Makes the actual call to session service. + // Lives on the file thread. + void DoReadWindows() { + if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { + LOG(ERROR) << "DoReadWindows called from wrong thread!"; + windows_ = NULL; + got_windows_.Signal(); + return; + } + SessionService::SessionCallback* callback = + NewCallback(this, &TestSessionService::OnGotSession); + service()->GetCurrentSession(&consumer_, callback); + } + + // Internal method used in the callback to obtain the current session. + // Lives on and called from backend thread (file_thread). + // We don't own windows so need to make a deep copy. + void OnGotSession(int handle, std::vector<SessionWindow*>* windows) { + // Hacky. We need to make a deep copy of the session windows. One way to do + // this is to use the session model associators functionality to create + // foreign sessions, which themselves wrap a SessionWindow vector. We just + // need to make sure to destroy all the foreign sessions we created when + // we're done. That's what the foreign_sessions_ ScopedVector is for. + sync_pb::SessionSpecifics session; + profile_->GetProfileSyncService()-> + GetSessionModelAssociator()-> + FillSpecificsFromSessions(windows, &session); + + std::vector<ForeignSession*> foreign_sessions; + profile_->GetProfileSyncService()-> + GetSessionModelAssociator()-> + AppendForeignSessionFromSpecifics(&session, &foreign_sessions); + ASSERT_EQ(foreign_sessions.size(), 1U); + foreign_sessions_.push_back(foreign_sessions[0]); + windows_ = &foreign_sessions[0]->windows; + got_windows_.Signal(); + } + + private: + ~TestSessionService() { + ReleaseService(); // We don't own this, so don't destroy it. + } + + friend class base::RefCountedThreadSafe<TestSessionService>; + + // Current session buffer. + std::vector<SessionWindow*>* windows_; + + // List of all foreign sessions we created in ReadWindows. We delete them all + // at destruction time so that complex tests can keep comparing against old + // SessionWindow data. Note that since we're constantly creating new foreign + // sessions, we don't have to worry about duplicates. + ScopedVector<ForeignSession> foreign_sessions_; + + // Barrier for saving session. + base::WaitableEvent done_saving_; + + // Barrier for getting current windows in ReadWindows. + base::WaitableEvent got_windows_; + + // Consumer used to obtain the current session. + CancelableRequestConsumer consumer_; + + // Sync profile associated with this session service. + Profile* profile_; + + SessionID window_id_; + const gfx::Rect window_bounds_; +}; + +class LiveSessionsSyncTest : public LiveSyncTest { + public: + explicit LiveSessionsSyncTest(TestType test_type) + : LiveSyncTest(test_type), + done_closing_(false, false) {} + virtual ~LiveSessionsSyncTest() {} + + // Used to access the session service associated with a specific sync profile. + SessionService* GetSessionService(int index) { + return GetProfile(index)->GetSessionService(); + } + + // Used to access the session service test helper associated with a specific + // sync profile. + TestSessionService* GetHelper(int index) { + return test_session_services_[index]->get(); + } + + // Used to access the browser associated with a specific sync profile. + Browser* GetBrowser(int index) { + return browsers_[index]; + } + + // Sets up the TestSessionService helper and the new browser windows. + bool SetupClients() { + if (!LiveSyncTest::SetupClients()) { + return false; + } + + // Go through and make the TestSessionServices and Browsers. + for (int i = 0; i < num_clients(); ++i) { + scoped_refptr<TestSessionService>* new_tester = + new scoped_refptr<TestSessionService>; + *new_tester = new TestSessionService( + GetSessionService(i), GetProfile(i)); + test_session_services_.push_back(new_tester); + GetHelper(i)->SetUp(); + + browsers_.push_back(Browser::Create(GetProfile(i))); + } + + return true; + } + + // Open a single tab and return the TabContents. TabContents must be checked + // to ensure the tab opened successsfully. + TabContents* OpenTab(int index, GURL url) WARN_UNUSED_RESULT { + TabContents* tab = GetBrowser(index)-> + AddSelectedTabWithURL(url, PageTransition::START_PAGE); + + // Wait for the page to finish loading. + ui_test_utils::WaitForNavigation( + &GetBrowser(index)->GetSelectedTabContents()->controller()); + + return tab; + } + + // Creates and verifies the creation of a new window with one tab displaying + // the specified GURL. + // Returns: the SessionWindow associated with the new window. + std::vector<SessionWindow*>* InitializeNewWindowWithTab(int index, GURL url) + WARN_UNUSED_RESULT { + if (!OpenTab(index, url)) { + return NULL; + } + GetHelper(index)->Save(); + std::vector<SessionWindow*>* windows = GetHelper(index)->ReadWindows(); + if (windows->size() != 1) { + LOG(ERROR) << "InitializeNewWindowWithTab called with open windows!"; + return NULL; + } + if (1U != (*windows)[0]->tabs.size()) + return NULL; + SortSessionWindows(windows); + return windows; + } + + // Checks that window count and foreign session count are 0. + bool CheckInitialState(int index) WARN_UNUSED_RESULT { + if (0 != GetNumWindows(index)) + return false; + if (0 != GetNumForeignSessions(index)) + return false; + return true; + } + + // Returns number of open windows for a profile. + int GetNumWindows(int index) { + // We don't own windows. + std::vector<SessionWindow*>* windows = GetHelper(index)->ReadWindows(); + return windows->size(); + } + + // Returns number of foreign sessions for a profile. + int GetNumForeignSessions(int index) { + ScopedVector<ForeignSession> sessions; + if (!GetProfile(index)->GetProfileSyncService()-> + GetSessionModelAssociator()->GetSessionData(&sessions.get())) + return 0; + return sessions.size(); + } + + // Fills the sessions vector with the model associator's foreign session data. + // Caller owns sessions. + bool GetSessionData(int index, std::vector<ForeignSession*>* sessions) + WARN_UNUSED_RESULT { + if (!GetProfile(index)->GetProfileSyncService()-> + GetSessionModelAssociator()->GetSessionData(sessions)) + return false; + SortForeignSessions(sessions); + return true; + } + + // Compare session windows based on their first tab's url. + // Returns true if the virtual url of the lhs is < the rhs. + static bool CompareSessionWindows(SessionWindow* lhs, SessionWindow* rhs) { + if (!lhs || + !rhs || + lhs->tabs.size() < 1 || + rhs->tabs.size() < 1 || + lhs->tabs[0]->navigations.size() < 1 || + rhs->tabs[0]->navigations.size() < 1) { + // Catchall for uncomparable data. + return false; + } + + return lhs->tabs[0]->navigations[0].virtual_url() < + rhs->tabs[0]->navigations[0].virtual_url(); + } + + // Sort session windows using our custom comparator (first tab url + // comparison). + void SortSessionWindows(std::vector<SessionWindow*>* windows) { + std::sort(windows->begin(), windows->end(), + LiveSessionsSyncTest::CompareSessionWindows); + } + + // Compares a foreign session based on the first session window. + // Returns true based on the comparison of the session windows. + static bool CompareForeignSessions(ForeignSession* lhs, ForeignSession* rhs) { + if (!lhs || + !rhs || + lhs->windows.size() < 1 || + rhs->windows.size() < 1) { + // Catchall for uncomparable data. + return false; + } + + return CompareSessionWindows(lhs->windows[0], rhs->windows[0]); + } + + // Sort a foreign session vector using our custom foreign session comparator. + void SortForeignSessions(std::vector<ForeignSession*>* sessions) { + std::sort(sessions->begin(), sessions->end(), + LiveSessionsSyncTest::CompareForeignSessions); + } + + // Verifies that two SessionWindows match. + // Returns: + // - true if all the following match: + // 1. number of SessionWindows per vector, + // 2. number of tabs per SessionWindow, + // 3. number of tab navigations per nab, + // 4. actual tab navigations + // - false otherwise. + bool WindowsMatch(const std::vector<SessionWindow*> &win1, + const std::vector<SessionWindow*> &win2) WARN_UNUSED_RESULT { + SessionTab* client0_tab; + SessionTab* client1_tab; + if (win1.size() != win2.size()) + return false; + for (size_t i = 0; i < win1.size(); ++i) { + if (win1[i]->tabs.size() != win2[i]->tabs.size()) + return false; + for (size_t j = 0; j < win1[i]->tabs.size(); ++j) { + client0_tab = win1[i]->tabs[j]; + client1_tab = win2[i]->tabs[j]; + for (size_t k = 0; k < client0_tab->navigations.size(); ++k) { + GetHelper(0)->AssertNavigationEquals(client0_tab->navigations[k], + client1_tab->navigations[k]); + } + } + } + + return true; + } + + // Retrieves the foreign sessions for a particular profile and compares them + // with a reference SessionWindow list. + // Returns true if the session windows of the foreign session matches the + // reference. + bool CheckForeignSessionsAgainst(int index, + const std::vector<std::vector<SessionWindow*>* >& windows) + WARN_UNUSED_RESULT { + ScopedVector<ForeignSession> sessions; + if (!GetSessionData(index, &sessions.get())) + return false; + if ((size_t)(num_clients()-1) != sessions.size()) + return false; + + int window_index = 0; + for (size_t j = 0; j < sessions->size(); ++j, ++window_index) { + if (window_index == index) + window_index++; // Skip self. + if (!WindowsMatch(sessions[j]->windows, *windows[window_index])) + return false; + } + + return true; + } + + protected: + // Clean up our mess. + virtual void CleanUpOnMainThread() { + // Close all browsers. We need to do this now, as opposed to letting the + // test framework handle it, because we created our own browser for each + // sync profile. + BrowserList::CloseAllBrowsers(); + ui_test_utils::RunAllPendingInMessageLoop(); + + // All browsers should be closed at this point, else when the framework + // calls QuitBrowsers() we could see memory corruption. + ASSERT_EQ(0U, BrowserList::size()); + + LiveSyncTest::CleanUpOnMainThread(); + } + + // Vector of our TestSessionService helpers. + ScopedVector<scoped_refptr<TestSessionService> > test_session_services_; + + // Vector of our browsers for each profile. + std::vector<Browser*> browsers_; + + // Barrier for closing the browsers we create in UI thread. + base::WaitableEvent done_closing_; + + DISALLOW_COPY_AND_ASSIGN(LiveSessionsSyncTest); +}; + +class SingleClientLiveSessionsSyncTest : public LiveSessionsSyncTest { + public: + SingleClientLiveSessionsSyncTest() + : LiveSessionsSyncTest(SINGLE_CLIENT) {} + virtual ~SingleClientLiveSessionsSyncTest() {} + + private: + DISALLOW_COPY_AND_ASSIGN(SingleClientLiveSessionsSyncTest); +}; + +class TwoClientLiveSessionsSyncTest : public LiveSessionsSyncTest { + public: + TwoClientLiveSessionsSyncTest() : LiveSessionsSyncTest(TWO_CLIENT) {} + virtual ~TwoClientLiveSessionsSyncTest() {} + + private: + DISALLOW_COPY_AND_ASSIGN(TwoClientLiveSessionsSyncTest); +}; + +class MultipleClientLiveSessionsSyncTest : public LiveSessionsSyncTest { + public: + MultipleClientLiveSessionsSyncTest() + : LiveSessionsSyncTest(MULTIPLE_CLIENT) {} + virtual ~MultipleClientLiveSessionsSyncTest() {} + + private: + DISALLOW_COPY_AND_ASSIGN(MultipleClientLiveSessionsSyncTest); +}; + +#endif // CHROME_TEST_LIVE_SYNC_LIVE_SESSIONS_SYNC_TEST_H_ + diff --git a/chrome/test/live_sync/live_sync_test.cc b/chrome/test/live_sync/live_sync_test.cc index 062df35..3b0bec6 100644 --- a/chrome/test/live_sync/live_sync_test.cc +++ b/chrome/test/live_sync/live_sync_test.cc @@ -118,6 +118,11 @@ void LiveSyncTest::SetUp() { cl->AppendSwitch(switches::kSyncTrySsltcpFirstForXmpp); } + // TODO(sync): Remove this once sessions sync is enabled by default. + if (!cl->HasSwitch(switches::kEnableSyncSessions)) { + cl->AppendSwitch(switches::kEnableSyncSessions); + } + // Mock the Mac Keychain service. The real Keychain can block on user input. #if defined(OS_MACOSX) Encryptor::UseMockKeychain(true); diff --git a/chrome/test/live_sync/multiple_client_live_sessions_sync_test.cc b/chrome/test/live_sync/multiple_client_live_sessions_sync_test.cc new file mode 100644 index 0000000..f5e8e1e --- /dev/null +++ b/chrome/test/live_sync/multiple_client_live_sessions_sync_test.cc @@ -0,0 +1,33 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/stringprintf.h" +#include "chrome/test/live_sync/live_sessions_sync_test.h" + +IN_PROC_BROWSER_TEST_F(MultipleClientLiveSessionsSyncTest, AllChanged) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + std::vector<std::vector<SessionWindow*>* > client_windows; + + for (int i = 0; i < num_clients(); ++i) { + ASSERT_TRUE(CheckInitialState(i)); + } + + // Open tabs on all clients and retain window information. + for (int i = 0; i < num_clients(); ++i) { + std::vector<SessionWindow*>* new_windows = + InitializeNewWindowWithTab(i, GURL(StringPrintf("about:bubba%i", i))); + ASSERT_TRUE(new_windows); + client_windows.push_back(new_windows); + } + + // Wait for sync. + ASSERT_TRUE(AwaitQuiescence()); + + // Get foreign session data from all clients and check it against all + // client_windows. + for (int i = 0; i < num_clients(); ++i) { + ASSERT_TRUE(CheckForeignSessionsAgainst(i, client_windows)); + } +} + diff --git a/chrome/test/live_sync/single_client_live_sessions_sync_test.cc b/chrome/test/live_sync/single_client_live_sessions_sync_test.cc new file mode 100644 index 0000000..9c5b2f7 --- /dev/null +++ b/chrome/test/live_sync/single_client_live_sessions_sync_test.cc @@ -0,0 +1,30 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/scoped_vector.h" +#include "chrome/test/live_sync/live_sessions_sync_test.h" + +IN_PROC_BROWSER_TEST_F(SingleClientLiveSessionsSyncTest, Sanity) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + + ASSERT_TRUE(CheckInitialState(0)); + + std::vector<SessionWindow*>* old_windows = + InitializeNewWindowWithTab(0, GURL("about:bubba")); + ASSERT_TRUE(old_windows); + + ASSERT_TRUE(GetClient(0)->AwaitSyncCycleCompletion( + "Waiting for session change.")); + + // Get foreign session data from client 0. + ScopedVector<ForeignSession> sessions; + ASSERT_TRUE(GetSessionData(0, &sessions.get())); + ASSERT_EQ(0U, sessions.size()); + + // Verify client didn't change. + std::vector<SessionWindow*>* new_windows = GetHelper(0)->ReadWindows(); + ASSERT_TRUE(new_windows); + ASSERT_TRUE(WindowsMatch(*old_windows, *new_windows)); +} + diff --git a/chrome/test/live_sync/two_client_live_sessions_sync_test.cc b/chrome/test/live_sync/two_client_live_sessions_sync_test.cc new file mode 100644 index 0000000..c6cf184 --- /dev/null +++ b/chrome/test/live_sync/two_client_live_sessions_sync_test.cc @@ -0,0 +1,62 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/test/live_sync/live_sessions_sync_test.h" + +// @TODO(zea): Test each individual session command we care about separately. +// (as well as multi-window). We're currently only checking basic single-window/ +// single-tab functionality. + +IN_PROC_BROWSER_TEST_F(TwoClientLiveSessionsSyncTest, SingleClientChanged) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + + ASSERT_TRUE(CheckInitialState(0)); + ASSERT_TRUE(CheckInitialState(1)); + + std::vector<SessionWindow*>* client0_windows = + InitializeNewWindowWithTab(0, GURL("about:bubba")); + ASSERT_TRUE(client0_windows); + + GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)); + + // Get foreign session data from client 1. + ScopedVector<ForeignSession> sessions1; + ASSERT_TRUE(GetSessionData(1, &sessions1.get())); + + // Verify client 1's foreign session matches client 0 current window. + ASSERT_EQ(1U, sessions1.size()); + ASSERT_TRUE(WindowsMatch(sessions1[0]->windows, *client0_windows)); +} + +IN_PROC_BROWSER_TEST_F(TwoClientLiveSessionsSyncTest, BothChanged) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + + ASSERT_TRUE(CheckInitialState(0)); + ASSERT_TRUE(CheckInitialState(1)); + + // Open tabs on both clients and retain window information. + std::vector<SessionWindow*>* client0_windows = + InitializeNewWindowWithTab(0, GURL("about:bubba0")); + ASSERT_TRUE(client0_windows); + std::vector<SessionWindow*>* client1_windows = + InitializeNewWindowWithTab(1, GURL("about:bubba1")); + ASSERT_TRUE(client1_windows); + + // Wait for sync. + ASSERT_TRUE(AwaitQuiescence()); + + // Get foreign session data from client 0 and 1. + ScopedVector<ForeignSession> sessions0; + ScopedVector<ForeignSession> sessions1; + ASSERT_TRUE(GetSessionData(0, &sessions0.get())); + ASSERT_TRUE(GetSessionData(1, &sessions1.get())); + + // Verify client 1's foreign session matches client 0's current window and + // vice versa. + ASSERT_EQ(1U, sessions0.size()); + ASSERT_EQ(1U, sessions1.size()); + ASSERT_TRUE(WindowsMatch(sessions1[0]->windows, *client0_windows)); + ASSERT_TRUE(WindowsMatch(sessions0[0]->windows, *client1_windows)); +} + |