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

Side by Side Diff: chrome/browser/sync/notifier/chrome_sync_notification_bridge_unittest.cc

Issue 9512005: [Sync] Move BridgedSyncNotifier and ChromeSyncNotificationBridge to glue/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync to head Created 8 years, 9 months 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/sync/notifier/chrome_sync_notification_bridge.h"
6
7 #include "base/compiler_specific.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/message_loop.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "base/test/test_timeouts.h"
12 #include "base/threading/thread.h"
13 #include "chrome/browser/sync/syncable/model_type.h"
14 #include "chrome/browser/sync/syncable/model_type_payload_map.h"
15 #include "chrome/browser/sync/notifier/mock_sync_notifier_observer.h"
16 #include "chrome/browser/sync/notifier/sync_notifier_observer.h"
17 #include "chrome/common/chrome_notification_types.h"
18 #include "chrome/test/base/profile_mock.h"
19 #include "content/public/browser/notification_service.h"
20 #include "content/public/browser/notification_details.h"
21 #include "content/test/test_browser_thread.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24
25 namespace sync_notifier {
26 namespace {
27
28 using ::testing::Mock;
29 using ::testing::NiceMock;
30 using ::testing::StrictMock;
31 using content::BrowserThread;
32
33 // Receives a ChromeSyncNotificationBridge to register to, and an expected
34 // ModelTypePayloadMap. ReceivedProperNotification() will return true only
35 // if the observer has received a notification with the proper source and
36 // payload.
37 // Note: Because this object lives on the IO thread, we use a fake (vs a mock)
38 // so we don't have to worry about possible thread safety issues within
39 // GTest/GMock.
40 class FakeSyncNotifierObserverIO : public SyncNotifierObserver {
41 public:
42 FakeSyncNotifierObserverIO(
43 ChromeSyncNotificationBridge* bridge,
44 const syncable::ModelTypePayloadMap& expected_payloads)
45 : bridge_(bridge),
46 received_improper_notification_(false),
47 notification_count_(0),
48 expected_payloads_(expected_payloads) {
49 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
50 bridge_->AddObserver(this);
51 }
52 virtual ~FakeSyncNotifierObserverIO() {
53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
54 bridge_->RemoveObserver(this);
55 }
56
57 // SyncNotifierObserver implementation.
58 virtual void OnIncomingNotification(
59 const syncable::ModelTypePayloadMap& type_payloads,
60 IncomingNotificationSource source) OVERRIDE {
61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
62 notification_count_++;
63 if (source != LOCAL_NOTIFICATION) {
64 LOG(ERROR) << "Received notification with wrong source.";
65 received_improper_notification_ = true;
66 }
67 if (expected_payloads_ != type_payloads) {
68 LOG(ERROR) << "Received wrong payload.";
69 received_improper_notification_ = true;
70 }
71 }
72 virtual void OnNotificationStateChange(bool notifications_enabled) {
73 NOTREACHED();
74 }
75 virtual void StoreState(const std::string& state) OVERRIDE {
76 NOTREACHED();
77 }
78
79 bool ReceivedProperNotification() const {
80 return (notification_count_ == 1) && !received_improper_notification_;
81 }
82
83 private:
84 ChromeSyncNotificationBridge* bridge_;
85 bool received_improper_notification_;
86 size_t notification_count_;
87 syncable::ModelTypePayloadMap expected_payloads_;
88 };
89
90 class ChromeSyncNotificationBridgeTest : public testing::Test {
91 public:
92 ChromeSyncNotificationBridgeTest()
93 : ui_thread_(BrowserThread::UI, &ui_loop_),
94 io_thread_(BrowserThread::IO),
95 io_observer_(NULL),
96 io_observer_notification_failure_(false),
97 bridge_(&mock_profile_),
98 done_(true, false) {
99 io_thread_.StartIOThread();
100 }
101 virtual ~ChromeSyncNotificationBridgeTest() {}
102
103 protected:
104 virtual void TearDown() OVERRIDE {
105 io_thread_.Stop();
106 ui_loop_.RunAllPending();
107 EXPECT_EQ(NULL, io_observer_);
108 if (io_observer_notification_failure_)
109 ADD_FAILURE() << "IO Observer did not receive proper notification.";
110 }
111
112 void VerifyAndDestroyObserverOnIOThread() {
113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
114 if (!io_observer_) {
115 io_observer_notification_failure_ = true;
116 } else {
117 io_observer_notification_failure_ =
118 !io_observer_->ReceivedProperNotification();
119 delete io_observer_;
120 io_observer_ = NULL;
121 }
122 }
123
124 void VerifyAndDestroyObserver() {
125 ASSERT_TRUE(BrowserThread::PostTask(
126 BrowserThread::IO,
127 FROM_HERE,
128 base::Bind(&ChromeSyncNotificationBridgeTest::
129 VerifyAndDestroyObserverOnIOThread,
130 base::Unretained(this))));
131 }
132
133 void CreateObserverOnIOThread(
134 syncable::ModelTypePayloadMap expected_payloads) {
135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
136 io_observer_ = new FakeSyncNotifierObserverIO(&bridge_,
137 expected_payloads);
138 }
139
140 void CreateObserverWithExpectedPayload(
141 syncable::ModelTypePayloadMap expected_payloads) {
142 ASSERT_TRUE(BrowserThread::PostTask(
143 BrowserThread::IO,
144 FROM_HERE,
145 base::Bind(&ChromeSyncNotificationBridgeTest::CreateObserverOnIOThread,
146 base::Unretained(this),
147 expected_payloads)));
148 BlockForIOThread();
149 }
150
151 void SignalOnIOThread() {
152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
153 done_.Signal();
154 }
155
156 void BlockForIOThread() {
157 done_.Reset();
158 BrowserThread::PostTask(
159 BrowserThread::IO,
160 FROM_HERE,
161 base::Bind(&ChromeSyncNotificationBridgeTest::SignalOnIOThread,
162 base::Unretained(this)));
163 done_.TimedWait(TestTimeouts::action_timeout());
164 if (!done_.IsSignaled())
165 ADD_FAILURE() << "Timed out waiting for IO thread.";
166 }
167
168 void TriggerRefreshNotification() {
169 const syncable::ModelType type = syncable::SESSIONS;
170 content::NotificationService::current()->Notify(
171 chrome::NOTIFICATION_SYNC_REFRESH,
172 content::Source<Profile>(&mock_profile_),
173 content::Details<const syncable::ModelType>(&type));
174 }
175
176 MessageLoop ui_loop_;
177 content::TestBrowserThread ui_thread_;
178 content::TestBrowserThread io_thread_;
179 NiceMock<ProfileMock> mock_profile_;
180 // Created/used/destroyed on I/O thread.
181 FakeSyncNotifierObserverIO* io_observer_;
182 bool io_observer_notification_failure_;
183 ChromeSyncNotificationBridge bridge_;
184 base::WaitableEvent done_;
185 };
186
187 // Adds an observer on the UI thread, triggers a refresh notification, and
188 // ensures the bridge posts a LOCAL_NOTIFICATION with the proper payload to it.
189 TEST_F(ChromeSyncNotificationBridgeTest, Basic) {
190 syncable::ModelTypePayloadMap payload_map;
191 payload_map[syncable::SESSIONS] = "";
192 StrictMock<MockSyncNotifierObserver> observer;
193 EXPECT_CALL(observer,
194 OnIncomingNotification(payload_map, LOCAL_NOTIFICATION));
195 bridge_.AddObserver(&observer);
196 TriggerRefreshNotification();
197 ui_loop_.RunAllPending();
198 Mock::VerifyAndClearExpectations(&observer);
199 }
200
201 // Adds an observer on the I/O thread. Then triggers a refresh notification on
202 // the UI thread. We finally verify the proper notification was received by the
203 // observer and destroy it on the I/O thread.
204 TEST_F(ChromeSyncNotificationBridgeTest, BasicThreaded) {
205 syncable::ModelTypePayloadMap payload_map;
206 payload_map[syncable::SESSIONS] = "";
207 CreateObserverWithExpectedPayload(payload_map);
208 TriggerRefreshNotification();
209 VerifyAndDestroyObserver();
210 }
211
212 } // namespace
213 } // namespace sync_notifier
OLDNEW
« no previous file with comments | « chrome/browser/sync/notifier/chrome_sync_notification_bridge.cc ('k') | chrome/browser/sync/notifier/sync_notifier_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698