OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/glue/chrome_sync_notification_bridge.h" | 5 #include "chrome/browser/sync/glue/chrome_sync_notification_bridge.h" |
6 | 6 |
7 #include <cstddef> | 7 #include <cstddef> |
8 | 8 |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "base/memory/weak_ptr.h" | 12 #include "base/memory/weak_ptr.h" |
13 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
14 #include "base/sequenced_task_runner.h" | 14 #include "base/sequenced_task_runner.h" |
15 #include "base/synchronization/waitable_event.h" | 15 #include "base/synchronization/waitable_event.h" |
16 #include "base/test/test_timeouts.h" | 16 #include "base/test/test_timeouts.h" |
17 #include "base/threading/thread.h" | 17 #include "base/threading/thread.h" |
18 #include "chrome/common/chrome_notification_types.h" | 18 #include "chrome/common/chrome_notification_types.h" |
19 #include "chrome/test/base/profile_mock.h" | 19 #include "chrome/test/base/profile_mock.h" |
20 #include "content/public/browser/notification_details.h" | 20 #include "content/public/browser/notification_details.h" |
21 #include "content/public/browser/notification_service.h" | 21 #include "content/public/browser/notification_service.h" |
22 #include "content/public/test/test_browser_thread.h" | 22 #include "content/public/test/test_browser_thread.h" |
23 #include "sync/internal_api/public/base/model_type.h" | 23 #include "sync/internal_api/public/base/model_type.h" |
24 #include "sync/internal_api/public/base/model_type_state_map.h" | 24 #include "sync/internal_api/public/base/model_type_state_map.h" |
| 25 #include "sync/notifier/invalidation_handler.h" |
25 #include "sync/notifier/object_id_state_map_test_util.h" | 26 #include "sync/notifier/object_id_state_map_test_util.h" |
26 #include "sync/notifier/sync_notifier_observer.h" | |
27 #include "testing/gmock/include/gmock/gmock.h" | 27 #include "testing/gmock/include/gmock/gmock.h" |
28 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
29 | 29 |
30 namespace browser_sync { | 30 namespace browser_sync { |
31 namespace { | 31 namespace { |
32 | 32 |
33 using ::testing::Mock; | 33 using ::testing::Mock; |
34 using ::testing::NiceMock; | 34 using ::testing::NiceMock; |
35 using ::testing::StrictMock; | 35 using ::testing::StrictMock; |
36 using content::BrowserThread; | 36 using content::BrowserThread; |
37 | 37 |
38 // Receives a ChromeSyncNotificationBridge to register to, and an expected | 38 // Receives a ChromeSyncNotificationBridge to register to, and an expected |
39 // ModelTypeStateMap. ReceivedProperNotification() will return true only | 39 // ModelTypeStateMap. ReceivedProperNotification() will return true only |
40 // if the observer has received a notification with the proper source and | 40 // if the observer has received a notification with the proper source and |
41 // state. | 41 // state. |
42 // Note: Because this object lives on the sync thread, we use a fake | 42 // Note: Because this object lives on the sync thread, we use a fake |
43 // (vs a mock) so we don't have to worry about possible thread safety | 43 // (vs a mock) so we don't have to worry about possible thread safety |
44 // issues within GTest/GMock. | 44 // issues within GTest/GMock. |
45 class FakeSyncNotifierObserver : public syncer::SyncNotifierObserver { | 45 class FakeInvalidationHandler : public syncer::InvalidationHandler { |
46 public: | 46 public: |
47 FakeSyncNotifierObserver( | 47 FakeInvalidationHandler( |
48 const scoped_refptr<base::SequencedTaskRunner>& sync_task_runner, | 48 const scoped_refptr<base::SequencedTaskRunner>& sync_task_runner, |
49 ChromeSyncNotificationBridge* bridge, | 49 ChromeSyncNotificationBridge* bridge, |
50 const syncer::ObjectIdStateMap& expected_states, | 50 const syncer::ObjectIdStateMap& expected_states, |
51 syncer::IncomingNotificationSource expected_source) | 51 syncer::IncomingNotificationSource expected_source) |
52 : sync_task_runner_(sync_task_runner), | 52 : sync_task_runner_(sync_task_runner), |
53 bridge_(bridge), | 53 bridge_(bridge), |
54 received_improper_notification_(false), | 54 received_improper_notification_(false), |
55 notification_count_(0), | 55 notification_count_(0), |
56 expected_states_(expected_states), | 56 expected_states_(expected_states), |
57 expected_source_(expected_source) { | 57 expected_source_(expected_source) { |
58 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); | 58 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); |
59 bridge_->RegisterHandler(this); | 59 bridge_->RegisterHandler(this); |
60 const syncer::ObjectIdSet& ids = | 60 const syncer::ObjectIdSet& ids = |
61 syncer::ObjectIdStateMapToSet(expected_states); | 61 syncer::ObjectIdStateMapToSet(expected_states); |
62 bridge_->UpdateRegisteredIds(this, ids); | 62 bridge_->UpdateRegisteredIds(this, ids); |
63 } | 63 } |
64 | 64 |
65 virtual ~FakeSyncNotifierObserver() { | 65 virtual ~FakeInvalidationHandler() { |
66 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); | 66 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); |
67 bridge_->UnregisterHandler(this); | 67 bridge_->UnregisterHandler(this); |
68 } | 68 } |
69 | 69 |
70 // SyncNotifierObserver implementation. | 70 // InvalidationHandler implementation. |
71 virtual void OnIncomingNotification( | 71 virtual void OnIncomingNotification( |
72 const syncer::ObjectIdStateMap& id_state_map, | 72 const syncer::ObjectIdStateMap& id_state_map, |
73 syncer::IncomingNotificationSource source) OVERRIDE { | 73 syncer::IncomingNotificationSource source) OVERRIDE { |
74 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); | 74 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); |
75 notification_count_++; | 75 notification_count_++; |
76 if (source != expected_source_) { | 76 if (source != expected_source_) { |
77 LOG(ERROR) << "Received notification with wrong source"; | 77 LOG(ERROR) << "Received notification with wrong source"; |
78 received_improper_notification_ = true; | 78 received_improper_notification_ = true; |
79 } | 79 } |
80 if (!::testing::Matches(Eq(expected_states_))(id_state_map)) { | 80 if (!::testing::Matches(Eq(expected_states_))(id_state_map)) { |
(...skipping 21 matching lines...) Expand all Loading... |
102 size_t notification_count_; | 102 size_t notification_count_; |
103 const syncer::ObjectIdStateMap expected_states_; | 103 const syncer::ObjectIdStateMap expected_states_; |
104 const syncer::IncomingNotificationSource expected_source_; | 104 const syncer::IncomingNotificationSource expected_source_; |
105 }; | 105 }; |
106 | 106 |
107 class ChromeSyncNotificationBridgeTest : public testing::Test { | 107 class ChromeSyncNotificationBridgeTest : public testing::Test { |
108 public: | 108 public: |
109 ChromeSyncNotificationBridgeTest() | 109 ChromeSyncNotificationBridgeTest() |
110 : ui_thread_(BrowserThread::UI), | 110 : ui_thread_(BrowserThread::UI), |
111 sync_thread_("Sync thread"), | 111 sync_thread_("Sync thread"), |
112 sync_observer_(NULL), | 112 sync_handler_(NULL), |
113 sync_observer_notification_failure_(false), | 113 sync_handler_notification_failure_(false), |
114 done_(true, false) {} | 114 done_(true, false) {} |
115 | 115 |
116 virtual ~ChromeSyncNotificationBridgeTest() {} | 116 virtual ~ChromeSyncNotificationBridgeTest() {} |
117 | 117 |
118 protected: | 118 protected: |
119 virtual void SetUp() OVERRIDE { | 119 virtual void SetUp() OVERRIDE { |
120 ASSERT_TRUE(sync_thread_.Start()); | 120 ASSERT_TRUE(sync_thread_.Start()); |
121 bridge_.reset( | 121 bridge_.reset( |
122 new ChromeSyncNotificationBridge( | 122 new ChromeSyncNotificationBridge( |
123 &mock_profile_, sync_thread_.message_loop_proxy())); | 123 &mock_profile_, sync_thread_.message_loop_proxy())); |
124 } | 124 } |
125 | 125 |
126 virtual void TearDown() OVERRIDE { | 126 virtual void TearDown() OVERRIDE { |
127 bridge_->StopForShutdown(); | 127 bridge_->StopForShutdown(); |
128 sync_thread_.Stop(); | 128 sync_thread_.Stop(); |
129 // Must be reset only after the sync thread is stopped. | 129 // Must be reset only after the sync thread is stopped. |
130 bridge_.reset(); | 130 bridge_.reset(); |
131 EXPECT_EQ(NULL, sync_observer_); | 131 EXPECT_EQ(NULL, sync_handler_); |
132 if (sync_observer_notification_failure_) | 132 if (sync_handler_notification_failure_) |
133 ADD_FAILURE() << "Sync Observer did not receive proper notification."; | 133 ADD_FAILURE() << "Sync Observer did not receive proper notification."; |
134 } | 134 } |
135 | 135 |
136 void VerifyAndDestroyObserver() { | 136 void VerifyAndDestroyObserver() { |
137 ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTask( | 137 ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTask( |
138 FROM_HERE, | 138 FROM_HERE, |
139 base::Bind(&ChromeSyncNotificationBridgeTest:: | 139 base::Bind(&ChromeSyncNotificationBridgeTest:: |
140 VerifyAndDestroyObserverOnSyncThread, | 140 VerifyAndDestroyObserverOnSyncThread, |
141 base::Unretained(this)))); | 141 base::Unretained(this)))); |
142 BlockForSyncThread(); | 142 BlockForSyncThread(); |
(...skipping 30 matching lines...) Expand all Loading... |
173 const syncer::ModelTypeStateMap& state_map) { | 173 const syncer::ModelTypeStateMap& state_map) { |
174 content::NotificationService::current()->Notify( | 174 content::NotificationService::current()->Notify( |
175 type, | 175 type, |
176 content::Source<Profile>(&mock_profile_), | 176 content::Source<Profile>(&mock_profile_), |
177 content::Details<const syncer::ModelTypeStateMap>(&state_map)); | 177 content::Details<const syncer::ModelTypeStateMap>(&state_map)); |
178 } | 178 } |
179 | 179 |
180 private: | 180 private: |
181 void VerifyAndDestroyObserverOnSyncThread() { | 181 void VerifyAndDestroyObserverOnSyncThread() { |
182 DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); | 182 DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); |
183 if (!sync_observer_) { | 183 if (!sync_handler_) { |
184 sync_observer_notification_failure_ = true; | 184 sync_handler_notification_failure_ = true; |
185 } else { | 185 } else { |
186 sync_observer_notification_failure_ = | 186 sync_handler_notification_failure_ = |
187 !sync_observer_->ReceivedProperNotification(); | 187 !sync_handler_->ReceivedProperNotification(); |
188 delete sync_observer_; | 188 delete sync_handler_; |
189 sync_observer_ = NULL; | 189 sync_handler_ = NULL; |
190 } | 190 } |
191 } | 191 } |
192 | 192 |
193 void CreateObserverOnSyncThread( | 193 void CreateObserverOnSyncThread( |
194 const syncer::ObjectIdStateMap& expected_states, | 194 const syncer::ObjectIdStateMap& expected_states, |
195 syncer::IncomingNotificationSource expected_source) { | 195 syncer::IncomingNotificationSource expected_source) { |
196 DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); | 196 DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); |
197 sync_observer_ = new FakeSyncNotifierObserver( | 197 sync_handler_ = new FakeInvalidationHandler( |
198 sync_thread_.message_loop_proxy(), | 198 sync_thread_.message_loop_proxy(), |
199 bridge_.get(), | 199 bridge_.get(), |
200 expected_states, | 200 expected_states, |
201 expected_source); | 201 expected_source); |
202 } | 202 } |
203 | 203 |
204 void UpdateBridgeEnabledTypesOnSyncThread( | 204 void UpdateBridgeEnabledTypesOnSyncThread( |
205 syncer::ModelTypeSet enabled_types) { | 205 syncer::ModelTypeSet enabled_types) { |
206 DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); | 206 DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); |
207 bridge_->UpdateEnabledTypes(enabled_types); | 207 bridge_->UpdateEnabledTypes(enabled_types); |
(...skipping 12 matching lines...) Expand all Loading... |
220 base::Unretained(this)))); | 220 base::Unretained(this)))); |
221 done_.TimedWait(TestTimeouts::action_timeout()); | 221 done_.TimedWait(TestTimeouts::action_timeout()); |
222 if (!done_.IsSignaled()) | 222 if (!done_.IsSignaled()) |
223 ADD_FAILURE() << "Timed out waiting for sync thread."; | 223 ADD_FAILURE() << "Timed out waiting for sync thread."; |
224 } | 224 } |
225 | 225 |
226 content::TestBrowserThread ui_thread_; | 226 content::TestBrowserThread ui_thread_; |
227 base::Thread sync_thread_; | 227 base::Thread sync_thread_; |
228 NiceMock<ProfileMock> mock_profile_; | 228 NiceMock<ProfileMock> mock_profile_; |
229 // Created/used/destroyed on sync thread. | 229 // Created/used/destroyed on sync thread. |
230 FakeSyncNotifierObserver* sync_observer_; | 230 FakeInvalidationHandler* sync_handler_; |
231 bool sync_observer_notification_failure_; | 231 bool sync_handler_notification_failure_; |
232 scoped_ptr<ChromeSyncNotificationBridge> bridge_; | 232 scoped_ptr<ChromeSyncNotificationBridge> bridge_; |
233 base::WaitableEvent done_; | 233 base::WaitableEvent done_; |
234 }; | 234 }; |
235 | 235 |
236 // Adds an observer on the sync thread, triggers a local refresh | 236 // Adds an observer on the sync thread, triggers a local refresh |
237 // notification, and ensures the bridge posts a LOCAL_NOTIFICATION | 237 // notification, and ensures the bridge posts a LOCAL_NOTIFICATION |
238 // with the proper state to it. | 238 // with the proper state to it. |
239 TEST_F(ChromeSyncNotificationBridgeTest, LocalNotification) { | 239 TEST_F(ChromeSyncNotificationBridgeTest, LocalNotification) { |
240 syncer::ModelTypeStateMap state_map; | 240 syncer::ModelTypeStateMap state_map; |
241 state_map.insert( | 241 state_map.insert( |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 CreateObserverWithExpectations( | 286 CreateObserverWithExpectations( |
287 enabled_types_state_map, syncer::REMOTE_NOTIFICATION); | 287 enabled_types_state_map, syncer::REMOTE_NOTIFICATION); |
288 UpdateBridgeEnabledTypes(enabled_types); | 288 UpdateBridgeEnabledTypes(enabled_types); |
289 TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_REMOTE, | 289 TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_REMOTE, |
290 syncer::ModelTypeStateMap()); | 290 syncer::ModelTypeStateMap()); |
291 VerifyAndDestroyObserver(); | 291 VerifyAndDestroyObserver(); |
292 } | 292 } |
293 | 293 |
294 } // namespace | 294 } // namespace |
295 } // namespace browser_sync | 295 } // namespace browser_sync |
OLD | NEW |