[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 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 | // This class defines tests that implementations of Invalidator should pass in |
| 6 | // order to be conformant. Here's how you use it to test your implementation. |
| 7 | // |
| 8 | // Say your class is called MyInvalidator. Then you need to define a class |
| 9 | // called MyInvalidatorTestDelegate in my_sync_notifier_unittest.cc like this: |
| 10 | // |
| 11 | // class MyInvalidatorTestDelegate { |
| 12 | // public: |
| 13 | // MyInvalidatorTestDelegate() ... |
| 14 | // |
| 15 | // ~MyInvalidatorTestDelegate() { |
| 16 | // // DestroyInvalidator() may not be explicitly called by tests. |
| 17 | // DestroyInvalidator(); |
| 18 | // } |
| 19 | // |
| 20 | // // Create the Invalidator implementation with the given parameters. |
| 21 | // void CreateInvalidator( |
| 22 | // const std::string& initial_state, |
| 23 | // const base::WeakPtr<InvalidationStateTracker>& |
| 24 | // invalidation_state_tracker) { |
| 25 | // ... |
| 26 | // } |
| 27 | // |
| 28 | // // Should return the Invalidator implementation. Only called after |
| 29 | // // CreateInvalidator and before DestroyInvalidator. |
| 30 | // MyInvalidator* GetInvalidator() { |
| 31 | // ... |
| 32 | // } |
| 33 | // |
| 34 | // // Destroy the Invalidator implementation. |
| 35 | // void DestroyInvalidator() { |
| 36 | // ... |
| 37 | // } |
| 38 | // |
| 39 | // // Called after a call to SetStateDeprecated(), SetUniqueId(), or |
| 40 | // // UpdateCredentials() on the Invalidator implementation. Should block |
| 41 | // // until the effects of the call are visible on the current thread. |
| 42 | // void WaitForInvalidator() { |
| 43 | // ... |
| 44 | // } |
| 45 | // |
| 46 | // // The Trigger* functions below should block until the effects of |
| 47 | // // the call are visible on the current thread. |
| 48 | // |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 49 | // // Should cause OnInvalidatorStateChange() to be called on all |
| 50 | // // observers of the Invalidator implementation with the given |
| 51 | // // parameters. |
| 52 | // void TriggerOnInvalidatorStateChange(InvalidatorState state) { |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 53 | // ... |
| 54 | // } |
| 55 | // |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 56 | // // Should cause OnIncomingInvalidation() to be called on all |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 57 | // // observers of the Invalidator implementation with the given |
| 58 | // // parameters. |
[email protected] | 3e31fa4 | 2012-10-04 03:53:09 | [diff] [blame^] | 59 | // void TriggerOnIncomingInvalidation( |
| 60 | // const ObjectIdInvalidationMap& invalidation_map, |
| 61 | // IncomingInvalidationSource source) { |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 62 | // ... |
| 63 | // } |
| 64 | // |
| 65 | // // Returns whether or not the notifier handles storing the old |
| 66 | // // (deprecated) notifier state. |
| 67 | // static bool InvalidatorHandlesDeprecatedState() { |
| 68 | // return false; |
| 69 | // } |
| 70 | // }; |
| 71 | // |
| 72 | // The InvalidatorTest test harness will have a member variable of |
| 73 | // this delegate type and will call its functions in the various |
| 74 | // tests. |
| 75 | // |
| 76 | // Then you simply #include this file as well as gtest.h and add the |
| 77 | // following statement to my_sync_notifier_unittest.cc: |
| 78 | // |
| 79 | // INSTANTIATE_TYPED_TEST_CASE_P( |
| 80 | // MyInvalidator, InvalidatorTest, MyInvalidatorTestDelegate); |
| 81 | // |
| 82 | // Easy! |
| 83 | |
| 84 | #ifndef SYNC_NOTIFIER_INVALIDATOR_TEST_TEMPLATE_H_ |
| 85 | #define SYNC_NOTIFIER_INVALIDATOR_TEST_TEMPLATE_H_ |
| 86 | |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 87 | #include "base/basictypes.h" |
| 88 | #include "base/compiler_specific.h" |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 89 | #include "google/cacheinvalidation/include/types.h" |
| 90 | #include "google/cacheinvalidation/types.pb.h" |
| 91 | #include "sync/notifier/fake_invalidation_handler.h" |
| 92 | #include "sync/notifier/fake_invalidation_state_tracker.h" |
| 93 | #include "sync/notifier/invalidator.h" |
[email protected] | 3e31fa4 | 2012-10-04 03:53:09 | [diff] [blame^] | 94 | #include "sync/notifier/object_id_invalidation_map.h" |
| 95 | #include "sync/notifier/object_id_invalidation_map_test_util.h" |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 96 | #include "testing/gtest/include/gtest/gtest.h" |
| 97 | |
| 98 | namespace syncer { |
| 99 | |
| 100 | template <typename InvalidatorTestDelegate> |
| 101 | class InvalidatorTest : public testing::Test { |
| 102 | protected: |
| 103 | InvalidatorTest() |
| 104 | : id1(ipc::invalidation::ObjectSource::TEST, "a"), |
| 105 | id2(ipc::invalidation::ObjectSource::TEST, "b"), |
| 106 | id3(ipc::invalidation::ObjectSource::TEST, "c"), |
| 107 | id4(ipc::invalidation::ObjectSource::TEST, "d") { |
| 108 | } |
| 109 | |
| 110 | Invalidator* CreateAndInitializeInvalidator() { |
| 111 | this->delegate_.CreateInvalidator("fake_initial_state", |
| 112 | this->fake_tracker_.AsWeakPtr()); |
| 113 | Invalidator* const invalidator = this->delegate_.GetInvalidator(); |
| 114 | |
| 115 | // TODO(tim): This call should be a no-op. Remove once bug 124140 and |
| 116 | // associated issues are fixed. |
| 117 | invalidator->SetStateDeprecated("fake_state"); |
| 118 | this->delegate_.WaitForInvalidator(); |
[email protected] | 8cdb689 | 2012-10-03 05:54:40 | [diff] [blame] | 119 | // We don't expect |fake_tracker_|'s bootstrap data to change, as we |
| 120 | // initialized with a non-empty value previously. |
| 121 | EXPECT_TRUE(this->fake_tracker_.GetBootstrapData().empty()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 122 | invalidator->SetUniqueId("fake_id"); |
| 123 | this->delegate_.WaitForInvalidator(); |
| 124 | invalidator->UpdateCredentials("[email protected]", "fake_token"); |
| 125 | this->delegate_.WaitForInvalidator(); |
| 126 | |
| 127 | return invalidator; |
| 128 | } |
| 129 | |
| 130 | FakeInvalidationStateTracker fake_tracker_; |
| 131 | InvalidatorTestDelegate delegate_; |
| 132 | |
| 133 | const invalidation::ObjectId id1; |
| 134 | const invalidation::ObjectId id2; |
| 135 | const invalidation::ObjectId id3; |
| 136 | const invalidation::ObjectId id4; |
| 137 | }; |
| 138 | |
| 139 | TYPED_TEST_CASE_P(InvalidatorTest); |
| 140 | |
| 141 | // Initialize the invalidator, register a handler, register some IDs for that |
| 142 | // handler, and then unregister the handler, dispatching invalidations in |
| 143 | // between. The handler should only see invalidations when its registered and |
| 144 | // its IDs are registered. |
| 145 | TYPED_TEST_P(InvalidatorTest, Basic) { |
| 146 | Invalidator* const invalidator = this->CreateAndInitializeInvalidator(); |
| 147 | |
| 148 | FakeInvalidationHandler handler; |
| 149 | |
| 150 | invalidator->RegisterHandler(&handler); |
| 151 | |
[email protected] | 3e31fa4 | 2012-10-04 03:53:09 | [diff] [blame^] | 152 | ObjectIdInvalidationMap states; |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 153 | states[this->id1].payload = "1"; |
| 154 | states[this->id2].payload = "2"; |
| 155 | states[this->id3].payload = "3"; |
| 156 | |
| 157 | // Should be ignored since no IDs are registered to |handler|. |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 158 | this->delegate_.TriggerOnIncomingInvalidation(states, REMOTE_INVALIDATION); |
| 159 | EXPECT_EQ(0, handler.GetInvalidationCount()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 160 | |
| 161 | ObjectIdSet ids; |
| 162 | ids.insert(this->id1); |
| 163 | ids.insert(this->id2); |
| 164 | invalidator->UpdateRegisteredIds(&handler, ids); |
| 165 | |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 166 | this->delegate_.TriggerOnInvalidatorStateChange(INVALIDATIONS_ENABLED); |
| 167 | EXPECT_EQ(INVALIDATIONS_ENABLED, handler.GetInvalidatorState()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 168 | |
[email protected] | 3e31fa4 | 2012-10-04 03:53:09 | [diff] [blame^] | 169 | ObjectIdInvalidationMap expected_states; |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 170 | expected_states[this->id1].payload = "1"; |
| 171 | expected_states[this->id2].payload = "2"; |
| 172 | |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 173 | this->delegate_.TriggerOnIncomingInvalidation(states, REMOTE_INVALIDATION); |
| 174 | EXPECT_EQ(1, handler.GetInvalidationCount()); |
[email protected] | 3e31fa4 | 2012-10-04 03:53:09 | [diff] [blame^] | 175 | EXPECT_THAT(expected_states, Eq(handler.GetLastInvalidationMap())); |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 176 | EXPECT_EQ(REMOTE_INVALIDATION, handler.GetLastInvalidationSource()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 177 | |
| 178 | ids.erase(this->id1); |
| 179 | ids.insert(this->id3); |
| 180 | invalidator->UpdateRegisteredIds(&handler, ids); |
| 181 | |
| 182 | expected_states.erase(this->id1); |
| 183 | expected_states[this->id3].payload = "3"; |
| 184 | |
| 185 | // Removed object IDs should not be notified, newly-added ones should. |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 186 | this->delegate_.TriggerOnIncomingInvalidation(states, REMOTE_INVALIDATION); |
| 187 | EXPECT_EQ(2, handler.GetInvalidationCount()); |
[email protected] | 3e31fa4 | 2012-10-04 03:53:09 | [diff] [blame^] | 188 | EXPECT_THAT(expected_states, Eq(handler.GetLastInvalidationMap())); |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 189 | EXPECT_EQ(REMOTE_INVALIDATION, handler.GetLastInvalidationSource()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 190 | |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 191 | this->delegate_.TriggerOnInvalidatorStateChange(TRANSIENT_INVALIDATION_ERROR); |
| 192 | EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, |
| 193 | handler.GetInvalidatorState()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 194 | |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 195 | this->delegate_.TriggerOnInvalidatorStateChange( |
| 196 | INVALIDATION_CREDENTIALS_REJECTED); |
| 197 | EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, |
| 198 | handler.GetInvalidatorState()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 199 | |
| 200 | invalidator->UnregisterHandler(&handler); |
| 201 | |
| 202 | // Should be ignored since |handler| isn't registered anymore. |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 203 | this->delegate_.TriggerOnIncomingInvalidation(states, REMOTE_INVALIDATION); |
| 204 | EXPECT_EQ(2, handler.GetInvalidationCount()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 205 | } |
| 206 | |
| 207 | // Register handlers and some IDs for those handlers, register a handler with |
| 208 | // no IDs, and register a handler with some IDs but unregister it. Then, |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 209 | // dispatch some invalidations and invalidations. Handlers that are registered |
| 210 | // should get invalidations, and the ones that have registered IDs should |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 211 | // receive invalidations for those IDs. |
| 212 | TYPED_TEST_P(InvalidatorTest, MultipleHandlers) { |
| 213 | Invalidator* const invalidator = this->CreateAndInitializeInvalidator(); |
| 214 | |
| 215 | FakeInvalidationHandler handler1; |
| 216 | FakeInvalidationHandler handler2; |
| 217 | FakeInvalidationHandler handler3; |
| 218 | FakeInvalidationHandler handler4; |
| 219 | |
| 220 | invalidator->RegisterHandler(&handler1); |
| 221 | invalidator->RegisterHandler(&handler2); |
| 222 | invalidator->RegisterHandler(&handler3); |
| 223 | invalidator->RegisterHandler(&handler4); |
| 224 | |
| 225 | { |
| 226 | ObjectIdSet ids; |
| 227 | ids.insert(this->id1); |
| 228 | ids.insert(this->id2); |
| 229 | invalidator->UpdateRegisteredIds(&handler1, ids); |
| 230 | } |
| 231 | |
| 232 | { |
| 233 | ObjectIdSet ids; |
| 234 | ids.insert(this->id3); |
| 235 | invalidator->UpdateRegisteredIds(&handler2, ids); |
| 236 | } |
| 237 | |
| 238 | // Don't register any IDs for handler3. |
| 239 | |
| 240 | { |
| 241 | ObjectIdSet ids; |
| 242 | ids.insert(this->id4); |
| 243 | invalidator->UpdateRegisteredIds(&handler4, ids); |
| 244 | } |
| 245 | |
| 246 | invalidator->UnregisterHandler(&handler4); |
| 247 | |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 248 | this->delegate_.TriggerOnInvalidatorStateChange(INVALIDATIONS_ENABLED); |
| 249 | EXPECT_EQ(INVALIDATIONS_ENABLED, handler1.GetInvalidatorState()); |
| 250 | EXPECT_EQ(INVALIDATIONS_ENABLED, handler2.GetInvalidatorState()); |
| 251 | EXPECT_EQ(INVALIDATIONS_ENABLED, handler3.GetInvalidatorState()); |
| 252 | EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler4.GetInvalidatorState()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 253 | |
| 254 | { |
[email protected] | 3e31fa4 | 2012-10-04 03:53:09 | [diff] [blame^] | 255 | ObjectIdInvalidationMap states; |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 256 | states[this->id1].payload = "1"; |
| 257 | states[this->id2].payload = "2"; |
| 258 | states[this->id3].payload = "3"; |
| 259 | states[this->id4].payload = "4"; |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 260 | this->delegate_.TriggerOnIncomingInvalidation(states, REMOTE_INVALIDATION); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 261 | |
[email protected] | 3e31fa4 | 2012-10-04 03:53:09 | [diff] [blame^] | 262 | ObjectIdInvalidationMap expected_states; |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 263 | expected_states[this->id1].payload = "1"; |
| 264 | expected_states[this->id2].payload = "2"; |
| 265 | |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 266 | EXPECT_EQ(1, handler1.GetInvalidationCount()); |
[email protected] | 3e31fa4 | 2012-10-04 03:53:09 | [diff] [blame^] | 267 | EXPECT_THAT(expected_states, Eq(handler1.GetLastInvalidationMap())); |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 268 | EXPECT_EQ(REMOTE_INVALIDATION, handler1.GetLastInvalidationSource()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 269 | |
| 270 | expected_states.clear(); |
| 271 | expected_states[this->id3].payload = "3"; |
| 272 | |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 273 | EXPECT_EQ(1, handler2.GetInvalidationCount()); |
[email protected] | 3e31fa4 | 2012-10-04 03:53:09 | [diff] [blame^] | 274 | EXPECT_THAT(expected_states, Eq(handler2.GetLastInvalidationMap())); |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 275 | EXPECT_EQ(REMOTE_INVALIDATION, handler2.GetLastInvalidationSource()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 276 | |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 277 | EXPECT_EQ(0, handler3.GetInvalidationCount()); |
| 278 | EXPECT_EQ(0, handler4.GetInvalidationCount()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 279 | } |
| 280 | |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 281 | this->delegate_.TriggerOnInvalidatorStateChange(TRANSIENT_INVALIDATION_ERROR); |
| 282 | EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler1.GetInvalidatorState()); |
| 283 | EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler2.GetInvalidatorState()); |
| 284 | EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler3.GetInvalidatorState()); |
| 285 | EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler4.GetInvalidatorState()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 286 | } |
| 287 | |
| 288 | // Make sure that passing an empty set to UpdateRegisteredIds clears the |
| 289 | // corresponding entries for the handler. |
| 290 | TYPED_TEST_P(InvalidatorTest, EmptySetUnregisters) { |
| 291 | Invalidator* const invalidator = this->CreateAndInitializeInvalidator(); |
| 292 | |
| 293 | FakeInvalidationHandler handler1; |
| 294 | |
| 295 | // Control observer. |
| 296 | FakeInvalidationHandler handler2; |
| 297 | |
| 298 | invalidator->RegisterHandler(&handler1); |
| 299 | invalidator->RegisterHandler(&handler2); |
| 300 | |
| 301 | { |
| 302 | ObjectIdSet ids; |
| 303 | ids.insert(this->id1); |
| 304 | ids.insert(this->id2); |
| 305 | invalidator->UpdateRegisteredIds(&handler1, ids); |
| 306 | } |
| 307 | |
| 308 | { |
| 309 | ObjectIdSet ids; |
| 310 | ids.insert(this->id3); |
| 311 | invalidator->UpdateRegisteredIds(&handler2, ids); |
| 312 | } |
| 313 | |
| 314 | // Unregister the IDs for the first observer. It should not receive any |
| 315 | // further invalidations. |
| 316 | invalidator->UpdateRegisteredIds(&handler1, ObjectIdSet()); |
| 317 | |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 318 | this->delegate_.TriggerOnInvalidatorStateChange(INVALIDATIONS_ENABLED); |
| 319 | EXPECT_EQ(INVALIDATIONS_ENABLED, handler1.GetInvalidatorState()); |
| 320 | EXPECT_EQ(INVALIDATIONS_ENABLED, handler2.GetInvalidatorState()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 321 | |
| 322 | { |
[email protected] | 3e31fa4 | 2012-10-04 03:53:09 | [diff] [blame^] | 323 | ObjectIdInvalidationMap states; |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 324 | states[this->id1].payload = "1"; |
| 325 | states[this->id2].payload = "2"; |
| 326 | states[this->id3].payload = "3"; |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 327 | this->delegate_.TriggerOnIncomingInvalidation(states, REMOTE_INVALIDATION); |
| 328 | EXPECT_EQ(0, handler1.GetInvalidationCount()); |
| 329 | EXPECT_EQ(1, handler2.GetInvalidationCount()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 330 | } |
| 331 | |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 332 | this->delegate_.TriggerOnInvalidatorStateChange(TRANSIENT_INVALIDATION_ERROR); |
| 333 | EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler1.GetInvalidatorState()); |
| 334 | EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler2.GetInvalidatorState()); |
| 335 | } |
| 336 | |
| 337 | namespace internal { |
| 338 | |
| 339 | // A FakeInvalidationHandler that is "bound" to a specific |
| 340 | // Invalidator. This is for cross-referencing state information with |
| 341 | // the bound Invalidator. |
| 342 | class BoundFakeInvalidationHandler : public FakeInvalidationHandler { |
| 343 | public: |
| 344 | explicit BoundFakeInvalidationHandler(const Invalidator& invalidator); |
| 345 | virtual ~BoundFakeInvalidationHandler(); |
| 346 | |
| 347 | // Returns the last return value of GetInvalidatorState() on the |
| 348 | // bound invalidator from the last time the invalidator state |
| 349 | // changed. |
| 350 | InvalidatorState GetLastRetrievedState() const; |
| 351 | |
| 352 | // InvalidationHandler implementation. |
| 353 | virtual void OnInvalidatorStateChange(InvalidatorState state) OVERRIDE; |
| 354 | |
| 355 | private: |
| 356 | const Invalidator& invalidator_; |
| 357 | InvalidatorState last_retrieved_state_; |
| 358 | |
| 359 | DISALLOW_COPY_AND_ASSIGN(BoundFakeInvalidationHandler); |
| 360 | }; |
| 361 | |
| 362 | } // namespace internal |
| 363 | |
| 364 | TYPED_TEST_P(InvalidatorTest, GetInvalidatorStateAlwaysCurrent) { |
| 365 | Invalidator* const invalidator = this->CreateAndInitializeInvalidator(); |
| 366 | |
| 367 | internal::BoundFakeInvalidationHandler handler(*invalidator); |
| 368 | invalidator->RegisterHandler(&handler); |
| 369 | |
| 370 | this->delegate_.TriggerOnInvalidatorStateChange(INVALIDATIONS_ENABLED); |
| 371 | EXPECT_EQ(INVALIDATIONS_ENABLED, handler.GetInvalidatorState()); |
| 372 | EXPECT_EQ(INVALIDATIONS_ENABLED, handler.GetLastRetrievedState()); |
| 373 | |
| 374 | this->delegate_.TriggerOnInvalidatorStateChange(TRANSIENT_INVALIDATION_ERROR); |
| 375 | EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler.GetInvalidatorState()); |
| 376 | EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, handler.GetLastRetrievedState()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 377 | } |
| 378 | |
[email protected] | 8cdb689 | 2012-10-03 05:54:40 | [diff] [blame] | 379 | // Initialize the invalidator with no bootstrap data. Call the deprecated |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 380 | // state setter function a number of times, destroying and re-creating the |
[email protected] | 8cdb689 | 2012-10-03 05:54:40 | [diff] [blame] | 381 | // invalidator in between. Only the first one should take effect (i.e., |
| 382 | // migration of bootstrap data should only happen once) |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 383 | TYPED_TEST_P(InvalidatorTest, MigrateState) { |
| 384 | if (!this->delegate_.InvalidatorHandlesDeprecatedState()) { |
| 385 | DLOG(INFO) << "This Invalidator doesn't handle deprecated state; " |
| 386 | << "skipping"; |
| 387 | return; |
| 388 | } |
| 389 | |
| 390 | this->delegate_.CreateInvalidator(std::string(), |
| 391 | this->fake_tracker_.AsWeakPtr()); |
| 392 | Invalidator* invalidator = this->delegate_.GetInvalidator(); |
| 393 | |
| 394 | invalidator->SetStateDeprecated("fake_state"); |
| 395 | this->delegate_.WaitForInvalidator(); |
[email protected] | 8cdb689 | 2012-10-03 05:54:40 | [diff] [blame] | 396 | EXPECT_EQ("fake_state", this->fake_tracker_.GetBootstrapData()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 397 | |
| 398 | // Should do nothing. |
| 399 | invalidator->SetStateDeprecated("spurious_fake_state"); |
| 400 | this->delegate_.WaitForInvalidator(); |
[email protected] | 8cdb689 | 2012-10-03 05:54:40 | [diff] [blame] | 401 | EXPECT_EQ("fake_state", this->fake_tracker_.GetBootstrapData()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 402 | |
| 403 | // Pretend that Chrome has shut down. |
| 404 | this->delegate_.DestroyInvalidator(); |
| 405 | this->delegate_.CreateInvalidator("fake_state", |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 406 | this->fake_tracker_.AsWeakPtr()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 407 | invalidator = this->delegate_.GetInvalidator(); |
| 408 | |
| 409 | // Should do nothing. |
| 410 | invalidator->SetStateDeprecated("more_spurious_fake_state"); |
| 411 | this->delegate_.WaitForInvalidator(); |
[email protected] | 8cdb689 | 2012-10-03 05:54:40 | [diff] [blame] | 412 | EXPECT_EQ("fake_state", this->fake_tracker_.GetBootstrapData()); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 413 | } |
| 414 | |
| 415 | REGISTER_TYPED_TEST_CASE_P(InvalidatorTest, |
| 416 | Basic, MultipleHandlers, EmptySetUnregisters, |
[email protected] | 08a6f999 | 2012-09-07 19:19:16 | [diff] [blame] | 417 | GetInvalidatorStateAlwaysCurrent, MigrateState); |
[email protected] | 33596da | 2012-08-31 23:39:25 | [diff] [blame] | 418 | |
| 419 | } // namespace syncer |
| 420 | |
| 421 | #endif // SYNC_NOTIFIER_INVALIDATOR_TEST_TEMPLATE_H_ |