Index: chrome/browser/sync/glue/synced_session_tracker_unittest.cc |
diff --git a/chrome/browser/sync/glue/synced_session_tracker_unittest.cc b/chrome/browser/sync/glue/synced_session_tracker_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..367f1002430c7a18697624289aeb9e413a0b1139 |
--- /dev/null |
+++ b/chrome/browser/sync/glue/synced_session_tracker_unittest.cc |
@@ -0,0 +1,207 @@ |
+// Copyright (c) 2011 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 <string> |
+#include <vector> |
+ |
+#include "base/memory/scoped_ptr.h" |
+#include "base/rand_util.h" |
+#include "chrome/browser/sessions/session_types.h" |
+#include "chrome/browser/sync/glue/synced_session_tracker.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace browser_sync { |
+ |
+typedef testing::Test SyncedSessionTrackerTest; |
+ |
+TEST_F(SyncedSessionTrackerTest, GetSession) { |
+ SyncedSessionTracker tracker; |
+ SyncedSession* session1 = tracker.GetSession("tag"); |
+ SyncedSession* session2 = tracker.GetSession("tag2"); |
+ ASSERT_EQ(session1, tracker.GetSession("tag")); |
+ ASSERT_NE(session1, session2); |
+ // Should clean up memory on it's own. |
+} |
+ |
+TEST_F(SyncedSessionTrackerTest, GetTabUnmapped) { |
+ SyncedSessionTracker tracker; |
+ SessionTab* tab = tracker.GetTab("tag", 0); |
+ ASSERT_EQ(tab, tracker.GetTab("tag", 0)); |
+ // Should clean up memory on it's own. |
+} |
+ |
+TEST_F(SyncedSessionTrackerTest, GetWindow) { |
+ SyncedSessionTracker tracker; |
+ SessionWindow* window = tracker.GetWindow("tag", 0); |
+ ASSERT_EQ(window, tracker.GetWindow("tag", 0)); |
+ SyncedSession* session = tracker.GetSession("tag"); |
+ session->windows[0] = window; |
+ // Should clean up memory on it's own. |
+} |
+ |
+TEST_F(SyncedSessionTrackerTest, GetTabForWindow) { |
+ SyncedSessionTracker tracker; |
+ SessionWindow* window = tracker.GetWindow("tag", 10); |
+ SessionTab* tab = tracker.GetTabForWindow("tag", 10, 0); |
+ SyncedSession* session = tracker.GetSession("tag"); |
+ session->windows[10] = window; |
+ window->tabs.push_back(tab); |
+ // Should clean up memory on it's own. |
+} |
+ |
+TEST_F(SyncedSessionTrackerTest, Complex) { |
+ const std::string tag1 = "tag"; |
+ const std::string tag2 = "tag2"; |
+ const std::string tag3 = "tag3"; |
+ SyncedSessionTracker tracker; |
+ std::vector<SessionTab*> tabs1, tabs2; |
+ SessionTab* temp_tab; |
+ ASSERT_TRUE(tracker.empty()); |
+ ASSERT_EQ(0U, tracker.num_synced_sessions()); |
+ ASSERT_EQ(0U, tracker.num_synced_tabs(tag1)); |
+ tabs1.push_back(tracker.GetTab(tag1, 0)); |
+ tabs1.push_back(tracker.GetTab(tag1, 1)); |
+ tabs1.push_back(tracker.GetTab(tag1, 2)); |
+ ASSERT_EQ(3U, tracker.num_synced_tabs(tag1)); |
+ ASSERT_EQ(0U, tracker.num_synced_sessions()); |
+ temp_tab = tracker.GetTab(tag1, 0); // Already created. |
+ ASSERT_EQ(3U, tracker.num_synced_tabs(tag1)); |
+ ASSERT_EQ(0U, tracker.num_synced_sessions()); |
+ ASSERT_EQ(tabs1[0], temp_tab); |
+ tabs2.push_back(tracker.GetTab(tag2, 0)); |
+ ASSERT_EQ(1U, tracker.num_synced_tabs(tag2)); |
+ ASSERT_EQ(0U, tracker.num_synced_sessions()); |
+ |
+ ASSERT_FALSE(tracker.DeleteSession(tag1)); |
+ ASSERT_FALSE(tracker.DeleteSession(tag3)); |
+ |
+ SyncedSession* session = tracker.GetSession(tag1); |
+ SyncedSession* session2 = tracker.GetSession(tag2); |
+ SyncedSession* session3 = tracker.GetSession(tag3); |
+ ASSERT_EQ(3U, tracker.num_synced_sessions()); |
+ |
+ ASSERT_TRUE(session); |
+ ASSERT_TRUE(session2); |
+ ASSERT_TRUE(session3); |
+ ASSERT_NE(session, session2); |
+ ASSERT_NE(session2, session3); |
+ ASSERT_TRUE(tracker.DeleteSession(tag3)); |
+ ASSERT_EQ(2U, tracker.num_synced_sessions()); |
+ |
+ temp_tab = tracker.GetTabForWindow(tag1, 0, 2); // No longer unmapped. |
+ session->windows[0] = tracker.GetWindow(tag1, 0); // Create a window. |
+ session->windows[0]->tabs.push_back(temp_tab); // Add the tab. |
+ ASSERT_EQ(3U, tracker.num_synced_tabs(tag1)); // Has not changed. |
+ |
+ const SessionTab *tab_ptr; |
+ ASSERT_TRUE(tracker.LookupSessionTab(tag1, 0, &tab_ptr)); |
+ ASSERT_EQ(tab_ptr, tabs1[0]); |
+ ASSERT_TRUE(tracker.LookupSessionTab(tag1, 2, &tab_ptr)); |
+ ASSERT_EQ(tab_ptr, tabs1[2]); |
+ ASSERT_FALSE(tracker.LookupSessionTab(tag1, 3, &tab_ptr)); |
+ ASSERT_EQ(static_cast<const SessionTab*>(NULL), tab_ptr); |
+ |
+ std::vector<SessionWindow*> windows; |
+ ASSERT_TRUE(tracker.LookupSessionWindows(tag1, &windows)); |
+ ASSERT_EQ(1U, windows.size()); |
+ ASSERT_TRUE(tracker.LookupSessionWindows(tag2, &windows)); |
+ ASSERT_EQ(0U, windows.size()); |
+ |
+ // The sessions don't have valid tabs, lookup should not succeed. |
+ std::vector<const SyncedSession*> sessions; |
+ ASSERT_FALSE(tracker.LookupAllForeignSessions(&sessions)); |
+ |
+ tracker.clear(); |
+ ASSERT_EQ(0U, tracker.num_synced_tabs(tag1)); |
+ ASSERT_EQ(0U, tracker.num_synced_tabs(tag2)); |
+ ASSERT_EQ(0U, tracker.num_synced_sessions()); |
+} |
+ |
+TEST_F(SyncedSessionTrackerTest, ManyGetTabs) { |
+ SyncedSessionTracker tracker; |
+ ASSERT_TRUE(tracker.empty()); |
+ const int kMaxSessions = 10; |
+ const int kMaxTabs = 1000; |
+ const int kMaxAttempts = 10000; |
+ for (int j=0; j<kMaxSessions; ++j) { |
+ std::string tag = "tag" + j; |
+ for (int i=0; i<kMaxAttempts; ++i) { |
+ // More attempts than tabs means we'll sometimes get the same tabs, |
+ // sometimes have to allocate new tabs. |
+ int rand_tab_num = base::RandInt(0, kMaxTabs); |
+ SessionTab* tab = tracker.GetTab(tag, rand_tab_num); |
+ ASSERT_TRUE(tab); |
+ } |
+ } |
+} |
+ |
+TEST_F(SyncedSessionTrackerTest, SessionTracking) { |
+ SyncedSessionTracker tracker; |
+ ASSERT_TRUE(tracker.empty()); |
+ std::string tag1 = "tag1"; |
+ std::string tag2 = "tag2"; |
+ |
+ // Create some session information that is stale. |
+ SyncedSession* session1= tracker.GetSession(tag1); |
+ session1->windows[0] = tracker.GetWindow(tag1, 0); |
+ session1->windows[0]->tabs.push_back( |
+ tracker.GetTabForWindow(tag1, 0, 0)); |
+ session1->windows[0]->tabs.push_back( |
+ tracker.GetTabForWindow(tag1, 0, 1)); |
+ tracker.GetTab(tag1, 2)->window_id.set_id(0); // Will be an unmapped tab. |
+ tracker.GetTab(tag1, 3)->window_id.set_id(0); // Will be an unmapped tab. |
+ session1->windows[1] = tracker.GetWindow(tag1, 1); |
+ session1->windows[1]->tabs.push_back( |
+ tracker.GetTabForWindow(tag1, 1, 4)); |
+ session1->windows[1]->tabs.push_back( |
+ tracker.GetTabForWindow(tag1, 1, 5)); |
+ ASSERT_EQ(2U, session1->windows.size()); |
+ ASSERT_EQ(2U, session1->windows[0]->tabs.size()); |
+ ASSERT_EQ(2U, session1->windows[1]->tabs.size()); |
+ ASSERT_EQ(6U, tracker.num_synced_tabs(tag1)); |
+ |
+ // Create a session that should not be affected. |
+ SyncedSession* session2 = tracker.GetSession(tag2); |
+ session2->windows[2] = tracker.GetWindow(tag2, 2); |
+ session2->windows[2]->tabs.push_back(tracker.GetTabForWindow(tag2, 2, 1)); |
+ ASSERT_EQ(1U, session2->windows.size()); |
+ ASSERT_EQ(1U, session2->windows[2]->tabs.size()); |
+ ASSERT_EQ(1U, tracker.num_synced_tabs(tag2)); |
+ |
+ // Reset tracking and get the current windows/tabs. |
+ // We simulate moving a tab from one window to another, then closing the first |
+ // window (including it's one remaining tab), and opening a new tab on the |
+ // remaining window. |
+ tracker.ResetSessionTracking(tag1); |
+ session1->windows[0] = tracker.GetWindow(tag1, 0); |
+ session1->windows[0]->tabs.clear(); |
+ session1->windows[0]->tabs.push_back( |
+ tracker.GetTabForWindow(tag1, 0, 0)); |
+ // Tab 1 is closed. |
+ session1->windows[0]->tabs.push_back( |
+ tracker.GetTabForWindow(tag1, 0, 2)); // No longer unmapped. |
+ session1->windows[0]->tabs.push_back( |
+ tracker.GetTabForWindow(tag1, 0, 4)); // Moved from window 1. |
+ tracker.GetTab(tag1, 6); // Unmapped. |
+ session1->windows[0]->tabs.push_back( |
+ tracker.GetTabForWindow(tag1, 0, 6)); // Then no longer unmapped |
+ // Tab 3 is not used. |
+ // Window 1 was closed, along with tab 5. |
+ // Session 2 should not be affected. |
+ tracker.CleanupSession(tag1); |
+ |
+ // Verify that only those parts of the session not used have been removed. |
+ ASSERT_EQ(1U, session1->windows.size()); |
+ ASSERT_EQ(4U, session1->windows[0]->tabs.size()); |
+ ASSERT_EQ(1U, session2->windows.size()); |
+ ASSERT_EQ(1U, session2->windows[2]->tabs.size()); |
+ ASSERT_EQ(2U, tracker.num_synced_sessions()); |
+ ASSERT_EQ(4U, tracker.num_synced_tabs(tag1)); |
+ ASSERT_EQ(1U, tracker.num_synced_tabs(tag2)); |
+ |
+ // All memory should be properly deallocated by destructor for the |
+ // SyncedSessionTracker. |
+} |
+ |
+} // namespace browser_sync |