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

Side by Side Diff: components/invalidation/invalidation_service_test_template.h

Issue 1191393008: Introduce a layering in the invalidation component as public and impl (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Explicitly forbid content to prevent future additions Created 5 years, 5 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
OLDNEW
(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 // This class defines tests that implementations of InvalidationService should
6 // pass in order to be conformant. Here's how you use it to test your
7 // implementation.
8 //
9 // Say your class is called MyInvalidationService. Then you need to define a
10 // class called MyInvalidationServiceTestDelegate in
11 // my_invalidation_frontend_unittest.cc like this:
12 //
13 // class MyInvalidationServiceTestDelegate {
14 // public:
15 // MyInvalidationServiceTestDelegate() ...
16 //
17 // ~MyInvalidationServiceTestDelegate() {
18 // // DestroyInvalidator() may not be explicitly called by tests.
19 // DestroyInvalidator();
20 // }
21 //
22 // // Create the InvalidationService implementation with the given params.
23 // void CreateInvalidationService() {
24 // ...
25 // }
26 //
27 // // Should return the InvalidationService implementation. Only called
28 // // after CreateInvalidator and before DestroyInvalidator.
29 // MyInvalidationService* GetInvalidationService() {
30 // ...
31 // }
32 //
33 // // Destroy the InvalidationService implementation.
34 // void DestroyInvalidationService() {
35 // ...
36 // }
37 //
38 // // The Trigger* functions below should block until the effects of
39 // // the call are visible on the current thread.
40 //
41 // // Should cause OnInvalidatorStateChange() to be called on all
42 // // observers of the InvalidationService implementation with the given
43 // // parameters.
44 // void TriggerOnInvalidatorStateChange(InvalidatorState state) {
45 // ...
46 // }
47 //
48 // // Should cause OnIncomingInvalidation() to be called on all
49 // // observers of the InvalidationService implementation with the given
50 // // parameters.
51 // void TriggerOnIncomingInvalidation(
52 // const ObjectIdInvalidationMap& invalidation_map) {
53 // ...
54 // }
55 // };
56 //
57 // The InvalidationServiceTest test harness will have a member variable of
58 // this delegate type and will call its functions in the various
59 // tests.
60 //
61 // Then you simply #include this file as well as gtest.h and add the
62 // following statement to my_sync_notifier_unittest.cc:
63 //
64 // INSTANTIATE_TYPED_TEST_CASE_P(
65 // MyInvalidationService,
66 // InvalidationServiceTest,
67 // MyInvalidatorTestDelegate);
68 //
69 // Easy!
70
71 #ifndef COMPONENTS_INVALIDATION_INVALIDATION_SERVICE_TEST_TEMPLATE_H_
72 #define COMPONENTS_INVALIDATION_INVALIDATION_SERVICE_TEST_TEMPLATE_H_
73
74 #include "base/basictypes.h"
75 #include "base/compiler_specific.h"
76 #include "components/invalidation/ack_handle.h"
77 #include "components/invalidation/fake_invalidation_handler.h"
78 #include "components/invalidation/invalidation.h"
79 #include "components/invalidation/invalidation_service.h"
80 #include "components/invalidation/object_id_invalidation_map.h"
81 #include "components/invalidation/object_id_invalidation_map_test_util.h"
82 #include "google/cacheinvalidation/include/types.h"
83 #include "google/cacheinvalidation/types.pb.h"
84 #include "testing/gtest/include/gtest/gtest.h"
85
86 template <typename InvalidatorTestDelegate>
87 class InvalidationServiceTest : public testing::Test {
88 protected:
89 InvalidationServiceTest()
90 : id1(ipc::invalidation::ObjectSource::CHROME_SYNC, "BOOKMARK"),
91 id2(ipc::invalidation::ObjectSource::CHROME_SYNC, "PREFERENCE"),
92 id3(ipc::invalidation::ObjectSource::CHROME_SYNC, "AUTOFILL"),
93 id4(ipc::invalidation::ObjectSource::CHROME_PUSH_MESSAGING,
94 "PUSH_MESSAGE") {
95 }
96
97 invalidation::InvalidationService*
98 CreateAndInitializeInvalidationService() {
99 this->delegate_.CreateInvalidationService();
100 return this->delegate_.GetInvalidationService();
101 }
102
103 InvalidatorTestDelegate delegate_;
104
105 const invalidation::ObjectId id1;
106 const invalidation::ObjectId id2;
107 const invalidation::ObjectId id3;
108 const invalidation::ObjectId id4;
109 };
110
111 TYPED_TEST_CASE_P(InvalidationServiceTest);
112
113 // Initialize the invalidator, register a handler, register some IDs for that
114 // handler, and then unregister the handler, dispatching invalidations in
115 // between. The handler should only see invalidations when its registered and
116 // its IDs are registered.
117 TYPED_TEST_P(InvalidationServiceTest, Basic) {
118 invalidation::InvalidationService* const invalidator =
119 this->CreateAndInitializeInvalidationService();
120
121 syncer::FakeInvalidationHandler handler;
122
123 invalidator->RegisterInvalidationHandler(&handler);
124
125 syncer::ObjectIdInvalidationMap invalidation_map;
126 invalidation_map.Insert(syncer::Invalidation::Init(this->id1, 1, "1"));
127 invalidation_map.Insert(syncer::Invalidation::Init(this->id2, 2, "2"));
128 invalidation_map.Insert(syncer::Invalidation::Init(this->id3, 3, "3"));
129
130 // Should be ignored since no IDs are registered to |handler|.
131 this->delegate_.TriggerOnIncomingInvalidation(invalidation_map);
132 EXPECT_EQ(0, handler.GetInvalidationCount());
133
134 syncer::ObjectIdSet ids;
135 ids.insert(this->id1);
136 ids.insert(this->id2);
137 EXPECT_TRUE(invalidator->UpdateRegisteredInvalidationIds(&handler, ids));
138
139 this->delegate_.TriggerOnInvalidatorStateChange(
140 syncer::INVALIDATIONS_ENABLED);
141 EXPECT_EQ(syncer::INVALIDATIONS_ENABLED, handler.GetInvalidatorState());
142
143 syncer::ObjectIdInvalidationMap expected_invalidations;
144 expected_invalidations.Insert(syncer::Invalidation::Init(this->id1, 1, "1"));
145 expected_invalidations.Insert(syncer::Invalidation::Init(this->id2, 2, "2"));
146
147 this->delegate_.TriggerOnIncomingInvalidation(invalidation_map);
148 EXPECT_EQ(1, handler.GetInvalidationCount());
149 EXPECT_THAT(expected_invalidations, Eq(handler.GetLastInvalidationMap()));
150
151 ids.erase(this->id1);
152 ids.insert(this->id3);
153 EXPECT_TRUE(invalidator->UpdateRegisteredInvalidationIds(&handler, ids));
154
155 expected_invalidations = syncer::ObjectIdInvalidationMap();
156 expected_invalidations.Insert(syncer::Invalidation::Init(this->id2, 2, "2"));
157 expected_invalidations.Insert(syncer::Invalidation::Init(this->id3, 3, "3"));
158
159 // Removed object IDs should not be notified, newly-added ones should.
160 this->delegate_.TriggerOnIncomingInvalidation(invalidation_map);
161 EXPECT_EQ(2, handler.GetInvalidationCount());
162 EXPECT_THAT(expected_invalidations, Eq(handler.GetLastInvalidationMap()));
163
164 this->delegate_.TriggerOnInvalidatorStateChange(
165 syncer::TRANSIENT_INVALIDATION_ERROR);
166 EXPECT_EQ(syncer::TRANSIENT_INVALIDATION_ERROR,
167 handler.GetInvalidatorState());
168
169 this->delegate_.TriggerOnInvalidatorStateChange(
170 syncer::INVALIDATIONS_ENABLED);
171 EXPECT_EQ(syncer::INVALIDATIONS_ENABLED,
172 handler.GetInvalidatorState());
173
174 invalidator->UnregisterInvalidationHandler(&handler);
175
176 // Should be ignored since |handler| isn't registered anymore.
177 this->delegate_.TriggerOnIncomingInvalidation(invalidation_map);
178 EXPECT_EQ(2, handler.GetInvalidationCount());
179 }
180
181 // Register handlers and some IDs for those handlers, register a handler with
182 // no IDs, and register a handler with some IDs but unregister it. Then,
183 // dispatch some invalidations and invalidations. Handlers that are registered
184 // should get invalidations, and the ones that have registered IDs should
185 // receive invalidations for those IDs.
186 TYPED_TEST_P(InvalidationServiceTest, MultipleHandlers) {
187 invalidation::InvalidationService* const invalidator =
188 this->CreateAndInitializeInvalidationService();
189
190 syncer::FakeInvalidationHandler handler1;
191 syncer::FakeInvalidationHandler handler2;
192 syncer::FakeInvalidationHandler handler3;
193 syncer::FakeInvalidationHandler handler4;
194
195 invalidator->RegisterInvalidationHandler(&handler1);
196 invalidator->RegisterInvalidationHandler(&handler2);
197 invalidator->RegisterInvalidationHandler(&handler3);
198 invalidator->RegisterInvalidationHandler(&handler4);
199
200 {
201 syncer::ObjectIdSet ids;
202 ids.insert(this->id1);
203 ids.insert(this->id2);
204 EXPECT_TRUE(invalidator->UpdateRegisteredInvalidationIds(&handler1, ids));
205 }
206
207 {
208 syncer::ObjectIdSet ids;
209 ids.insert(this->id3);
210 EXPECT_TRUE(invalidator->UpdateRegisteredInvalidationIds(&handler2, ids));
211 }
212
213 // Don't register any IDs for handler3.
214
215 {
216 syncer::ObjectIdSet ids;
217 ids.insert(this->id4);
218 EXPECT_TRUE(invalidator->UpdateRegisteredInvalidationIds(&handler4, ids));
219 }
220
221 invalidator->UnregisterInvalidationHandler(&handler4);
222
223 this->delegate_.TriggerOnInvalidatorStateChange(
224 syncer::INVALIDATIONS_ENABLED);
225 EXPECT_EQ(syncer::INVALIDATIONS_ENABLED, handler1.GetInvalidatorState());
226 EXPECT_EQ(syncer::INVALIDATIONS_ENABLED, handler2.GetInvalidatorState());
227 EXPECT_EQ(syncer::INVALIDATIONS_ENABLED, handler3.GetInvalidatorState());
228 EXPECT_EQ(syncer::TRANSIENT_INVALIDATION_ERROR,
229 handler4.GetInvalidatorState());
230
231 {
232 syncer::ObjectIdInvalidationMap invalidation_map;
233 invalidation_map.Insert(syncer::Invalidation::Init(this->id1, 1, "1"));
234 invalidation_map.Insert(syncer::Invalidation::Init(this->id2, 2, "2"));
235 invalidation_map.Insert(syncer::Invalidation::Init(this->id3, 3, "3"));
236 invalidation_map.Insert(syncer::Invalidation::Init(this->id4, 4, "4"));
237 this->delegate_.TriggerOnIncomingInvalidation(invalidation_map);
238
239 syncer::ObjectIdInvalidationMap expected_invalidations;
240 expected_invalidations.Insert(
241 syncer::Invalidation::Init(this->id1, 1, "1"));
242 expected_invalidations.Insert(
243 syncer::Invalidation::Init(this->id2, 2, "2"));
244
245 EXPECT_EQ(1, handler1.GetInvalidationCount());
246 EXPECT_THAT(expected_invalidations, Eq(handler1.GetLastInvalidationMap()));
247
248 expected_invalidations = syncer::ObjectIdInvalidationMap();
249 expected_invalidations.Insert(
250 syncer::Invalidation::Init(this->id3, 3, "3"));
251
252 EXPECT_EQ(1, handler2.GetInvalidationCount());
253 EXPECT_THAT(expected_invalidations, Eq(handler2.GetLastInvalidationMap()));
254
255 EXPECT_EQ(0, handler3.GetInvalidationCount());
256 EXPECT_EQ(0, handler4.GetInvalidationCount());
257 }
258
259 this->delegate_.TriggerOnInvalidatorStateChange(
260 syncer::TRANSIENT_INVALIDATION_ERROR);
261 EXPECT_EQ(syncer::TRANSIENT_INVALIDATION_ERROR,
262 handler1.GetInvalidatorState());
263 EXPECT_EQ(syncer::TRANSIENT_INVALIDATION_ERROR,
264 handler2.GetInvalidatorState());
265 EXPECT_EQ(syncer::TRANSIENT_INVALIDATION_ERROR,
266 handler3.GetInvalidatorState());
267 EXPECT_EQ(syncer::TRANSIENT_INVALIDATION_ERROR,
268 handler4.GetInvalidatorState());
269
270 invalidator->UnregisterInvalidationHandler(&handler3);
271 invalidator->UnregisterInvalidationHandler(&handler2);
272 invalidator->UnregisterInvalidationHandler(&handler1);
273 }
274
275 // Multiple registrations by different handlers on the same object ID should
276 // return false.
277 TYPED_TEST_P(InvalidationServiceTest, MultipleRegistrations) {
278 invalidation::InvalidationService* const invalidator =
279 this->CreateAndInitializeInvalidationService();
280
281 syncer::FakeInvalidationHandler handler1;
282 syncer::FakeInvalidationHandler handler2;
283
284 invalidator->RegisterInvalidationHandler(&handler1);
285 invalidator->RegisterInvalidationHandler(&handler2);
286
287 // Registering both handlers for the same ObjectId. First call should succeed,
288 // second should fail.
289 syncer::ObjectIdSet ids;
290 ids.insert(this->id1);
291 EXPECT_TRUE(invalidator->UpdateRegisteredInvalidationIds(&handler1, ids));
292 EXPECT_FALSE(invalidator->UpdateRegisteredInvalidationIds(&handler2, ids));
293
294 invalidator->UnregisterInvalidationHandler(&handler2);
295 invalidator->UnregisterInvalidationHandler(&handler1);
296 }
297
298 // Make sure that passing an empty set to UpdateRegisteredInvalidationIds clears
299 // the corresponding entries for the handler.
300 TYPED_TEST_P(InvalidationServiceTest, EmptySetUnregisters) {
301 invalidation::InvalidationService* const invalidator =
302 this->CreateAndInitializeInvalidationService();
303
304 syncer::FakeInvalidationHandler handler1;
305
306 // Control observer.
307 syncer::FakeInvalidationHandler handler2;
308
309 invalidator->RegisterInvalidationHandler(&handler1);
310 invalidator->RegisterInvalidationHandler(&handler2);
311
312 {
313 syncer::ObjectIdSet ids;
314 ids.insert(this->id1);
315 ids.insert(this->id2);
316 EXPECT_TRUE(invalidator->UpdateRegisteredInvalidationIds(&handler1, ids));
317 }
318
319 {
320 syncer::ObjectIdSet ids;
321 ids.insert(this->id3);
322 EXPECT_TRUE(invalidator->UpdateRegisteredInvalidationIds(&handler2, ids));
323 }
324
325 // Unregister the IDs for the first observer. It should not receive any
326 // further invalidations.
327 EXPECT_TRUE(invalidator->UpdateRegisteredInvalidationIds(
328 &handler1, syncer::ObjectIdSet()));
329
330 this->delegate_.TriggerOnInvalidatorStateChange(
331 syncer::INVALIDATIONS_ENABLED);
332 EXPECT_EQ(syncer::INVALIDATIONS_ENABLED, handler1.GetInvalidatorState());
333 EXPECT_EQ(syncer::INVALIDATIONS_ENABLED, handler2.GetInvalidatorState());
334
335 {
336 syncer::ObjectIdInvalidationMap invalidation_map;
337 invalidation_map.Insert(syncer::Invalidation::Init(this->id1, 1, "1"));
338 invalidation_map.Insert(syncer::Invalidation::Init(this->id2, 2, "2"));
339 invalidation_map.Insert(syncer::Invalidation::Init(this->id3, 3, "3"));
340 this->delegate_.TriggerOnIncomingInvalidation(invalidation_map);
341 EXPECT_EQ(0, handler1.GetInvalidationCount());
342 EXPECT_EQ(1, handler2.GetInvalidationCount());
343 }
344
345 this->delegate_.TriggerOnInvalidatorStateChange(
346 syncer::TRANSIENT_INVALIDATION_ERROR);
347 EXPECT_EQ(syncer::TRANSIENT_INVALIDATION_ERROR,
348 handler1.GetInvalidatorState());
349 EXPECT_EQ(syncer::TRANSIENT_INVALIDATION_ERROR,
350 handler2.GetInvalidatorState());
351
352 invalidator->UnregisterInvalidationHandler(&handler2);
353 invalidator->UnregisterInvalidationHandler(&handler1);
354 }
355
356 namespace internal {
357
358 // A FakeInvalidationHandler that is "bound" to a specific
359 // InvalidationService. This is for cross-referencing state information with
360 // the bound InvalidationService.
361 class BoundFakeInvalidationHandler : public syncer::FakeInvalidationHandler {
362 public:
363 explicit BoundFakeInvalidationHandler(
364 const invalidation::InvalidationService& invalidator);
365 ~BoundFakeInvalidationHandler() override;
366
367 // Returns the last return value of GetInvalidatorState() on the
368 // bound invalidator from the last time the invalidator state
369 // changed.
370 syncer::InvalidatorState GetLastRetrievedState() const;
371
372 // InvalidationHandler implementation.
373 void OnInvalidatorStateChange(syncer::InvalidatorState state) override;
374
375 private:
376 const invalidation::InvalidationService& invalidator_;
377 syncer::InvalidatorState last_retrieved_state_;
378
379 DISALLOW_COPY_AND_ASSIGN(BoundFakeInvalidationHandler);
380 };
381
382 } // namespace internal
383
384 TYPED_TEST_P(InvalidationServiceTest, GetInvalidatorStateAlwaysCurrent) {
385 invalidation::InvalidationService* const invalidator =
386 this->CreateAndInitializeInvalidationService();
387
388 internal::BoundFakeInvalidationHandler handler(*invalidator);
389 invalidator->RegisterInvalidationHandler(&handler);
390
391 this->delegate_.TriggerOnInvalidatorStateChange(
392 syncer::INVALIDATIONS_ENABLED);
393 EXPECT_EQ(syncer::INVALIDATIONS_ENABLED, handler.GetInvalidatorState());
394 EXPECT_EQ(syncer::INVALIDATIONS_ENABLED, handler.GetLastRetrievedState());
395
396 this->delegate_.TriggerOnInvalidatorStateChange(
397 syncer::TRANSIENT_INVALIDATION_ERROR);
398 EXPECT_EQ(syncer::TRANSIENT_INVALIDATION_ERROR,
399 handler.GetInvalidatorState());
400 EXPECT_EQ(syncer::TRANSIENT_INVALIDATION_ERROR,
401 handler.GetLastRetrievedState());
402
403 invalidator->UnregisterInvalidationHandler(&handler);
404 }
405
406 REGISTER_TYPED_TEST_CASE_P(InvalidationServiceTest,
407 Basic,
408 MultipleHandlers,
409 MultipleRegistrations,
410 EmptySetUnregisters,
411 GetInvalidatorStateAlwaysCurrent);
412
413 #endif // COMPONENTS_INVALIDATION_INVALIDATION_SERVICE_TEST_TEMPLATE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698