OLD | NEW |
---|---|
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 Loading... | |
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 } | |
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 Loading... | |
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 SessionsSyncManager::LocalEventRouter { | |
109 public: | |
110 virtual ~DummyRouter() {} | |
111 virtual void StartRoutingTo(LocalSessionEventHandler* handler) OVERRIDE {} | |
112 virtual void Stop() OVERRIDE {} | |
113 }; | |
114 | |
115 scoped_ptr<SessionsSyncManager::LocalEventRouter> NewDummyRouter() { | |
116 return scoped_ptr<SessionsSyncManager::LocalEventRouter>(new DummyRouter()); | |
117 } | |
118 | |
95 } // namespace | 119 } // namespace |
96 | 120 |
97 class SessionsSyncManagerTest | 121 class SessionsSyncManagerTest |
98 : public BrowserWithTestWindowTest, | 122 : public BrowserWithTestWindowTest, |
Nicolas Zea
2013/11/21 02:34:52
now that you're abstracting away all the real inte
tim (not reviewing)
2013/11/21 21:38:59
I was thinking the same when creating the LocalEve
Nicolas Zea
2013/11/22 23:34:51
sgtm
| |
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(profile())); | |
131 router->set_flare(syncer::SyncableService::StartSyncFlare()); | |
132 manager_.reset(new SessionsSyncManager(profile(), this, | |
133 scoped_ptr<SessionsSyncManager::LocalEventRouter>(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>( |
135 new TestSyncProcessorStub(output)), | 165 test_processor_), |
Nicolas Zea
2013/11/21 02:34:52
nit: fits on previous line?
tim (not reviewing)
2013/11/21 21:38:59
Done.
| |
136 scoped_ptr<syncer::SyncErrorFactory>( | 166 scoped_ptr<syncer::SyncErrorFactory>( |
137 new syncer::SyncErrorFactoryMock())); | 167 new syncer::SyncErrorFactoryMock())); |
138 EXPECT_FALSE(result.error().IsSet()); | 168 EXPECT_FALSE(result.error().IsSet()); |
139 } | 169 } |
140 | 170 |
141 void InitWithNoSyncData() { | 171 void InitWithNoSyncData() { |
142 InitWithSyncDataTakeOutput(syncer::SyncDataList(), NULL); | 172 InitWithSyncDataTakeOutput(syncer::SyncDataList(), NULL); |
143 } | 173 } |
144 | 174 |
175 void TriggerProcessSyncChangesError() { | |
176 test_processor_->FailProcessSyncChangesWith(syncer::SyncError( | |
177 FROM_HERE, syncer::SyncError::PERSISTENCE_ERROR, "Error", | |
Nicolas Zea
2013/11/21 02:34:52
nit: prefer something other than persistence error
tim (not reviewing)
2013/11/21 21:38:59
Ah. I actually wasn't clear on the difference fro
| |
178 syncer::SESSIONS)); | |
179 } | |
180 | |
145 syncer::SyncChangeList* FilterOutLocalHeaderChanges( | 181 syncer::SyncChangeList* FilterOutLocalHeaderChanges( |
146 syncer::SyncChangeList* list) { | 182 syncer::SyncChangeList* list) { |
147 syncer::SyncChangeList::iterator it = list->begin(); | 183 syncer::SyncChangeList::iterator it = list->begin(); |
148 bool found = false; | 184 bool found = false; |
149 while (it != list->end()) { | 185 while (it != list->end()) { |
150 if (it->sync_data().GetTag() == manager_->current_machine_tag()) { | 186 if (it->sync_data().GetTag() == manager_->current_machine_tag()) { |
151 EXPECT_TRUE(SyncChange::ACTION_ADD == it->change_type() || | 187 EXPECT_TRUE(SyncChange::ACTION_ADD == it->change_type() || |
152 SyncChange::ACTION_UPDATE == it->change_type()); | 188 SyncChange::ACTION_UPDATE == it->change_type()); |
153 it = list->erase(it); | 189 it = list->erase(it); |
154 found = true; | 190 found = true; |
155 } else { | 191 } else { |
156 ++it; | 192 ++it; |
157 } | 193 } |
158 } | 194 } |
159 EXPECT_TRUE(found); | 195 EXPECT_TRUE(found); |
160 return list; | 196 return list; |
161 } | 197 } |
162 | 198 |
163 private: | 199 private: |
164 scoped_ptr<SessionsSyncManager> manager_; | 200 scoped_ptr<SessionsSyncManager> manager_; |
165 SessionSyncTestHelper helper_; | 201 SessionSyncTestHelper helper_; |
202 TestSyncProcessorStub* test_processor_; | |
166 }; | 203 }; |
167 | 204 |
168 TEST_F(SessionsSyncManagerTest, PopulateSessionHeader) { | 205 TEST_F(SessionsSyncManagerTest, PopulateSessionHeader) { |
169 sync_pb::SessionHeader header_s; | 206 sync_pb::SessionHeader header_s; |
170 header_s.set_client_name("Client 1"); | 207 header_s.set_client_name("Client 1"); |
171 header_s.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_WIN); | 208 header_s.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_WIN); |
172 | 209 |
173 SyncedSession session; | 210 SyncedSession session; |
174 base::Time time = base::Time::Now(); | 211 base::Time time = base::Time::Now(); |
175 SessionsSyncManager::PopulateSessionHeaderFromSpecifics( | 212 SessionsSyncManager::PopulateSessionHeaderFromSpecifics( |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
512 const sync_pb::SessionSpecifics& specifics2(data_2.GetSpecifics().session()); | 549 const sync_pb::SessionSpecifics& specifics2(data_2.GetSpecifics().session()); |
513 EXPECT_EQ(manager()->current_machine_tag(), specifics2.session_tag()); | 550 EXPECT_EQ(manager()->current_machine_tag(), specifics2.session_tag()); |
514 EXPECT_TRUE(specifics2.has_header()); | 551 EXPECT_TRUE(specifics2.has_header()); |
515 const sync_pb::SessionHeader& header_s2 = specifics2.header(); | 552 const sync_pb::SessionHeader& header_s2 = specifics2.header(); |
516 EXPECT_EQ(0, header_s2.window_size()); | 553 EXPECT_EQ(0, header_s2.window_size()); |
517 | 554 |
518 // Now take that header node and feed it in as input. | 555 // Now take that header node and feed it in as input. |
519 SyncData d(SyncData::CreateRemoteData(1, data.GetSpecifics(), base::Time())); | 556 SyncData d(SyncData::CreateRemoteData(1, data.GetSpecifics(), base::Time())); |
520 syncer::SyncDataList in(&d, &d + 1); | 557 syncer::SyncDataList in(&d, &d + 1); |
521 out.clear(); | 558 out.clear(); |
522 SessionsSyncManager manager2(profile(), this); | 559 SessionsSyncManager manager2(profile(), this, NewDummyRouter()); |
523 syncer::SyncMergeResult result = manager2.MergeDataAndStartSyncing( | 560 syncer::SyncMergeResult result = manager2.MergeDataAndStartSyncing( |
524 syncer::SESSIONS, in, | 561 syncer::SESSIONS, in, |
525 scoped_ptr<syncer::SyncChangeProcessor>( | 562 scoped_ptr<syncer::SyncChangeProcessor>( |
526 new TestSyncProcessorStub(&out)), | 563 new TestSyncProcessorStub(&out)), |
527 scoped_ptr<syncer::SyncErrorFactory>( | 564 scoped_ptr<syncer::SyncErrorFactory>( |
528 new syncer::SyncErrorFactoryMock())); | 565 new syncer::SyncErrorFactoryMock())); |
529 ASSERT_FALSE(result.error().IsSet()); | 566 ASSERT_FALSE(result.error().IsSet()); |
530 | 567 |
531 EXPECT_EQ(1U, out.size()); | 568 EXPECT_EQ(1U, out.size()); |
532 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type()); | 569 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type()); |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
905 manager()->local_tab_pool_.GetFreeTabNode(&changes); | 942 manager()->local_tab_pool_.GetFreeTabNode(&changes); |
906 | 943 |
907 // Update the tab_id of the node, so that it is considered a valid | 944 // 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 | 945 // unassociated node otherwise it will be mistaken for a corrupted node and |
909 // will be deleted before being added to the tab node pool. | 946 // will be deleted before being added to the tab node pool. |
910 sync_pb::EntitySpecifics entity(changes[0].sync_data().GetSpecifics()); | 947 sync_pb::EntitySpecifics entity(changes[0].sync_data().GetSpecifics()); |
911 entity.mutable_session()->mutable_tab()->set_tab_id(1); | 948 entity.mutable_session()->mutable_tab()->set_tab_id(1); |
912 SyncData d(SyncData::CreateRemoteData(1, entity, base::Time())); | 949 SyncData d(SyncData::CreateRemoteData(1, entity, base::Time())); |
913 syncer::SyncDataList in(&d, &d + 1); | 950 syncer::SyncDataList in(&d, &d + 1); |
914 changes.clear(); | 951 changes.clear(); |
915 SessionsSyncManager manager2(profile(), this); | 952 SessionsSyncManager manager2(profile(), this, NewDummyRouter()); |
916 syncer::SyncMergeResult result = manager2.MergeDataAndStartSyncing( | 953 syncer::SyncMergeResult result = manager2.MergeDataAndStartSyncing( |
917 syncer::SESSIONS, in, | 954 syncer::SESSIONS, in, |
918 scoped_ptr<syncer::SyncChangeProcessor>( | 955 scoped_ptr<syncer::SyncChangeProcessor>( |
919 new TestSyncProcessorStub(&changes)), | 956 new TestSyncProcessorStub(&changes)), |
920 scoped_ptr<syncer::SyncErrorFactory>( | 957 scoped_ptr<syncer::SyncErrorFactory>( |
921 new syncer::SyncErrorFactoryMock())); | 958 new syncer::SyncErrorFactoryMock())); |
922 ASSERT_FALSE(result.error().IsSet()); | 959 ASSERT_FALSE(result.error().IsSet()); |
923 EXPECT_TRUE(FilterOutLocalHeaderChanges(&changes)->empty()); | 960 EXPECT_TRUE(FilterOutLocalHeaderChanges(&changes)->empty()); |
924 } | 961 } |
925 | 962 |
926 TEST_F(SessionsSyncManagerTest, MergeDeletesCorruptNode) { | 963 TEST_F(SessionsSyncManagerTest, MergeDeletesCorruptNode) { |
927 syncer::SyncChangeList changes; | 964 syncer::SyncChangeList changes; |
928 InitWithNoSyncData(); | 965 InitWithNoSyncData(); |
929 | 966 |
930 std::string local_tag = manager()->current_machine_tag(); | 967 std::string local_tag = manager()->current_machine_tag(); |
931 int tab_node_id = manager()->local_tab_pool_.GetFreeTabNode(&changes); | 968 int tab_node_id = manager()->local_tab_pool_.GetFreeTabNode(&changes); |
932 SyncData d(SyncData::CreateRemoteData( | 969 SyncData d(SyncData::CreateRemoteData( |
933 1, changes[0].sync_data().GetSpecifics(), base::Time())); | 970 1, changes[0].sync_data().GetSpecifics(), base::Time())); |
934 syncer::SyncDataList in(&d, &d + 1); | 971 syncer::SyncDataList in(&d, &d + 1); |
935 changes.clear(); | 972 changes.clear(); |
936 TearDown(); | 973 TearDown(); |
937 SetUp(); | 974 SetUp(); |
938 InitWithSyncDataTakeOutput(in, &changes); | 975 InitWithSyncDataTakeOutput(in, &changes); |
939 EXPECT_EQ(1U, FilterOutLocalHeaderChanges(&changes)->size()); | 976 EXPECT_EQ(1U, FilterOutLocalHeaderChanges(&changes)->size()); |
940 EXPECT_EQ(SyncChange::ACTION_DELETE, changes[0].change_type()); | 977 EXPECT_EQ(SyncChange::ACTION_DELETE, changes[0].change_type()); |
941 EXPECT_EQ(TabNodePool2::TabIdToTag(local_tag, tab_node_id), | 978 EXPECT_EQ(TabNodePool2::TabIdToTag(local_tag, tab_node_id), |
942 changes[0].sync_data().GetTag()); | 979 changes[0].sync_data().GetTag()); |
943 } | 980 } |
944 | 981 |
982 // Test that things work if a tab is initially ignored. | |
945 TEST_F(SessionsSyncManagerTest, AssociateWindowsDontReloadTabs) { | 983 TEST_F(SessionsSyncManagerTest, AssociateWindowsDontReloadTabs) { |
946 syncer::SyncChangeList out; | 984 syncer::SyncChangeList out; |
947 // Go to a URL that is ignored by session syncing. | 985 // Go to a URL that is ignored by session syncing. |
948 AddTab(browser(), GURL("chrome://preferences/")); | 986 AddTab(browser(), GURL("chrome://preferences/")); |
949 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); | 987 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); |
950 ASSERT_EQ(2U, out.size()); | 988 ASSERT_EQ(2U, out.size()); // Header add and update. |
951 EXPECT_EQ( | 989 EXPECT_EQ( |
952 0, | 990 0, |
953 out[1].sync_data().GetSpecifics().session().header().window_size()); | 991 out[1].sync_data().GetSpecifics().session().header().window_size()); |
954 out.clear(); | 992 out.clear(); |
955 | 993 |
956 // Go to a sync-interesting URL. | 994 // Go to a sync-interesting URL. |
957 NavigateAndCommitActiveTab(GURL("http://foo2")); | 995 NavigateAndCommitActiveTab(GURL("http://foo2")); |
958 | 996 |
959 // Simulate a selective association (e.g in response to tab event) as | 997 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 | 998 |
966 EXPECT_TRUE(StartsWithASCII(out[0].sync_data().GetTag(), | 999 EXPECT_TRUE(StartsWithASCII(out[0].sync_data().GetTag(), |
967 manager()->current_machine_tag(), true)); | 1000 manager()->current_machine_tag(), true)); |
968 EXPECT_EQ(manager()->current_machine_tag(), | 1001 EXPECT_EQ(manager()->current_machine_tag(), |
969 out[0].sync_data().GetSpecifics().session().session_tag()); | 1002 out[0].sync_data().GetSpecifics().session().session_tag()); |
970 EXPECT_EQ(SyncChange::ACTION_ADD, out[0].change_type()); | 1003 EXPECT_EQ(SyncChange::ACTION_ADD, out[0].change_type()); |
971 | 1004 |
972 EXPECT_TRUE(StartsWithASCII(out[1].sync_data().GetTag(), | 1005 EXPECT_TRUE(StartsWithASCII(out[1].sync_data().GetTag(), |
973 manager()->current_machine_tag(), true)); | 1006 manager()->current_machine_tag(), true)); |
974 EXPECT_EQ(manager()->current_machine_tag(), | 1007 EXPECT_EQ(manager()->current_machine_tag(), |
975 out[1].sync_data().GetSpecifics().session().session_tag()); | 1008 out[1].sync_data().GetSpecifics().session().session_tag()); |
976 EXPECT_TRUE(out[1].sync_data().GetSpecifics().session().has_tab()); | 1009 EXPECT_TRUE(out[1].sync_data().GetSpecifics().session().has_tab()); |
977 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[1].change_type()); | 1010 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[1].change_type()); |
978 | 1011 |
979 out.clear(); | 1012 EXPECT_TRUE(out[2].IsValid()); |
980 manager()->AssociateWindows(SessionsSyncManager::DONT_RELOAD_TABS, | 1013 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[2].change_type()); |
981 &out); | 1014 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()); | 1015 EXPECT_EQ(manager()->current_machine_tag(), data.GetTag()); |
988 const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session()); | 1016 const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session()); |
989 EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag()); | 1017 EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag()); |
990 EXPECT_TRUE(specifics.has_header()); | 1018 EXPECT_TRUE(specifics.has_header()); |
991 const sync_pb::SessionHeader& header_s = specifics.header(); | 1019 const sync_pb::SessionHeader& header_s = specifics.header(); |
992 EXPECT_EQ(1, header_s.window_size()); | 1020 EXPECT_EQ(1, header_s.window_size()); |
993 EXPECT_EQ(1, header_s.window(0).tab_size()); | 1021 EXPECT_EQ(1, header_s.window(0).tab_size()); |
994 } | 1022 } |
995 | 1023 |
1024 TEST_F(SessionsSyncManagerTest, OnLocalTabModified) { | |
1025 syncer::SyncChangeList out; | |
1026 // Init with no local data, relies on MergeLocalSessionNoTabs. | |
1027 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); | |
1028 ASSERT_FALSE(manager()->current_machine_tag().empty()); | |
1029 ASSERT_EQ(2U, out.size()); | |
1030 | |
1031 // Copy the original header. | |
1032 sync_pb::EntitySpecifics header(out[0].sync_data().GetSpecifics()); | |
1033 out.clear(); | |
1034 | |
1035 const GURL foo1("http://foo/1"); | |
1036 const GURL foo2("http://foo/2"); | |
1037 const GURL bar1("http://bar/1"); | |
1038 const GURL bar2("http://bar/2"); | |
1039 AddTab(browser(), foo1); | |
1040 NavigateAndCommitActiveTab(foo2); | |
1041 AddTab(browser(), bar1); | |
1042 NavigateAndCommitActiveTab(bar2); | |
1043 | |
1044 // One add, one update for each AddTab. | |
1045 // One update for each NavigateAndCommit. | |
1046 // = 6 total tab updates. | |
1047 // One header update corresponding to each of those. | |
1048 // = 6 total header updates. | |
1049 // 12 total updates. | |
1050 ASSERT_EQ(12U, out.size()); | |
1051 | |
1052 // Verify the tab node creations and updates to ensure the SyncProcessor | |
1053 // sees the right operations. | |
1054 for (int i = 0; i < 12; i++) { | |
1055 SCOPED_TRACE(i); | |
1056 EXPECT_TRUE(out[i].IsValid()); | |
1057 const SyncData data(out[i].sync_data()); | |
1058 EXPECT_TRUE(StartsWithASCII(data.GetTag(), | |
1059 manager()->current_machine_tag(), true)); | |
1060 const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session()); | |
1061 EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag()); | |
1062 if (i % 6 == 0) { | |
1063 // First thing on an AddTab is a no-op header update for parented tab. | |
1064 EXPECT_EQ(header.SerializeAsString(), | |
1065 data.GetSpecifics().SerializeAsString()); | |
1066 } else if (i % 6 == 1) { | |
1067 // Next, the TabNodePool should create the tab node. | |
1068 EXPECT_EQ(SyncChange::ACTION_ADD, out[i].change_type()); | |
1069 } else if (i % 6 == 2) { | |
1070 // Then we see the tab update to the URL. | |
1071 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type()); | |
1072 ASSERT_TRUE(specifics.has_tab()); | |
1073 } else if (i % 6 == 3) { | |
1074 // The header needs to be updated to reflect the new window state. | |
1075 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type()); | |
1076 EXPECT_TRUE(specifics.has_header()); | |
1077 } else if (i % 6 == 4) { | |
1078 // Now we move on to NavigateAndCommit. Update the tab. | |
1079 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type()); | |
1080 ASSERT_TRUE(specifics.has_tab()); | |
1081 } else if (i % 6 == 5) { | |
1082 // The header needs to be updated to reflect the new window state. | |
1083 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type()); | |
1084 ASSERT_TRUE(specifics.has_header()); | |
1085 header = data.GetSpecifics(); | |
1086 } | |
1087 } | |
1088 | |
1089 // Verify the actual content to ensure sync sees the right data. | |
1090 // When it's all said and done, the header should reflect two tabs. | |
1091 const sync_pb::SessionHeader& session_header = header.session().header(); | |
1092 ASSERT_EQ(1, session_header.window_size()); | |
1093 EXPECT_EQ(2, session_header.window(0).tab_size()); | |
1094 | |
1095 // ASSERT_TRUEs above allow us to dive in freely here. | |
1096 // Verify first tab. | |
1097 const sync_pb::SessionTab& tab1_1 = | |
1098 out[2].sync_data().GetSpecifics().session().tab(); | |
1099 ASSERT_EQ(1, tab1_1.navigation_size()); | |
1100 EXPECT_EQ(foo1.spec(), tab1_1.navigation(0).virtual_url()); | |
1101 const sync_pb::SessionTab& tab1_2 = | |
1102 out[4].sync_data().GetSpecifics().session().tab(); | |
1103 ASSERT_EQ(2, tab1_2.navigation_size()); | |
1104 EXPECT_EQ(foo1.spec(), tab1_2.navigation(0).virtual_url()); | |
1105 EXPECT_EQ(foo2.spec(), tab1_2.navigation(1).virtual_url()); | |
1106 | |
1107 // Verify second tab. | |
1108 const sync_pb::SessionTab& tab2_1 = | |
1109 out[8].sync_data().GetSpecifics().session().tab(); | |
1110 ASSERT_EQ(1, tab2_1.navigation_size()); | |
1111 EXPECT_EQ(bar1.spec(), tab2_1.navigation(0).virtual_url()); | |
1112 const sync_pb::SessionTab& tab2_2 = | |
1113 out[10].sync_data().GetSpecifics().session().tab(); | |
1114 ASSERT_EQ(2, tab2_2.navigation_size()); | |
1115 EXPECT_EQ(bar1.spec(), tab2_2.navigation(0).virtual_url()); | |
1116 EXPECT_EQ(bar2.spec(), tab2_2.navigation(1).virtual_url()); | |
1117 } | |
1118 | |
996 // Ensure model association associates the pre-existing tabs. | 1119 // Ensure model association associates the pre-existing tabs. |
997 TEST_F(SessionsSyncManagerTest, MergeLocalSessionExistingTabs) { | 1120 TEST_F(SessionsSyncManagerTest, MergeLocalSessionExistingTabs) { |
998 AddTab(browser(), GURL("http://foo1")); | 1121 AddTab(browser(), GURL("http://foo1")); |
999 NavigateAndCommitActiveTab(GURL("http://foo2")); | 1122 NavigateAndCommitActiveTab(GURL("http://foo2")); // Adds back entry. |
1000 AddTab(browser(), GURL("http://bar1")); | 1123 AddTab(browser(), GURL("http://bar1")); |
1001 NavigateAndCommitActiveTab(GURL("http://bar2")); | 1124 NavigateAndCommitActiveTab(GURL("http://bar2")); // Adds back entry. |
1002 | 1125 |
1003 syncer::SyncChangeList out; | 1126 syncer::SyncChangeList out; |
1004 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); | 1127 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); |
1005 ASSERT_EQ(6U, out.size()); | 1128 ASSERT_EQ(6U, out.size()); |
1006 | 1129 |
1007 // Check that this machine's data is not included in the foreign windows. | 1130 // Check that this machine's data is not included in the foreign windows. |
1008 std::vector<const SyncedSession*> foreign_sessions; | 1131 std::vector<const SyncedSession*> foreign_sessions; |
1009 ASSERT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions)); | 1132 ASSERT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions)); |
1010 | 1133 |
1011 // Verify the header. | 1134 // Verify the header. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1070 TEST_F(SessionsSyncManagerTest, CheckPrerenderedWebContentsSwap) { | 1193 TEST_F(SessionsSyncManagerTest, CheckPrerenderedWebContentsSwap) { |
1071 AddTab(browser(), GURL("http://foo1")); | 1194 AddTab(browser(), GURL("http://foo1")); |
1072 NavigateAndCommitActiveTab(GURL("http://foo2")); | 1195 NavigateAndCommitActiveTab(GURL("http://foo2")); |
1073 | 1196 |
1074 syncer::SyncChangeList out; | 1197 syncer::SyncChangeList out; |
1075 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); | 1198 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); |
1076 ASSERT_EQ(4U, out.size()); // Header, tab ADD, tab UPDATE, header UPDATE. | 1199 ASSERT_EQ(4U, out.size()); // Header, tab ADD, tab UPDATE, header UPDATE. |
1077 | 1200 |
1078 // To simulate WebContents swap during prerendering, create new WebContents | 1201 // To simulate WebContents swap during prerendering, create new WebContents |
1079 // and swap with old WebContents. | 1202 // and swap with old WebContents. |
1080 content::WebContents* old_web_contents = | 1203 scoped_ptr<content::WebContents> old_web_contents; |
1081 browser()->tab_strip_model()->GetActiveWebContents(); | 1204 old_web_contents.reset(browser()->tab_strip_model()->GetActiveWebContents()); |
1082 | 1205 |
1083 // Create new WebContents, with the required tab helpers. | 1206 // Create new WebContents, with the required tab helpers. |
1084 WebContents* new_web_contents = WebContents::CreateWithSessionStorage( | 1207 WebContents* new_web_contents = WebContents::CreateWithSessionStorage( |
1085 WebContents::CreateParams(profile()), | 1208 WebContents::CreateParams(profile()), |
1086 old_web_contents->GetController().GetSessionStorageNamespaceMap()); | 1209 old_web_contents->GetController().GetSessionStorageNamespaceMap()); |
1087 SessionTabHelper::CreateForWebContents(new_web_contents); | 1210 SessionTabHelper::CreateForWebContents(new_web_contents); |
1088 TabContentsSyncedTabDelegate::CreateForWebContents(new_web_contents); | 1211 TabContentsSyncedTabDelegate::CreateForWebContents(new_web_contents); |
1089 new_web_contents->GetController() | 1212 new_web_contents->GetController() |
1090 .CopyStateFrom(old_web_contents->GetController()); | 1213 .CopyStateFrom(old_web_contents->GetController()); |
1091 | 1214 |
1092 // Swap the WebContents. | 1215 // Swap the WebContents. |
1093 int index = | 1216 int index = browser()->tab_strip_model()->GetIndexOfWebContents( |
1094 browser()->tab_strip_model()->GetIndexOfWebContents(old_web_contents); | 1217 old_web_contents.get()); |
1095 browser()->tab_strip_model()->ReplaceWebContentsAt(index, new_web_contents); | 1218 browser()->tab_strip_model()->ReplaceWebContentsAt(index, new_web_contents); |
1096 | 1219 |
1097 manager()->AssociateWindows(SessionsSyncManager::RELOAD_TABS, &out); | 1220 ASSERT_EQ(9U, out.size()); |
1098 ASSERT_EQ(7U, out.size()); | |
1099 EXPECT_EQ(SyncChange::ACTION_ADD, out[4].change_type()); | 1221 EXPECT_EQ(SyncChange::ACTION_ADD, out[4].change_type()); |
1100 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[5].change_type()); | 1222 EXPECT_EQ(SyncChange::ACTION_UPDATE, out[5].change_type()); |
1101 | 1223 |
1102 // Navigate away. | 1224 // Navigate away. |
1103 NavigateAndCommitActiveTab(GURL("http://bar2")); | 1225 NavigateAndCommitActiveTab(GURL("http://bar2")); |
1104 manager()->AssociateWindows(SessionsSyncManager::RELOAD_TABS, &out); | |
1105 | 1226 |
1106 // Delete old WebContents. This should not crash. | 1227 // Delete old WebContents. This should not crash. |
1107 delete old_web_contents; | 1228 old_web_contents.reset(); |
1108 manager()->AssociateWindows(SessionsSyncManager::RELOAD_TABS, &out); | |
1109 | 1229 |
1110 // Try more navigations and verify output size. This can also reveal | 1230 // Try more navigations and verify output size. This can also reveal |
1111 // bugs (leaks) on memcheck bots if the SessionSyncManager | 1231 // bugs (leaks) on memcheck bots if the SessionSyncManager |
1112 // didn't properly clean up the tab pool or session tracker. | 1232 // didn't properly clean up the tab pool or session tracker. |
1113 NavigateAndCommitActiveTab(GURL("http://bar3")); | 1233 NavigateAndCommitActiveTab(GURL("http://bar3")); |
1114 manager()->AssociateWindows(SessionsSyncManager::RELOAD_TABS, &out); | |
1115 | 1234 |
1116 AddTab(browser(), GURL("http://bar4")); | 1235 AddTab(browser(), GURL("http://bar4")); |
1117 manager()->AssociateWindows(SessionsSyncManager::RELOAD_TABS, &out); | |
1118 NavigateAndCommitActiveTab(GURL("http://bar5")); | 1236 NavigateAndCommitActiveTab(GURL("http://bar5")); |
1119 manager()->AssociateWindows(SessionsSyncManager::RELOAD_TABS, &out); | 1237 ASSERT_EQ(19U, out.size()); |
1120 ASSERT_EQ(20U, out.size()); | |
1121 } | 1238 } |
1122 | 1239 |
1123 namespace { | 1240 namespace { |
1124 class SessionNotificationObserver : public content::NotificationObserver { | 1241 class SessionNotificationObserver : public content::NotificationObserver { |
1125 public: | 1242 public: |
1126 SessionNotificationObserver() : notified_of_update_(false) { | 1243 SessionNotificationObserver() : notified_of_update_(false), |
1244 notified_of_refresh_(false) { | |
1127 registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED, | 1245 registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED, |
1128 content::NotificationService::AllSources()); | 1246 content::NotificationService::AllSources()); |
1247 registrar_.Add(this, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, | |
1248 content::NotificationService::AllSources()); | |
1129 } | 1249 } |
1130 virtual void Observe(int type, | 1250 virtual void Observe(int type, |
1131 const content::NotificationSource& source, | 1251 const content::NotificationSource& source, |
1132 const content::NotificationDetails& details) OVERRIDE { | 1252 const content::NotificationDetails& details) OVERRIDE { |
1133 switch (type) { | 1253 switch (type) { |
1134 case chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED: | 1254 case chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED: |
1135 notified_of_update_ = true; | 1255 notified_of_update_ = true; |
1136 break; | 1256 break; |
1257 case chrome::NOTIFICATION_SYNC_REFRESH_LOCAL: | |
1258 notified_of_refresh_ = true; | |
1259 break; | |
1137 default: | 1260 default: |
1138 NOTREACHED(); | 1261 NOTREACHED(); |
1139 break; | 1262 break; |
1140 } | 1263 } |
1141 } | 1264 } |
1142 bool notified_of_update() const { return notified_of_update_; } | 1265 bool notified_of_update() const { return notified_of_update_; } |
1143 void Reset() { notified_of_update_ = false; } | 1266 bool notified_of_refresh() const { return notified_of_refresh_; } |
1267 void Reset() { | |
1268 notified_of_update_ = false; | |
1269 notified_of_refresh_ = false; | |
1270 } | |
1144 private: | 1271 private: |
1145 content::NotificationRegistrar registrar_; | 1272 content::NotificationRegistrar registrar_; |
1146 bool notified_of_update_; | 1273 bool notified_of_update_; |
1274 bool notified_of_refresh_; | |
1147 }; | 1275 }; |
1148 } // namespace | 1276 } // namespace |
1149 | 1277 |
1150 TEST_F(SessionsSyncManagerTest, NotifiedOfUpdates) { | 1278 TEST_F(SessionsSyncManagerTest, NotifiedOfUpdates) { |
1151 SessionNotificationObserver observer; | 1279 SessionNotificationObserver observer; |
1280 ASSERT_FALSE(observer.notified_of_update()); | |
1152 InitWithNoSyncData(); | 1281 InitWithNoSyncData(); |
1153 | 1282 |
1154 SessionID::id_type n[] = {5}; | 1283 SessionID::id_type n[] = {5}; |
1155 std::vector<sync_pb::SessionSpecifics> tabs1; | 1284 std::vector<sync_pb::SessionSpecifics> tabs1; |
1156 std::vector<SessionID::id_type> tab_list(n, n + arraysize(n)); | 1285 std::vector<SessionID::id_type> tab_list(n, n + arraysize(n)); |
1157 sync_pb::SessionSpecifics meta(helper()->BuildForeignSession( | 1286 sync_pb::SessionSpecifics meta(helper()->BuildForeignSession( |
1158 "tag1", tab_list, &tabs1)); | 1287 "tag1", tab_list, &tabs1)); |
1159 | 1288 |
1160 syncer::SyncChangeList changes; | 1289 syncer::SyncChangeList changes; |
1161 changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD)); | 1290 changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD)); |
1162 manager()->ProcessSyncChanges(FROM_HERE, changes); | 1291 manager()->ProcessSyncChanges(FROM_HERE, changes); |
1163 EXPECT_TRUE(observer.notified_of_update()); | 1292 EXPECT_TRUE(observer.notified_of_update()); |
1164 | 1293 |
1165 changes.clear(); | 1294 changes.clear(); |
1166 observer.Reset(); | 1295 observer.Reset(); |
1167 AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &changes); | 1296 AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &changes); |
1168 manager()->ProcessSyncChanges(FROM_HERE, changes); | 1297 manager()->ProcessSyncChanges(FROM_HERE, changes); |
1169 EXPECT_TRUE(observer.notified_of_update()); | 1298 EXPECT_TRUE(observer.notified_of_update()); |
1170 | 1299 |
1171 changes.clear(); | 1300 changes.clear(); |
1172 observer.Reset(); | 1301 observer.Reset(); |
1173 changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_DELETE)); | 1302 changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_DELETE)); |
1174 manager()->ProcessSyncChanges(FROM_HERE, changes); | 1303 manager()->ProcessSyncChanges(FROM_HERE, changes); |
1175 EXPECT_TRUE(observer.notified_of_update()); | 1304 EXPECT_TRUE(observer.notified_of_update()); |
1176 } | 1305 } |
1177 | 1306 |
1307 TEST_F(SessionsSyncManagerTest, NotifiedOfRefresh) { | |
1308 SessionNotificationObserver observer; | |
1309 ASSERT_FALSE(observer.notified_of_refresh()); | |
1310 InitWithNoSyncData(); | |
1311 AddTab(browser(), GURL("http://foo1")); | |
1312 EXPECT_FALSE(observer.notified_of_refresh()); | |
1313 NavigateAndCommitActiveTab(GURL("chrome://newtab/#open_tabs")); | |
1314 EXPECT_TRUE(observer.notified_of_refresh()); | |
1315 } | |
1316 | |
1178 } // namespace browser_sync | 1317 } // namespace browser_sync |
OLD | NEW |