Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: chrome/browser/sync/sessions2/sessions_sync_manager_unittest.cc

Issue 79973002: sync: Route local sessions events to SessionsSyncManager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Richard's review Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/sessions2/sessions_sync_manager.h" 5 #include "chrome/browser/sync/sessions2/sessions_sync_manager.h"
6 6
7 #include "base/strings/string_util.h" 7 #include "base/strings/string_util.h"
8 #include "chrome/browser/chrome_notification_types.h" 8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/sessions/session_id.h" 9 #include "chrome/browser/sessions/session_id.h"
10 #include "chrome/browser/sessions/session_tab_helper.h" 10 #include "chrome/browser/sessions/session_tab_helper.h"
11 #include "chrome/browser/sessions/session_types.h" 11 #include "chrome/browser/sessions/session_types.h"
12 #include "chrome/browser/sync/glue/device_info.h" 12 #include "chrome/browser/sync/glue/device_info.h"
13 #include "chrome/browser/sync/glue/session_sync_test_helper.h" 13 #include "chrome/browser/sync/glue/session_sync_test_helper.h"
14 #include "chrome/browser/sync/glue/synced_tab_delegate.h" 14 #include "chrome/browser/sync/glue/synced_tab_delegate.h"
15 #include "chrome/browser/sync/sessions2/notification_service_sessions_router.h"
15 #include "chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h" 16 #include "chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h" 17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/test/base/browser_with_test_window_test.h" 18 #include "chrome/test/base/browser_with_test_window_test.h"
18 #include "components/sessions/serialized_navigation_entry_test_helper.h" 19 #include "components/sessions/serialized_navigation_entry_test_helper.h"
19 #include "content/public/browser/navigation_entry.h" 20 #include "content/public/browser/navigation_entry.h"
20 #include "content/public/browser/notification_details.h" 21 #include "content/public/browser/notification_details.h"
21 #include "content/public/browser/notification_service.h" 22 #include "content/public/browser/notification_service.h"
22 #include "content/public/browser/notification_source.h" 23 #include "content/public/browser/notification_source.h"
23 #include "content/public/browser/web_contents.h" 24 #include "content/public/browser/web_contents.h"
24 #include "sync/api/sync_error_factory_mock.h" 25 #include "sync/api/sync_error_factory_mock.h"
(...skipping 10 matching lines...) Expand all
35 36
36 namespace { 37 namespace {
37 38
38 class TestSyncProcessorStub : public syncer::SyncChangeProcessor { 39 class TestSyncProcessorStub : public syncer::SyncChangeProcessor {
39 public: 40 public:
40 explicit TestSyncProcessorStub(syncer::SyncChangeList* output) 41 explicit TestSyncProcessorStub(syncer::SyncChangeList* output)
41 : output_(output) {} 42 : output_(output) {}
42 virtual syncer::SyncError ProcessSyncChanges( 43 virtual syncer::SyncError ProcessSyncChanges(
43 const tracked_objects::Location& from_here, 44 const tracked_objects::Location& from_here,
44 const syncer::SyncChangeList& change_list) OVERRIDE { 45 const syncer::SyncChangeList& change_list) OVERRIDE {
46 if (error_.IsSet()) {
47 syncer::SyncError error = error_;
48 error_ = syncer::SyncError();
49 return error;
50 }
51
45 if (output_) 52 if (output_)
46 output_->assign(change_list.begin(), change_list.end()); 53 output_->insert(output_->end(), change_list.begin(), change_list.end());
54
47 return syncer::SyncError(); 55 return syncer::SyncError();
48 } 56 }
49 57
50 virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) 58 virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type)
51 const OVERRIDE { 59 const OVERRIDE {
52 return syncer::SyncDataList(); 60 return syncer::SyncDataList();
53 } 61 }
62
63 void FailProcessSyncChangesWith(const syncer::SyncError& error) {
64 error_ = error;
65 }
Nicolas Zea 2013/12/02 21:41:33 nit: newline after
tim (not reviewing) 2013/12/02 23:01:45 Done.
54 private: 66 private:
67 syncer::SyncError error_;
55 syncer::SyncChangeList* output_; 68 syncer::SyncChangeList* output_;
56 }; 69 };
57 70
58 syncer::SyncChange MakeRemoteChange( 71 syncer::SyncChange MakeRemoteChange(
59 int64 id, 72 int64 id,
60 const sync_pb::SessionSpecifics& specifics, 73 const sync_pb::SessionSpecifics& specifics,
61 SyncChange::SyncChangeType type) { 74 SyncChange::SyncChangeType type) {
62 sync_pb::EntitySpecifics entity; 75 sync_pb::EntitySpecifics entity;
63 entity.mutable_session()->CopyFrom(specifics); 76 entity.mutable_session()->CopyFrom(specifics);
64 return syncer::SyncChange( 77 return syncer::SyncChange(
(...skipping 20 matching lines...) Expand all
85 void AddTabsToSyncDataList(const std::vector<sync_pb::SessionSpecifics> tabs, 98 void AddTabsToSyncDataList(const std::vector<sync_pb::SessionSpecifics> tabs,
86 syncer::SyncDataList* list) { 99 syncer::SyncDataList* list) {
87 for (size_t i = 0; i < tabs.size(); i++) { 100 for (size_t i = 0; i < tabs.size(); i++) {
88 sync_pb::EntitySpecifics entity; 101 sync_pb::EntitySpecifics entity;
89 entity.mutable_session()->CopyFrom(tabs[i]); 102 entity.mutable_session()->CopyFrom(tabs[i]);
90 list->push_back(SyncData::CreateRemoteData( 103 list->push_back(SyncData::CreateRemoteData(
91 i + 2, entity, base::Time())); 104 i + 2, entity, base::Time()));
92 } 105 }
93 } 106 }
94 107
108 class DummyRouter : public LocalSessionEventRouter {
109 public:
110 virtual ~DummyRouter() {}
111 virtual void StartRoutingTo(LocalSessionEventHandler* handler) OVERRIDE {}
112 virtual void Stop() OVERRIDE {}
113 };
114
115 scoped_ptr<LocalSessionEventRouter> NewDummyRouter() {
116 return scoped_ptr<LocalSessionEventRouter>(new DummyRouter());
117 }
118
95 } // namespace 119 } // namespace
96 120
97 class SessionsSyncManagerTest 121 class SessionsSyncManagerTest
98 : public BrowserWithTestWindowTest, 122 : public BrowserWithTestWindowTest,
99 public SessionsSyncManager::SyncInternalApiDelegate { 123 public SessionsSyncManager::SyncInternalApiDelegate {
100 public: 124 public:
101 SessionsSyncManagerTest() {} 125 SessionsSyncManagerTest() : test_processor_(NULL) {}
102 126
103 virtual void SetUp() OVERRIDE { 127 virtual void SetUp() OVERRIDE {
104 BrowserWithTestWindowTest::SetUp(); 128 BrowserWithTestWindowTest::SetUp();
105 manager_.reset(new SessionsSyncManager(profile(), this)); 129 browser_sync::NotificationServiceSessionsRouter* router(
130 new browser_sync::NotificationServiceSessionsRouter(
131 profile(), syncer::SyncableService::StartSyncFlare()));
132 manager_.reset(new SessionsSyncManager(profile(), this,
133 scoped_ptr<LocalSessionEventRouter>(router)));
106 } 134 }
107 135
108 virtual void TearDown() OVERRIDE { 136 virtual void TearDown() OVERRIDE {
137 test_processor_ = NULL;
109 helper()->Reset(); 138 helper()->Reset();
110 manager_.reset(); 139 manager_.reset();
111 BrowserWithTestWindowTest::TearDown(); 140 BrowserWithTestWindowTest::TearDown();
112 } 141 }
113 142
114 virtual scoped_ptr<DeviceInfo> GetLocalDeviceInfo() const OVERRIDE { 143 virtual scoped_ptr<DeviceInfo> GetLocalDeviceInfo() const OVERRIDE {
115 return scoped_ptr<DeviceInfo>( 144 return scoped_ptr<DeviceInfo>(
116 new DeviceInfo(GetLocalSyncCacheGUID(), 145 new DeviceInfo(GetLocalSyncCacheGUID(),
117 "Wayne Gretzky's Hacking Box", 146 "Wayne Gretzky's Hacking Box",
118 "Chromium 10k", 147 "Chromium 10k",
119 "Chrome 10k", 148 "Chrome 10k",
120 sync_pb::SyncEnums_DeviceType_TYPE_LINUX)); 149 sync_pb::SyncEnums_DeviceType_TYPE_LINUX));
121 } 150 }
122 151
123 virtual std::string GetLocalSyncCacheGUID() const OVERRIDE { 152 virtual std::string GetLocalSyncCacheGUID() const OVERRIDE {
124 return "cache_guid"; 153 return "cache_guid";
125 } 154 }
126 155
127 SessionsSyncManager* manager() { return manager_.get(); } 156 SessionsSyncManager* manager() { return manager_.get(); }
128 SessionSyncTestHelper* helper() { return &helper_; } 157 SessionSyncTestHelper* helper() { return &helper_; }
129 158
130 void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data, 159 void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data,
131 syncer::SyncChangeList* output) { 160 syncer::SyncChangeList* output) {
161 test_processor_ = new TestSyncProcessorStub(output);
132 syncer::SyncMergeResult result = manager_->MergeDataAndStartSyncing( 162 syncer::SyncMergeResult result = manager_->MergeDataAndStartSyncing(
133 syncer::SESSIONS, initial_data, 163 syncer::SESSIONS, initial_data,
134 scoped_ptr<syncer::SyncChangeProcessor>( 164 scoped_ptr<syncer::SyncChangeProcessor>(test_processor_),
135 new TestSyncProcessorStub(output)),
136 scoped_ptr<syncer::SyncErrorFactory>( 165 scoped_ptr<syncer::SyncErrorFactory>(
137 new syncer::SyncErrorFactoryMock())); 166 new syncer::SyncErrorFactoryMock()));
138 EXPECT_FALSE(result.error().IsSet()); 167 EXPECT_FALSE(result.error().IsSet());
139 } 168 }
140 169
141 void InitWithNoSyncData() { 170 void InitWithNoSyncData() {
142 InitWithSyncDataTakeOutput(syncer::SyncDataList(), NULL); 171 InitWithSyncDataTakeOutput(syncer::SyncDataList(), NULL);
143 } 172 }
144 173
174 void TriggerProcessSyncChangesError() {
175 test_processor_->FailProcessSyncChangesWith(syncer::SyncError(
176 FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "Error",
177 syncer::SESSIONS));
178 }
179
145 syncer::SyncChangeList* FilterOutLocalHeaderChanges( 180 syncer::SyncChangeList* FilterOutLocalHeaderChanges(
146 syncer::SyncChangeList* list) { 181 syncer::SyncChangeList* list) {
147 syncer::SyncChangeList::iterator it = list->begin(); 182 syncer::SyncChangeList::iterator it = list->begin();
148 bool found = false; 183 bool found = false;
149 while (it != list->end()) { 184 while (it != list->end()) {
150 if (it->sync_data().GetTag() == manager_->current_machine_tag()) { 185 if (it->sync_data().GetTag() == manager_->current_machine_tag()) {
151 EXPECT_TRUE(SyncChange::ACTION_ADD == it->change_type() || 186 EXPECT_TRUE(SyncChange::ACTION_ADD == it->change_type() ||
152 SyncChange::ACTION_UPDATE == it->change_type()); 187 SyncChange::ACTION_UPDATE == it->change_type());
153 it = list->erase(it); 188 it = list->erase(it);
154 found = true; 189 found = true;
155 } else { 190 } else {
156 ++it; 191 ++it;
157 } 192 }
158 } 193 }
159 EXPECT_TRUE(found); 194 EXPECT_TRUE(found);
160 return list; 195 return list;
161 } 196 }
162 197
163 private: 198 private:
164 scoped_ptr<SessionsSyncManager> manager_; 199 scoped_ptr<SessionsSyncManager> manager_;
165 SessionSyncTestHelper helper_; 200 SessionSyncTestHelper helper_;
201 TestSyncProcessorStub* test_processor_;
166 }; 202 };
167 203
168 TEST_F(SessionsSyncManagerTest, PopulateSessionHeader) { 204 TEST_F(SessionsSyncManagerTest, PopulateSessionHeader) {
169 sync_pb::SessionHeader header_s; 205 sync_pb::SessionHeader header_s;
170 header_s.set_client_name("Client 1"); 206 header_s.set_client_name("Client 1");
171 header_s.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_WIN); 207 header_s.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_WIN);
172 208
173 SyncedSession session; 209 SyncedSession session;
174 base::Time time = base::Time::Now(); 210 base::Time time = base::Time::Now();
175 SessionsSyncManager::PopulateSessionHeaderFromSpecifics( 211 SessionsSyncManager::PopulateSessionHeaderFromSpecifics(
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 const sync_pb::SessionSpecifics& specifics2(data_2.GetSpecifics().session()); 548 const sync_pb::SessionSpecifics& specifics2(data_2.GetSpecifics().session());
513 EXPECT_EQ(manager()->current_machine_tag(), specifics2.session_tag()); 549 EXPECT_EQ(manager()->current_machine_tag(), specifics2.session_tag());
514 EXPECT_TRUE(specifics2.has_header()); 550 EXPECT_TRUE(specifics2.has_header());
515 const sync_pb::SessionHeader& header_s2 = specifics2.header(); 551 const sync_pb::SessionHeader& header_s2 = specifics2.header();
516 EXPECT_EQ(0, header_s2.window_size()); 552 EXPECT_EQ(0, header_s2.window_size());
517 553
518 // Now take that header node and feed it in as input. 554 // Now take that header node and feed it in as input.
519 SyncData d(SyncData::CreateRemoteData(1, data.GetSpecifics(), base::Time())); 555 SyncData d(SyncData::CreateRemoteData(1, data.GetSpecifics(), base::Time()));
520 syncer::SyncDataList in(&d, &d + 1); 556 syncer::SyncDataList in(&d, &d + 1);
521 out.clear(); 557 out.clear();
522 SessionsSyncManager manager2(profile(), this); 558 SessionsSyncManager manager2(profile(), this, NewDummyRouter());
523 syncer::SyncMergeResult result = manager2.MergeDataAndStartSyncing( 559 syncer::SyncMergeResult result = manager2.MergeDataAndStartSyncing(
524 syncer::SESSIONS, in, 560 syncer::SESSIONS, in,
525 scoped_ptr<syncer::SyncChangeProcessor>( 561 scoped_ptr<syncer::SyncChangeProcessor>(
526 new TestSyncProcessorStub(&out)), 562 new TestSyncProcessorStub(&out)),
527 scoped_ptr<syncer::SyncErrorFactory>( 563 scoped_ptr<syncer::SyncErrorFactory>(
528 new syncer::SyncErrorFactoryMock())); 564 new syncer::SyncErrorFactoryMock()));
529 ASSERT_FALSE(result.error().IsSet()); 565 ASSERT_FALSE(result.error().IsSet());
530 566
531 EXPECT_EQ(1U, out.size()); 567 EXPECT_EQ(1U, out.size());
532 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type()); 568 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type());
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 manager()->local_tab_pool_.GetFreeTabNode(&changes); 941 manager()->local_tab_pool_.GetFreeTabNode(&changes);
906 942
907 // Update the tab_id of the node, so that it is considered a valid 943 // Update the tab_id of the node, so that it is considered a valid
908 // unassociated node otherwise it will be mistaken for a corrupted node and 944 // unassociated node otherwise it will be mistaken for a corrupted node and
909 // will be deleted before being added to the tab node pool. 945 // will be deleted before being added to the tab node pool.
910 sync_pb::EntitySpecifics entity(changes[0].sync_data().GetSpecifics()); 946 sync_pb::EntitySpecifics entity(changes[0].sync_data().GetSpecifics());
911 entity.mutable_session()->mutable_tab()->set_tab_id(1); 947 entity.mutable_session()->mutable_tab()->set_tab_id(1);
912 SyncData d(SyncData::CreateRemoteData(1, entity, base::Time())); 948 SyncData d(SyncData::CreateRemoteData(1, entity, base::Time()));
913 syncer::SyncDataList in(&d, &d + 1); 949 syncer::SyncDataList in(&d, &d + 1);
914 changes.clear(); 950 changes.clear();
915 SessionsSyncManager manager2(profile(), this); 951 SessionsSyncManager manager2(profile(), this, NewDummyRouter());
916 syncer::SyncMergeResult result = manager2.MergeDataAndStartSyncing( 952 syncer::SyncMergeResult result = manager2.MergeDataAndStartSyncing(
917 syncer::SESSIONS, in, 953 syncer::SESSIONS, in,
918 scoped_ptr<syncer::SyncChangeProcessor>( 954 scoped_ptr<syncer::SyncChangeProcessor>(
919 new TestSyncProcessorStub(&changes)), 955 new TestSyncProcessorStub(&changes)),
920 scoped_ptr<syncer::SyncErrorFactory>( 956 scoped_ptr<syncer::SyncErrorFactory>(
921 new syncer::SyncErrorFactoryMock())); 957 new syncer::SyncErrorFactoryMock()));
922 ASSERT_FALSE(result.error().IsSet()); 958 ASSERT_FALSE(result.error().IsSet());
923 EXPECT_TRUE(FilterOutLocalHeaderChanges(&changes)->empty()); 959 EXPECT_TRUE(FilterOutLocalHeaderChanges(&changes)->empty());
924 } 960 }
925 961
926 TEST_F(SessionsSyncManagerTest, MergeDeletesCorruptNode) { 962 TEST_F(SessionsSyncManagerTest, MergeDeletesCorruptNode) {
927 syncer::SyncChangeList changes; 963 syncer::SyncChangeList changes;
928 InitWithNoSyncData(); 964 InitWithNoSyncData();
929 965
930 std::string local_tag = manager()->current_machine_tag(); 966 std::string local_tag = manager()->current_machine_tag();
931 int tab_node_id = manager()->local_tab_pool_.GetFreeTabNode(&changes); 967 int tab_node_id = manager()->local_tab_pool_.GetFreeTabNode(&changes);
932 SyncData d(SyncData::CreateRemoteData( 968 SyncData d(SyncData::CreateRemoteData(
933 1, changes[0].sync_data().GetSpecifics(), base::Time())); 969 1, changes[0].sync_data().GetSpecifics(), base::Time()));
934 syncer::SyncDataList in(&d, &d + 1); 970 syncer::SyncDataList in(&d, &d + 1);
935 changes.clear(); 971 changes.clear();
936 TearDown(); 972 TearDown();
937 SetUp(); 973 SetUp();
938 InitWithSyncDataTakeOutput(in, &changes); 974 InitWithSyncDataTakeOutput(in, &changes);
939 EXPECT_EQ(1U, FilterOutLocalHeaderChanges(&changes)->size()); 975 EXPECT_EQ(1U, FilterOutLocalHeaderChanges(&changes)->size());
940 EXPECT_EQ(SyncChange::ACTION_DELETE, changes[0].change_type()); 976 EXPECT_EQ(SyncChange::ACTION_DELETE, changes[0].change_type());
941 EXPECT_EQ(TabNodePool2::TabIdToTag(local_tag, tab_node_id), 977 EXPECT_EQ(TabNodePool2::TabIdToTag(local_tag, tab_node_id),
942 changes[0].sync_data().GetTag()); 978 changes[0].sync_data().GetTag());
943 } 979 }
944 980
981 // Test that things work if a tab is initially ignored.
945 TEST_F(SessionsSyncManagerTest, AssociateWindowsDontReloadTabs) { 982 TEST_F(SessionsSyncManagerTest, AssociateWindowsDontReloadTabs) {
946 syncer::SyncChangeList out; 983 syncer::SyncChangeList out;
947 // Go to a URL that is ignored by session syncing. 984 // Go to a URL that is ignored by session syncing.
948 AddTab(browser(), GURL("chrome://preferences/")); 985 AddTab(browser(), GURL("chrome://preferences/"));
949 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); 986 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
950 ASSERT_EQ(2U, out.size()); 987 ASSERT_EQ(2U, out.size()); // Header add and update.
951 EXPECT_EQ( 988 EXPECT_EQ(
952 0, 989 0,
953 out[1].sync_data().GetSpecifics().session().header().window_size()); 990 out[1].sync_data().GetSpecifics().session().header().window_size());
954 out.clear(); 991 out.clear();
955 992
956 // Go to a sync-interesting URL. 993 // Go to a sync-interesting URL.
957 NavigateAndCommitActiveTab(GURL("http://foo2")); 994 NavigateAndCommitActiveTab(GURL("http://foo2"));
958 995
959 // Simulate a selective association (e.g in response to tab event) as 996 EXPECT_EQ(3U, out.size()); // Tab add, update, and header update.
960 // would occur in practice from ProcessSyncChanges.
961 content::WebContents* c =
962 browser()->tab_strip_model()->GetActiveWebContents();
963 manager()->AssociateTab(SyncedTabDelegate::ImplFromWebContents(c), &out);
964 ASSERT_EQ(2U, out.size());
965 997
966 EXPECT_TRUE(StartsWithASCII(out[0].sync_data().GetTag(), 998 EXPECT_TRUE(StartsWithASCII(out[0].sync_data().GetTag(),
967 manager()->current_machine_tag(), true)); 999 manager()->current_machine_tag(), true));
968 EXPECT_EQ(manager()->current_machine_tag(), 1000 EXPECT_EQ(manager()->current_machine_tag(),
969 out[0].sync_data().GetSpecifics().session().session_tag()); 1001 out[0].sync_data().GetSpecifics().session().session_tag());
970 EXPECT_EQ(SyncChange::ACTION_ADD, out[0].change_type()); 1002 EXPECT_EQ(SyncChange::ACTION_ADD, out[0].change_type());
971 1003
972 EXPECT_TRUE(StartsWithASCII(out[1].sync_data().GetTag(), 1004 EXPECT_TRUE(StartsWithASCII(out[1].sync_data().GetTag(),
973 manager()->current_machine_tag(), true)); 1005 manager()->current_machine_tag(), true));
974 EXPECT_EQ(manager()->current_machine_tag(), 1006 EXPECT_EQ(manager()->current_machine_tag(),
975 out[1].sync_data().GetSpecifics().session().session_tag()); 1007 out[1].sync_data().GetSpecifics().session().session_tag());
976 EXPECT_TRUE(out[1].sync_data().GetSpecifics().session().has_tab()); 1008 EXPECT_TRUE(out[1].sync_data().GetSpecifics().session().has_tab());
977 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[1].change_type()); 1009 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[1].change_type());
978 1010
979 out.clear(); 1011 EXPECT_TRUE(out[2].IsValid());
980 manager()->AssociateWindows(SessionsSyncManager::DONT_RELOAD_TABS, 1012 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[2].change_type());
981 &out); 1013 const SyncData data(out[2].sync_data());
982
983 EXPECT_EQ(1U, out.size());
984 EXPECT_TRUE(out[0].IsValid());
985 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type());
986 const SyncData data(out[0].sync_data());
987 EXPECT_EQ(manager()->current_machine_tag(), data.GetTag()); 1014 EXPECT_EQ(manager()->current_machine_tag(), data.GetTag());
988 const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session()); 1015 const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
989 EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag()); 1016 EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
990 EXPECT_TRUE(specifics.has_header()); 1017 EXPECT_TRUE(specifics.has_header());
991 const sync_pb::SessionHeader& header_s = specifics.header(); 1018 const sync_pb::SessionHeader& header_s = specifics.header();
992 EXPECT_EQ(1, header_s.window_size()); 1019 EXPECT_EQ(1, header_s.window_size());
993 EXPECT_EQ(1, header_s.window(0).tab_size()); 1020 EXPECT_EQ(1, header_s.window(0).tab_size());
994 } 1021 }
995 1022
1023 TEST_F(SessionsSyncManagerTest, OnLocalTabModified) {
1024 syncer::SyncChangeList out;
1025 // Init with no local data, relies on MergeLocalSessionNoTabs.
1026 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
1027 ASSERT_FALSE(manager()->current_machine_tag().empty());
1028 ASSERT_EQ(2U, out.size());
1029
1030 // Copy the original header.
1031 sync_pb::EntitySpecifics header(out[0].sync_data().GetSpecifics());
1032 out.clear();
1033
1034 const GURL foo1("http://foo/1");
1035 const GURL foo2("http://foo/2");
1036 const GURL bar1("http://bar/1");
1037 const GURL bar2("http://bar/2");
1038 AddTab(browser(), foo1);
1039 NavigateAndCommitActiveTab(foo2);
1040 AddTab(browser(), bar1);
1041 NavigateAndCommitActiveTab(bar2);
1042
1043 // One add, one update for each AddTab.
1044 // One update for each NavigateAndCommit.
1045 // = 6 total tab updates.
1046 // One header update corresponding to each of those.
1047 // = 6 total header updates.
1048 // 12 total updates.
1049 ASSERT_EQ(12U, out.size());
1050
1051 // Verify the tab node creations and updates to ensure the SyncProcessor
1052 // sees the right operations.
1053 for (int i = 0; i < 12; i++) {
1054 SCOPED_TRACE(i);
1055 EXPECT_TRUE(out[i].IsValid());
1056 const SyncData data(out[i].sync_data());
1057 EXPECT_TRUE(StartsWithASCII(data.GetTag(),
1058 manager()->current_machine_tag(), true));
1059 const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
1060 EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
1061 if (i % 6 == 0) {
1062 // First thing on an AddTab is a no-op header update for parented tab.
1063 EXPECT_EQ(header.SerializeAsString(),
1064 data.GetSpecifics().SerializeAsString());
1065 } else if (i % 6 == 1) {
1066 // Next, the TabNodePool should create the tab node.
1067 EXPECT_EQ(SyncChange::ACTION_ADD, out[i].change_type());
1068 } else if (i % 6 == 2) {
1069 // Then we see the tab update to the URL.
1070 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
1071 ASSERT_TRUE(specifics.has_tab());
1072 } else if (i % 6 == 3) {
1073 // The header needs to be updated to reflect the new window state.
1074 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
1075 EXPECT_TRUE(specifics.has_header());
1076 } else if (i % 6 == 4) {
1077 // Now we move on to NavigateAndCommit. Update the tab.
1078 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
1079 ASSERT_TRUE(specifics.has_tab());
1080 } else if (i % 6 == 5) {
1081 // The header needs to be updated to reflect the new window state.
1082 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
1083 ASSERT_TRUE(specifics.has_header());
1084 header = data.GetSpecifics();
1085 }
1086 }
1087
1088 // Verify the actual content to ensure sync sees the right data.
1089 // When it's all said and done, the header should reflect two tabs.
1090 const sync_pb::SessionHeader& session_header = header.session().header();
1091 ASSERT_EQ(1, session_header.window_size());
1092 EXPECT_EQ(2, session_header.window(0).tab_size());
1093
1094 // ASSERT_TRUEs above allow us to dive in freely here.
1095 // Verify first tab.
1096 const sync_pb::SessionTab& tab1_1 =
1097 out[2].sync_data().GetSpecifics().session().tab();
1098 ASSERT_EQ(1, tab1_1.navigation_size());
1099 EXPECT_EQ(foo1.spec(), tab1_1.navigation(0).virtual_url());
1100 const sync_pb::SessionTab& tab1_2 =
1101 out[4].sync_data().GetSpecifics().session().tab();
1102 ASSERT_EQ(2, tab1_2.navigation_size());
1103 EXPECT_EQ(foo1.spec(), tab1_2.navigation(0).virtual_url());
1104 EXPECT_EQ(foo2.spec(), tab1_2.navigation(1).virtual_url());
1105
1106 // Verify second tab.
1107 const sync_pb::SessionTab& tab2_1 =
1108 out[8].sync_data().GetSpecifics().session().tab();
1109 ASSERT_EQ(1, tab2_1.navigation_size());
1110 EXPECT_EQ(bar1.spec(), tab2_1.navigation(0).virtual_url());
1111 const sync_pb::SessionTab& tab2_2 =
1112 out[10].sync_data().GetSpecifics().session().tab();
1113 ASSERT_EQ(2, tab2_2.navigation_size());
1114 EXPECT_EQ(bar1.spec(), tab2_2.navigation(0).virtual_url());
1115 EXPECT_EQ(bar2.spec(), tab2_2.navigation(1).virtual_url());
1116 }
1117
996 // Ensure model association associates the pre-existing tabs. 1118 // Ensure model association associates the pre-existing tabs.
997 TEST_F(SessionsSyncManagerTest, MergeLocalSessionExistingTabs) { 1119 TEST_F(SessionsSyncManagerTest, MergeLocalSessionExistingTabs) {
998 AddTab(browser(), GURL("http://foo1")); 1120 AddTab(browser(), GURL("http://foo1"));
999 NavigateAndCommitActiveTab(GURL("http://foo2")); 1121 NavigateAndCommitActiveTab(GURL("http://foo2")); // Adds back entry.
1000 AddTab(browser(), GURL("http://bar1")); 1122 AddTab(browser(), GURL("http://bar1"));
1001 NavigateAndCommitActiveTab(GURL("http://bar2")); 1123 NavigateAndCommitActiveTab(GURL("http://bar2")); // Adds back entry.
1002 1124
1003 syncer::SyncChangeList out; 1125 syncer::SyncChangeList out;
1004 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); 1126 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
1005 ASSERT_EQ(6U, out.size()); 1127 ASSERT_EQ(6U, out.size());
1006 1128
1007 // Check that this machine's data is not included in the foreign windows. 1129 // Check that this machine's data is not included in the foreign windows.
1008 std::vector<const SyncedSession*> foreign_sessions; 1130 std::vector<const SyncedSession*> foreign_sessions;
1009 ASSERT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions)); 1131 ASSERT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions));
1010 1132
1011 // Verify the header. 1133 // Verify the header.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 TEST_F(SessionsSyncManagerTest, CheckPrerenderedWebContentsSwap) { 1192 TEST_F(SessionsSyncManagerTest, CheckPrerenderedWebContentsSwap) {
1071 AddTab(browser(), GURL("http://foo1")); 1193 AddTab(browser(), GURL("http://foo1"));
1072 NavigateAndCommitActiveTab(GURL("http://foo2")); 1194 NavigateAndCommitActiveTab(GURL("http://foo2"));
1073 1195
1074 syncer::SyncChangeList out; 1196 syncer::SyncChangeList out;
1075 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); 1197 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
1076 ASSERT_EQ(4U, out.size()); // Header, tab ADD, tab UPDATE, header UPDATE. 1198 ASSERT_EQ(4U, out.size()); // Header, tab ADD, tab UPDATE, header UPDATE.
1077 1199
1078 // To simulate WebContents swap during prerendering, create new WebContents 1200 // To simulate WebContents swap during prerendering, create new WebContents
1079 // and swap with old WebContents. 1201 // and swap with old WebContents.
1080 content::WebContents* old_web_contents = 1202 scoped_ptr<content::WebContents> old_web_contents;
1081 browser()->tab_strip_model()->GetActiveWebContents(); 1203 old_web_contents.reset(browser()->tab_strip_model()->GetActiveWebContents());
1082 1204
1083 // Create new WebContents, with the required tab helpers. 1205 // Create new WebContents, with the required tab helpers.
1084 WebContents* new_web_contents = WebContents::CreateWithSessionStorage( 1206 WebContents* new_web_contents = WebContents::CreateWithSessionStorage(
1085 WebContents::CreateParams(profile()), 1207 WebContents::CreateParams(profile()),
1086 old_web_contents->GetController().GetSessionStorageNamespaceMap()); 1208 old_web_contents->GetController().GetSessionStorageNamespaceMap());
1087 SessionTabHelper::CreateForWebContents(new_web_contents); 1209 SessionTabHelper::CreateForWebContents(new_web_contents);
1088 TabContentsSyncedTabDelegate::CreateForWebContents(new_web_contents); 1210 TabContentsSyncedTabDelegate::CreateForWebContents(new_web_contents);
1089 new_web_contents->GetController() 1211 new_web_contents->GetController()
1090 .CopyStateFrom(old_web_contents->GetController()); 1212 .CopyStateFrom(old_web_contents->GetController());
1091 1213
1092 // Swap the WebContents. 1214 // Swap the WebContents.
1093 int index = 1215 int index = browser()->tab_strip_model()->GetIndexOfWebContents(
1094 browser()->tab_strip_model()->GetIndexOfWebContents(old_web_contents); 1216 old_web_contents.get());
1095 browser()->tab_strip_model()->ReplaceWebContentsAt(index, new_web_contents); 1217 browser()->tab_strip_model()->ReplaceWebContentsAt(index, new_web_contents);
1096 1218
1097 manager()->AssociateWindows(SessionsSyncManager::RELOAD_TABS, &out); 1219 ASSERT_EQ(9U, out.size());
1098 ASSERT_EQ(7U, out.size());
1099 EXPECT_EQ(SyncChange::ACTION_ADD, out[4].change_type()); 1220 EXPECT_EQ(SyncChange::ACTION_ADD, out[4].change_type());
1100 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[5].change_type()); 1221 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[5].change_type());
1101 1222
1102 // Navigate away. 1223 // Navigate away.
1103 NavigateAndCommitActiveTab(GURL("http://bar2")); 1224 NavigateAndCommitActiveTab(GURL("http://bar2"));
1104 manager()->AssociateWindows(SessionsSyncManager::RELOAD_TABS, &out);
1105 1225
1106 // Delete old WebContents. This should not crash. 1226 // Delete old WebContents. This should not crash.
1107 delete old_web_contents; 1227 old_web_contents.reset();
1108 manager()->AssociateWindows(SessionsSyncManager::RELOAD_TABS, &out);
1109 1228
1110 // Try more navigations and verify output size. This can also reveal 1229 // Try more navigations and verify output size. This can also reveal
1111 // bugs (leaks) on memcheck bots if the SessionSyncManager 1230 // bugs (leaks) on memcheck bots if the SessionSyncManager
1112 // didn't properly clean up the tab pool or session tracker. 1231 // didn't properly clean up the tab pool or session tracker.
1113 NavigateAndCommitActiveTab(GURL("http://bar3")); 1232 NavigateAndCommitActiveTab(GURL("http://bar3"));
1114 manager()->AssociateWindows(SessionsSyncManager::RELOAD_TABS, &out);
1115 1233
1116 AddTab(browser(), GURL("http://bar4")); 1234 AddTab(browser(), GURL("http://bar4"));
1117 manager()->AssociateWindows(SessionsSyncManager::RELOAD_TABS, &out);
1118 NavigateAndCommitActiveTab(GURL("http://bar5")); 1235 NavigateAndCommitActiveTab(GURL("http://bar5"));
1119 manager()->AssociateWindows(SessionsSyncManager::RELOAD_TABS, &out); 1236 ASSERT_EQ(19U, out.size());
1120 ASSERT_EQ(20U, out.size());
1121 } 1237 }
1122 1238
1123 namespace { 1239 namespace {
1124 class SessionNotificationObserver : public content::NotificationObserver { 1240 class SessionNotificationObserver : public content::NotificationObserver {
1125 public: 1241 public:
1126 SessionNotificationObserver() : notified_of_update_(false) { 1242 SessionNotificationObserver() : notified_of_update_(false),
1243 notified_of_refresh_(false) {
1127 registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED, 1244 registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED,
1128 content::NotificationService::AllSources()); 1245 content::NotificationService::AllSources());
1246 registrar_.Add(this, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
1247 content::NotificationService::AllSources());
1129 } 1248 }
1130 virtual void Observe(int type, 1249 virtual void Observe(int type,
1131 const content::NotificationSource& source, 1250 const content::NotificationSource& source,
1132 const content::NotificationDetails& details) OVERRIDE { 1251 const content::NotificationDetails& details) OVERRIDE {
1133 switch (type) { 1252 switch (type) {
1134 case chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED: 1253 case chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED:
1135 notified_of_update_ = true; 1254 notified_of_update_ = true;
1136 break; 1255 break;
1256 case chrome::NOTIFICATION_SYNC_REFRESH_LOCAL:
1257 notified_of_refresh_ = true;
1258 break;
1137 default: 1259 default:
1138 NOTREACHED(); 1260 NOTREACHED();
1139 break; 1261 break;
1140 } 1262 }
1141 } 1263 }
1142 bool notified_of_update() const { return notified_of_update_; } 1264 bool notified_of_update() const { return notified_of_update_; }
1143 void Reset() { notified_of_update_ = false; } 1265 bool notified_of_refresh() const { return notified_of_refresh_; }
1266 void Reset() {
1267 notified_of_update_ = false;
1268 notified_of_refresh_ = false;
1269 }
1144 private: 1270 private:
1145 content::NotificationRegistrar registrar_; 1271 content::NotificationRegistrar registrar_;
1146 bool notified_of_update_; 1272 bool notified_of_update_;
1273 bool notified_of_refresh_;
1147 }; 1274 };
1148 } // namespace 1275 } // namespace
1149 1276
1150 TEST_F(SessionsSyncManagerTest, NotifiedOfUpdates) { 1277 TEST_F(SessionsSyncManagerTest, NotifiedOfUpdates) {
1151 SessionNotificationObserver observer; 1278 SessionNotificationObserver observer;
1279 ASSERT_FALSE(observer.notified_of_update());
1152 InitWithNoSyncData(); 1280 InitWithNoSyncData();
1153 1281
1154 SessionID::id_type n[] = {5}; 1282 SessionID::id_type n[] = {5};
1155 std::vector<sync_pb::SessionSpecifics> tabs1; 1283 std::vector<sync_pb::SessionSpecifics> tabs1;
1156 std::vector<SessionID::id_type> tab_list(n, n + arraysize(n)); 1284 std::vector<SessionID::id_type> tab_list(n, n + arraysize(n));
1157 sync_pb::SessionSpecifics meta(helper()->BuildForeignSession( 1285 sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
1158 "tag1", tab_list, &tabs1)); 1286 "tag1", tab_list, &tabs1));
1159 1287
1160 syncer::SyncChangeList changes; 1288 syncer::SyncChangeList changes;
1161 changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD)); 1289 changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD));
1162 manager()->ProcessSyncChanges(FROM_HERE, changes); 1290 manager()->ProcessSyncChanges(FROM_HERE, changes);
1163 EXPECT_TRUE(observer.notified_of_update()); 1291 EXPECT_TRUE(observer.notified_of_update());
1164 1292
1165 changes.clear(); 1293 changes.clear();
1166 observer.Reset(); 1294 observer.Reset();
1167 AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &changes); 1295 AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &changes);
1168 manager()->ProcessSyncChanges(FROM_HERE, changes); 1296 manager()->ProcessSyncChanges(FROM_HERE, changes);
1169 EXPECT_TRUE(observer.notified_of_update()); 1297 EXPECT_TRUE(observer.notified_of_update());
1170 1298
1171 changes.clear(); 1299 changes.clear();
1172 observer.Reset(); 1300 observer.Reset();
1173 changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_DELETE)); 1301 changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_DELETE));
1174 manager()->ProcessSyncChanges(FROM_HERE, changes); 1302 manager()->ProcessSyncChanges(FROM_HERE, changes);
1175 EXPECT_TRUE(observer.notified_of_update()); 1303 EXPECT_TRUE(observer.notified_of_update());
1176 } 1304 }
1177 1305
1306 #if defined(OS_ANDROID) || defined(OS_IOS)
1307 // Tests that opening the other devices page triggers a session sync refresh.
1308 // This page only exists on mobile platforms today; desktop has a
1309 // search-enhanced NTP without other devices.
1310 TEST_F(SessionsSyncManagerTest, NotifiedOfRefresh) {
1311 SessionNotificationObserver observer;
1312 ASSERT_FALSE(observer.notified_of_refresh());
1313 InitWithNoSyncData();
1314 AddTab(browser(), GURL("http://foo1"));
1315 EXPECT_FALSE(observer.notified_of_refresh());
1316 NavigateAndCommitActiveTab(GURL("chrome://newtab/#open_tabs"));
1317 EXPECT_TRUE(observer.notified_of_refresh());
1318 }
1319 #endif // defined(OS_ANDROID) || defined(OS_IOS)
1320
1178 } // namespace browser_sync 1321 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698