OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 "components/invalidation/p2p_invalidator.h" | |
6 | |
7 #include <cstddef> | |
8 | |
9 #include "components/invalidation/fake_invalidation_handler.h" | |
10 #include "components/invalidation/invalidator_state.h" | |
11 #include "components/invalidation/invalidator_test_template.h" | |
12 #include "components/invalidation/notifier_reason_util.h" | |
13 #include "jingle/notifier/listener/fake_push_client.h" | |
14 #include "testing/gtest/include/gtest/gtest.h" | |
15 | |
16 namespace syncer { | |
17 | |
18 namespace { | |
19 | |
20 class P2PInvalidatorTestDelegate { | |
21 public: | |
22 P2PInvalidatorTestDelegate() : fake_push_client_(NULL) {} | |
23 | |
24 ~P2PInvalidatorTestDelegate() { | |
25 DestroyInvalidator(); | |
26 } | |
27 | |
28 void CreateInvalidator( | |
29 const std::string& invalidator_client_id, | |
30 const std::string& initial_state, | |
31 const base::WeakPtr<InvalidationStateTracker>& | |
32 invalidation_state_tracker) { | |
33 DCHECK(!fake_push_client_); | |
34 DCHECK(!invalidator_.get()); | |
35 fake_push_client_ = new notifier::FakePushClient(); | |
36 invalidator_.reset( | |
37 new P2PInvalidator( | |
38 scoped_ptr<notifier::PushClient>(fake_push_client_), | |
39 invalidator_client_id, | |
40 NOTIFY_OTHERS)); | |
41 } | |
42 | |
43 P2PInvalidator* GetInvalidator() { | |
44 return invalidator_.get(); | |
45 } | |
46 | |
47 notifier::FakePushClient* GetPushClient() { | |
48 return fake_push_client_; | |
49 } | |
50 | |
51 void DestroyInvalidator() { | |
52 invalidator_.reset(); | |
53 fake_push_client_ = NULL; | |
54 } | |
55 | |
56 void WaitForInvalidator() { | |
57 // Do Nothing. | |
58 } | |
59 | |
60 void TriggerOnInvalidatorStateChange(InvalidatorState state) { | |
61 if (state == INVALIDATIONS_ENABLED) { | |
62 fake_push_client_->EnableNotifications(); | |
63 } else { | |
64 fake_push_client_->DisableNotifications(ToNotifierReasonForTest(state)); | |
65 } | |
66 } | |
67 | |
68 void TriggerOnIncomingInvalidation( | |
69 const ObjectIdInvalidationMap& invalidation_map) { | |
70 const P2PNotificationData notification_data( | |
71 std::string(), NOTIFY_ALL, invalidation_map); | |
72 notifier::Notification notification; | |
73 notification.channel = kSyncP2PNotificationChannel; | |
74 notification.data = notification_data.ToString(); | |
75 fake_push_client_->SimulateIncomingNotification(notification); | |
76 } | |
77 | |
78 private: | |
79 // Owned by |invalidator_|. | |
80 notifier::FakePushClient* fake_push_client_; | |
81 scoped_ptr<P2PInvalidator> invalidator_; | |
82 }; | |
83 | |
84 class P2PInvalidatorTest : public testing::Test { | |
85 protected: | |
86 P2PInvalidatorTest() | |
87 : next_sent_notification_to_reflect_(0) { | |
88 default_enabled_ids_.insert(invalidation::ObjectId(10, "A")); | |
89 default_enabled_ids_.insert(invalidation::ObjectId(10, "B")); | |
90 delegate_.CreateInvalidator("sender", | |
91 "fake_state", | |
92 base::WeakPtr<InvalidationStateTracker>()); | |
93 delegate_.GetInvalidator()->RegisterHandler(&fake_handler_); | |
94 } | |
95 | |
96 ~P2PInvalidatorTest() override { | |
97 delegate_.GetInvalidator()->UnregisterHandler(&fake_handler_); | |
98 } | |
99 | |
100 ObjectIdInvalidationMap MakeInvalidationMap(ObjectIdSet ids) { | |
101 return ObjectIdInvalidationMap::InvalidateAll(ids); | |
102 } | |
103 | |
104 // Simulate receiving all the notifications we sent out since last | |
105 // time this was called. | |
106 void ReflectSentNotifications() { | |
107 const std::vector<notifier::Notification>& sent_notifications = | |
108 delegate_.GetPushClient()->sent_notifications(); | |
109 for(size_t i = next_sent_notification_to_reflect_; | |
110 i < sent_notifications.size(); ++i) { | |
111 delegate_.GetInvalidator()->OnIncomingNotification(sent_notifications[i]); | |
112 } | |
113 next_sent_notification_to_reflect_ = sent_notifications.size(); | |
114 } | |
115 | |
116 ObjectIdSet default_enabled_ids_; | |
117 | |
118 FakeInvalidationHandler fake_handler_; | |
119 P2PInvalidatorTestDelegate delegate_; | |
120 | |
121 private: | |
122 size_t next_sent_notification_to_reflect_; | |
123 }; | |
124 | |
125 // Make sure the P2PNotificationTarget <-> string conversions work. | |
126 TEST_F(P2PInvalidatorTest, P2PNotificationTarget) { | |
127 for (int i = FIRST_NOTIFICATION_TARGET; | |
128 i <= LAST_NOTIFICATION_TARGET; ++i) { | |
129 P2PNotificationTarget target = static_cast<P2PNotificationTarget>(i); | |
130 const std::string& target_str = P2PNotificationTargetToString(target); | |
131 EXPECT_FALSE(target_str.empty()); | |
132 EXPECT_EQ(target, P2PNotificationTargetFromString(target_str)); | |
133 } | |
134 EXPECT_EQ(NOTIFY_SELF, P2PNotificationTargetFromString("unknown")); | |
135 } | |
136 | |
137 // Make sure notification targeting works correctly. | |
138 TEST_F(P2PInvalidatorTest, P2PNotificationDataIsTargeted) { | |
139 { | |
140 const P2PNotificationData notification_data( | |
141 "sender", NOTIFY_SELF, ObjectIdInvalidationMap()); | |
142 EXPECT_TRUE(notification_data.IsTargeted("sender")); | |
143 EXPECT_FALSE(notification_data.IsTargeted("other1")); | |
144 EXPECT_FALSE(notification_data.IsTargeted("other2")); | |
145 } | |
146 { | |
147 const P2PNotificationData notification_data( | |
148 "sender", NOTIFY_OTHERS, ObjectIdInvalidationMap()); | |
149 EXPECT_FALSE(notification_data.IsTargeted("sender")); | |
150 EXPECT_TRUE(notification_data.IsTargeted("other1")); | |
151 EXPECT_TRUE(notification_data.IsTargeted("other2")); | |
152 } | |
153 { | |
154 const P2PNotificationData notification_data( | |
155 "sender", NOTIFY_ALL, ObjectIdInvalidationMap()); | |
156 EXPECT_TRUE(notification_data.IsTargeted("sender")); | |
157 EXPECT_TRUE(notification_data.IsTargeted("other1")); | |
158 EXPECT_TRUE(notification_data.IsTargeted("other2")); | |
159 } | |
160 } | |
161 | |
162 // Make sure the P2PNotificationData <-> string conversions work for a | |
163 // default-constructed P2PNotificationData. | |
164 TEST_F(P2PInvalidatorTest, P2PNotificationDataDefault) { | |
165 const P2PNotificationData notification_data; | |
166 EXPECT_TRUE(notification_data.IsTargeted(std::string())); | |
167 EXPECT_FALSE(notification_data.IsTargeted("other1")); | |
168 EXPECT_FALSE(notification_data.IsTargeted("other2")); | |
169 EXPECT_TRUE(notification_data.GetIdInvalidationMap().Empty()); | |
170 const std::string& notification_data_str = notification_data.ToString(); | |
171 EXPECT_EQ( | |
172 "{\"invalidations\":[],\"notificationType\":\"notifySelf\"," | |
173 "\"senderId\":\"\"}", notification_data_str); | |
174 | |
175 P2PNotificationData notification_data_parsed; | |
176 EXPECT_TRUE(notification_data_parsed.ResetFromString(notification_data_str)); | |
177 EXPECT_TRUE(notification_data.Equals(notification_data_parsed)); | |
178 } | |
179 | |
180 // Make sure the P2PNotificationData <-> string conversions work for a | |
181 // non-default-constructed P2PNotificationData. | |
182 TEST_F(P2PInvalidatorTest, P2PNotificationDataNonDefault) { | |
183 ObjectIdInvalidationMap invalidation_map = | |
184 ObjectIdInvalidationMap::InvalidateAll(default_enabled_ids_); | |
185 const P2PNotificationData notification_data("sender", | |
186 NOTIFY_ALL, | |
187 invalidation_map); | |
188 EXPECT_TRUE(notification_data.IsTargeted("sender")); | |
189 EXPECT_TRUE(notification_data.IsTargeted("other1")); | |
190 EXPECT_TRUE(notification_data.IsTargeted("other2")); | |
191 EXPECT_EQ(invalidation_map, notification_data.GetIdInvalidationMap()); | |
192 const std::string& notification_data_str = notification_data.ToString(); | |
193 EXPECT_EQ( | |
194 "{\"invalidations\":[" | |
195 "{\"isUnknownVersion\":true," | |
196 "\"objectId\":{\"name\":\"A\",\"source\":10}}," | |
197 "{\"isUnknownVersion\":true," | |
198 "\"objectId\":{\"name\":\"B\",\"source\":10}}" | |
199 "],\"notificationType\":\"notifyAll\"," | |
200 "\"senderId\":\"sender\"}", | |
201 notification_data_str); | |
202 | |
203 P2PNotificationData notification_data_parsed; | |
204 EXPECT_TRUE(notification_data_parsed.ResetFromString(notification_data_str)); | |
205 EXPECT_TRUE(notification_data.Equals(notification_data_parsed)); | |
206 } | |
207 | |
208 // Set up the P2PInvalidator, simulate a successful connection, and send | |
209 // a notification with the default target (NOTIFY_OTHERS). The | |
210 // observer should receive only a notification from the call to | |
211 // UpdateEnabledTypes(). | |
212 TEST_F(P2PInvalidatorTest, NotificationsBasic) { | |
213 P2PInvalidator* const invalidator = delegate_.GetInvalidator(); | |
214 notifier::FakePushClient* const push_client = delegate_.GetPushClient(); | |
215 | |
216 invalidator->UpdateRegisteredIds(&fake_handler_, default_enabled_ids_); | |
217 | |
218 const char kEmail[] = "foo@bar.com"; | |
219 const char kToken[] = "token"; | |
220 invalidator->UpdateCredentials(kEmail, kToken); | |
221 { | |
222 notifier::Subscription expected_subscription; | |
223 expected_subscription.channel = kSyncP2PNotificationChannel; | |
224 expected_subscription.from = kEmail; | |
225 EXPECT_TRUE(notifier::SubscriptionListsEqual( | |
226 push_client->subscriptions(), | |
227 notifier::SubscriptionList(1, expected_subscription))); | |
228 } | |
229 EXPECT_EQ(kEmail, push_client->email()); | |
230 EXPECT_EQ(kToken, push_client->token()); | |
231 | |
232 ReflectSentNotifications(); | |
233 push_client->EnableNotifications(); | |
234 EXPECT_EQ(INVALIDATIONS_ENABLED, fake_handler_.GetInvalidatorState()); | |
235 | |
236 ReflectSentNotifications(); | |
237 EXPECT_EQ(1, fake_handler_.GetInvalidationCount()); | |
238 EXPECT_THAT(MakeInvalidationMap(default_enabled_ids_), | |
239 Eq(fake_handler_.GetLastInvalidationMap())); | |
240 | |
241 // Sent with target NOTIFY_OTHERS so should not be propagated to | |
242 // |fake_handler_|. | |
243 invalidator->SendInvalidation(default_enabled_ids_); | |
244 | |
245 ReflectSentNotifications(); | |
246 EXPECT_EQ(1, fake_handler_.GetInvalidationCount()); | |
247 } | |
248 | |
249 // Set up the P2PInvalidator and send out notifications with various | |
250 // target settings. The notifications received by the observer should | |
251 // be consistent with the target settings. | |
252 TEST_F(P2PInvalidatorTest, SendNotificationData) { | |
253 ObjectIdSet enabled_ids; | |
254 ObjectIdSet changed_ids; | |
255 ObjectIdSet expected_ids; | |
256 | |
257 enabled_ids.insert(invalidation::ObjectId(20, "A")); | |
258 enabled_ids.insert(invalidation::ObjectId(20, "B")); | |
259 enabled_ids.insert(invalidation::ObjectId(20, "C")); | |
260 | |
261 changed_ids.insert(invalidation::ObjectId(20, "A")); | |
262 changed_ids.insert(invalidation::ObjectId(20, "Z")); | |
263 | |
264 expected_ids.insert(invalidation::ObjectId(20, "A")); | |
265 | |
266 const ObjectIdInvalidationMap& invalidation_map = | |
267 MakeInvalidationMap(changed_ids); | |
268 | |
269 P2PInvalidator* const invalidator = delegate_.GetInvalidator(); | |
270 notifier::FakePushClient* const push_client = delegate_.GetPushClient(); | |
271 | |
272 invalidator->UpdateRegisteredIds(&fake_handler_, enabled_ids); | |
273 | |
274 invalidator->UpdateCredentials("foo@bar.com", "fake_token"); | |
275 | |
276 ReflectSentNotifications(); | |
277 push_client->EnableNotifications(); | |
278 EXPECT_EQ(INVALIDATIONS_ENABLED, fake_handler_.GetInvalidatorState()); | |
279 | |
280 ReflectSentNotifications(); | |
281 EXPECT_EQ(1, fake_handler_.GetInvalidationCount()); | |
282 EXPECT_EQ(enabled_ids, fake_handler_.GetLastInvalidationMap().GetObjectIds()); | |
283 | |
284 // Should be dropped. | |
285 invalidator->SendNotificationDataForTest(P2PNotificationData()); | |
286 ReflectSentNotifications(); | |
287 EXPECT_EQ(1, fake_handler_.GetInvalidationCount()); | |
288 | |
289 // Should be propagated. | |
290 invalidator->SendNotificationDataForTest( | |
291 P2PNotificationData("sender", NOTIFY_SELF, invalidation_map)); | |
292 ReflectSentNotifications(); | |
293 EXPECT_EQ(2, fake_handler_.GetInvalidationCount()); | |
294 EXPECT_EQ(expected_ids, | |
295 fake_handler_.GetLastInvalidationMap().GetObjectIds()); | |
296 | |
297 // Should be dropped. | |
298 invalidator->SendNotificationDataForTest( | |
299 P2PNotificationData("sender2", NOTIFY_SELF, invalidation_map)); | |
300 ReflectSentNotifications(); | |
301 EXPECT_EQ(2, fake_handler_.GetInvalidationCount()); | |
302 | |
303 // Should be dropped. | |
304 invalidator->SendNotificationDataForTest( | |
305 P2PNotificationData("sender", NOTIFY_SELF, ObjectIdInvalidationMap())); | |
306 ReflectSentNotifications(); | |
307 EXPECT_EQ(2, fake_handler_.GetInvalidationCount()); | |
308 | |
309 // Should be dropped. | |
310 invalidator->SendNotificationDataForTest( | |
311 P2PNotificationData("sender", NOTIFY_OTHERS, invalidation_map)); | |
312 ReflectSentNotifications(); | |
313 EXPECT_EQ(2, fake_handler_.GetInvalidationCount()); | |
314 | |
315 // Should be propagated. | |
316 invalidator->SendNotificationDataForTest( | |
317 P2PNotificationData("sender2", NOTIFY_OTHERS, invalidation_map)); | |
318 ReflectSentNotifications(); | |
319 EXPECT_EQ(3, fake_handler_.GetInvalidationCount()); | |
320 EXPECT_EQ(expected_ids, | |
321 fake_handler_.GetLastInvalidationMap().GetObjectIds()); | |
322 | |
323 // Should be dropped. | |
324 invalidator->SendNotificationDataForTest( | |
325 P2PNotificationData("sender2", NOTIFY_OTHERS, ObjectIdInvalidationMap())); | |
326 ReflectSentNotifications(); | |
327 EXPECT_EQ(3, fake_handler_.GetInvalidationCount()); | |
328 | |
329 // Should be propagated. | |
330 invalidator->SendNotificationDataForTest( | |
331 P2PNotificationData("sender", NOTIFY_ALL, invalidation_map)); | |
332 ReflectSentNotifications(); | |
333 EXPECT_EQ(4, fake_handler_.GetInvalidationCount()); | |
334 EXPECT_EQ(expected_ids, | |
335 fake_handler_.GetLastInvalidationMap().GetObjectIds()); | |
336 | |
337 // Should be propagated. | |
338 invalidator->SendNotificationDataForTest( | |
339 P2PNotificationData("sender2", NOTIFY_ALL, invalidation_map)); | |
340 ReflectSentNotifications(); | |
341 EXPECT_EQ(5, fake_handler_.GetInvalidationCount()); | |
342 EXPECT_EQ(expected_ids, | |
343 fake_handler_.GetLastInvalidationMap().GetObjectIds()); | |
344 | |
345 // Should be dropped. | |
346 invalidator->SendNotificationDataForTest( | |
347 P2PNotificationData("sender2", NOTIFY_ALL, ObjectIdInvalidationMap())); | |
348 ReflectSentNotifications(); | |
349 EXPECT_EQ(5, fake_handler_.GetInvalidationCount()); | |
350 } | |
351 | |
352 INSTANTIATE_TYPED_TEST_CASE_P( | |
353 P2PInvalidatorTest, InvalidatorTest, | |
354 P2PInvalidatorTestDelegate); | |
355 | |
356 } // namespace | |
357 | |
358 } // namespace syncer | |
OLD | NEW |