| 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/sessions_helper.h" | |
| 6 | |
| 7 #include "base/stl_util.h" | |
| 8 #include "base/test/test_timeouts.h" | |
| 9 #include "base/time.h" | |
| 10 #include "chrome/browser/profiles/profile.h" | |
| 11 #include "chrome/browser/sync/profile_sync_service.h" | |
| 12 #include "chrome/browser/sync/profile_sync_service_harness.h" | |
| 13 #include "chrome/browser/sync/glue/session_model_associator.h" | |
| 14 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | |
| 15 #include "chrome/test/base/ui_test_utils.h" | |
| 16 #include "chrome/test/live_sync/sync_datatype_helper.h" | |
| 17 #include "chrome/test/live_sync/live_sync_test.h" | |
| 18 #include "content/browser/browser_thread.h" | |
| 19 #include "content/browser/tab_contents/tab_contents.h" | |
| 20 #include "googleurl/src/gurl.h" | |
| 21 | |
| 22 using sync_datatype_helper::test; | |
| 23 | |
| 24 namespace sessions_helper { | |
| 25 | |
| 26 bool GetLocalSession(int index, const SyncedSession** session) { | |
| 27 return test()->GetProfile(index)->GetProfileSyncService()-> | |
| 28 GetSessionModelAssociator()->GetLocalSession(session); | |
| 29 } | |
| 30 | |
| 31 bool ModelAssociatorHasTabWithUrl(int index, const GURL& url) { | |
| 32 ui_test_utils::RunAllPendingInMessageLoop(); | |
| 33 const SyncedSession* local_session; | |
| 34 if (!GetLocalSession(index, &local_session)) { | |
| 35 return false; | |
| 36 } | |
| 37 | |
| 38 if (local_session->windows.size() == 0) { | |
| 39 VLOG(1) << "Empty windows vector"; | |
| 40 return false; | |
| 41 } | |
| 42 | |
| 43 int nav_index; | |
| 44 TabNavigation nav; | |
| 45 for (SessionWindowVector::const_iterator it = | |
| 46 local_session->windows.begin(); it != local_session->windows.end(); | |
| 47 ++it) { | |
| 48 if ((*it)->tabs.size() == 0) { | |
| 49 VLOG(1) << "Empty tabs vector"; | |
| 50 continue; | |
| 51 } | |
| 52 for (std::vector<SessionTab*>::const_iterator tab_it = | |
| 53 (*it)->tabs.begin(); tab_it != (*it)->tabs.end(); ++tab_it) { | |
| 54 if ((*tab_it)->navigations.size() == 0) { | |
| 55 VLOG(1) << "Empty navigations vector"; | |
| 56 continue; | |
| 57 } | |
| 58 nav_index = (*tab_it)->current_navigation_index; | |
| 59 nav = (*tab_it)->navigations[nav_index]; | |
| 60 if (nav.virtual_url() == url) { | |
| 61 VLOG(1) << "Found tab with url " << url.spec(); | |
| 62 if (nav.title().empty()) { | |
| 63 VLOG(1) << "No title!"; | |
| 64 continue; | |
| 65 } | |
| 66 return true; | |
| 67 } | |
| 68 } | |
| 69 } | |
| 70 VLOG(1) << "Could not find tab with url " << url.spec(); | |
| 71 return false; | |
| 72 } | |
| 73 | |
| 74 bool OpenTab(int index, const GURL& url) { | |
| 75 VLOG(1) << "Opening tab: " << url.spec() << " using profile " << index << "."; | |
| 76 test()->GetBrowser(index)->ShowSingletonTab(url); | |
| 77 return WaitForTabsToLoad(index, std::vector<GURL>(1, url)); | |
| 78 } | |
| 79 | |
| 80 bool OpenMultipleTabs(int index, const std::vector<GURL>& urls) { | |
| 81 Browser* browser = test()->GetBrowser(index); | |
| 82 for (std::vector<GURL>::const_iterator it = urls.begin(); | |
| 83 it != urls.end(); ++it) { | |
| 84 VLOG(1) << "Opening tab: " << it->spec() << " using profile " << index | |
| 85 << "."; | |
| 86 browser->ShowSingletonTab(*it); | |
| 87 } | |
| 88 return WaitForTabsToLoad(index, urls); | |
| 89 } | |
| 90 | |
| 91 bool WaitForTabsToLoad(int index, const std::vector<GURL>& urls) { | |
| 92 VLOG(1) << "Waiting for session to propagate to associator."; | |
| 93 static const int timeout_milli = TestTimeouts::action_max_timeout_ms(); | |
| 94 base::TimeTicks start_time = base::TimeTicks::Now(); | |
| 95 base::TimeTicks end_time = start_time + | |
| 96 base::TimeDelta::FromMilliseconds(timeout_milli); | |
| 97 bool found; | |
| 98 for (std::vector<GURL>::const_iterator it = urls.begin(); | |
| 99 it != urls.end(); ++it) { | |
| 100 found = false; | |
| 101 while (!found) { | |
| 102 found = ModelAssociatorHasTabWithUrl(index, *it); | |
| 103 if (base::TimeTicks::Now() >= end_time) { | |
| 104 LOG(ERROR) << "Failed to find all tabs after " << timeout_milli/1000.0 | |
| 105 << " seconds."; | |
| 106 return false; | |
| 107 } | |
| 108 if (!found) { | |
| 109 test()->GetProfile(index)->GetProfileSyncService()-> | |
| 110 GetSessionModelAssociator()-> | |
| 111 BlockUntilLocalChangeForTest(timeout_milli); | |
| 112 ui_test_utils::RunMessageLoop(); | |
| 113 } | |
| 114 } | |
| 115 } | |
| 116 return true; | |
| 117 } | |
| 118 | |
| 119 bool GetLocalWindows(int index, SessionWindowVector& local_windows) { | |
| 120 // The local session provided by GetLocalSession is owned, and has lifetime | |
| 121 // controlled, by the model associator, so we must make our own copy. | |
| 122 const SyncedSession* local_session; | |
| 123 if (!GetLocalSession(index, &local_session)) { | |
| 124 return false; | |
| 125 } | |
| 126 for (size_t w = 0; w < local_session->windows.size(); ++w) { | |
| 127 const SessionWindow& window = *local_session->windows.at(w); | |
| 128 SessionWindow* new_window = new SessionWindow(); | |
| 129 for (size_t t = 0; t < window.tabs.size(); ++t) { | |
| 130 const SessionTab& tab = *window.tabs.at(t); | |
| 131 SessionTab* new_tab = new SessionTab(); | |
| 132 new_tab->navigations.resize(tab.navigations.size()); | |
| 133 std::copy(tab.navigations.begin(), tab.navigations.end(), | |
| 134 new_tab->navigations.begin()); | |
| 135 new_window->tabs.push_back(new_tab); | |
| 136 } | |
| 137 local_windows.push_back(new_window); | |
| 138 } | |
| 139 | |
| 140 // Sort the windows so their order is deterministic. | |
| 141 SortSessionWindows(local_windows); | |
| 142 | |
| 143 return true; | |
| 144 } | |
| 145 | |
| 146 bool OpenTabAndGetLocalWindows(int index, | |
| 147 const GURL& url, | |
| 148 SessionWindowVector& local_windows) { | |
| 149 if (!OpenTab(index, url)) { | |
| 150 return false; | |
| 151 } | |
| 152 return GetLocalWindows(index, local_windows); | |
| 153 } | |
| 154 | |
| 155 bool CheckInitialState(int index) { | |
| 156 if (0 != GetNumWindows(index)) | |
| 157 return false; | |
| 158 if (0 != GetNumForeignSessions(index)) | |
| 159 return false; | |
| 160 return true; | |
| 161 } | |
| 162 | |
| 163 int GetNumWindows(int index) { | |
| 164 const SyncedSession* local_session; | |
| 165 if (!GetLocalSession(index, &local_session)) { | |
| 166 return 0; | |
| 167 } | |
| 168 return local_session->windows.size(); | |
| 169 } | |
| 170 | |
| 171 int GetNumForeignSessions(int index) { | |
| 172 SyncedSessionVector sessions; | |
| 173 if (!test()->GetProfile(index)->GetProfileSyncService()-> | |
| 174 GetSessionModelAssociator()->GetAllForeignSessions(&sessions)) | |
| 175 return 0; | |
| 176 return sessions.size(); | |
| 177 } | |
| 178 | |
| 179 bool GetSessionData(int index, SyncedSessionVector* sessions) { | |
| 180 if (!test()->GetProfile(index)->GetProfileSyncService()-> | |
| 181 GetSessionModelAssociator()->GetAllForeignSessions(sessions)) | |
| 182 return false; | |
| 183 SortSyncedSessions(sessions); | |
| 184 return true; | |
| 185 } | |
| 186 | |
| 187 bool CompareSessionWindows(SessionWindow* lhs, SessionWindow* rhs) { | |
| 188 if (!lhs || | |
| 189 !rhs || | |
| 190 lhs->tabs.size() < 1 || | |
| 191 rhs->tabs.size() < 1 || | |
| 192 lhs->tabs[0]->navigations.size() < 1 || | |
| 193 rhs->tabs[0]->navigations.size() < 1) { | |
| 194 // Catchall for uncomparable data. | |
| 195 return false; | |
| 196 } | |
| 197 | |
| 198 return lhs->tabs[0]->navigations[0].virtual_url() < | |
| 199 rhs->tabs[0]->navigations[0].virtual_url(); | |
| 200 } | |
| 201 | |
| 202 void SortSessionWindows(SessionWindowVector& windows) { | |
| 203 std::sort(windows.begin(), windows.end(), | |
| 204 CompareSessionWindows); | |
| 205 } | |
| 206 | |
| 207 bool CompareSyncedSessions(const SyncedSession* lhs, const SyncedSession* rhs) { | |
| 208 if (!lhs || | |
| 209 !rhs || | |
| 210 lhs->windows.size() < 1 || | |
| 211 rhs->windows.size() < 1) { | |
| 212 // Catchall for uncomparable data. | |
| 213 return false; | |
| 214 } | |
| 215 | |
| 216 return CompareSessionWindows(lhs->windows[0], rhs->windows[0]); | |
| 217 } | |
| 218 | |
| 219 void SortSyncedSessions(SyncedSessionVector* sessions) { | |
| 220 std::sort(sessions->begin(), sessions->end(), | |
| 221 CompareSyncedSessions); | |
| 222 } | |
| 223 | |
| 224 bool NavigationEquals(const TabNavigation& expected, | |
| 225 const TabNavigation& actual) { | |
| 226 if (expected.virtual_url() != actual.virtual_url()) { | |
| 227 LOG(ERROR) << "Expected url " << expected.virtual_url() | |
| 228 << ", actual " << actual.virtual_url(); | |
| 229 return false; | |
| 230 } | |
| 231 if (expected.referrer() != actual.referrer()) { | |
| 232 LOG(ERROR) << "Expected referrer " << expected.referrer() | |
| 233 << ", actual " << actual.referrer(); | |
| 234 return false; | |
| 235 } | |
| 236 if (expected.title() != actual.title()) { | |
| 237 LOG(ERROR) << "Expected title " << expected.title() | |
| 238 << ", actual " << actual.title(); | |
| 239 return false; | |
| 240 } | |
| 241 if (expected.transition() != actual.transition()) { | |
| 242 LOG(ERROR) << "Expected transition " << expected.transition() | |
| 243 << ", actual " << actual.transition(); | |
| 244 return false; | |
| 245 } | |
| 246 return true; | |
| 247 } | |
| 248 | |
| 249 bool WindowsMatch(const SessionWindowVector& win1, | |
| 250 const SessionWindowVector& win2) { | |
| 251 SessionTab* client0_tab; | |
| 252 SessionTab* client1_tab; | |
| 253 if (win1.size() != win2.size()) | |
| 254 return false; | |
| 255 for (size_t i = 0; i < win1.size(); ++i) { | |
| 256 if (win1[i]->tabs.size() != win2[i]->tabs.size()) | |
| 257 return false; | |
| 258 for (size_t j = 0; j < win1[i]->tabs.size(); ++j) { | |
| 259 client0_tab = win1[i]->tabs[j]; | |
| 260 client1_tab = win2[i]->tabs[j]; | |
| 261 for (size_t k = 0; k < client0_tab->navigations.size(); ++k) { | |
| 262 if (!NavigationEquals(client0_tab->navigations[k], | |
| 263 client1_tab->navigations[k])) { | |
| 264 return false; | |
| 265 } | |
| 266 } | |
| 267 } | |
| 268 } | |
| 269 | |
| 270 return true; | |
| 271 } | |
| 272 | |
| 273 bool CheckForeignSessionsAgainst( | |
| 274 int index, | |
| 275 const std::vector<SessionWindowVector*>& windows) { | |
| 276 SyncedSessionVector sessions; | |
| 277 if (!GetSessionData(index, &sessions)) | |
| 278 return false; | |
| 279 if ((size_t)(test()->num_clients()-1) != sessions.size()) | |
| 280 return false; | |
| 281 | |
| 282 int window_index = 0; | |
| 283 for (size_t j = 0; j < sessions.size(); ++j, ++window_index) { | |
| 284 if (window_index == index) | |
| 285 window_index++; // Skip self. | |
| 286 if (!WindowsMatch(sessions[j]->windows, *windows[window_index])) | |
| 287 return false; | |
| 288 } | |
| 289 | |
| 290 return true; | |
| 291 } | |
| 292 | |
| 293 } // namespace sessions_helper | |
| OLD | NEW |