// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/invalidation/invalidation_logger.h" #include "components/invalidation/invalidation_logger_observer.h" #include "testing/gtest/include/gtest/gtest.h" namespace invalidation { class InvalidationLoggerObserverTest : public InvalidationLoggerObserver { public: InvalidationLoggerObserverTest() { ResetStates(); } void ResetStates() { registration_change_received = false; state_received = false; update_id_received = false; debug_message_received = false; invalidation_received = false; detailed_status_received = false; update_id_replicated = std::map(); registered_handlers = std::multiset(); } void OnRegistrationChange( const std::multiset& handlers) override { registered_handlers = handlers; registration_change_received = true; } void OnStateChange(const syncer::InvalidatorState& new_state, const base::Time& last_change_timestamp) override { state_received = true; } void OnUpdateIds(const std::string& handler, const syncer::ObjectIdCountMap& details) override { update_id_received = true; update_id_replicated[handler] = details; } void OnDebugMessage(const base::DictionaryValue& details) override { debug_message_received = true; } void OnInvalidation( const syncer::ObjectIdInvalidationMap& new_invalidations) override { invalidation_received = true; } void OnDetailedStatus(const base::DictionaryValue& details) override { detailed_status_received = true; } bool registration_change_received; bool state_received; bool update_id_received; bool debug_message_received; bool invalidation_received; bool detailed_status_received; std::map update_id_replicated; std::multiset registered_handlers; }; // Test that the callbacks are actually being called when observers are // registered and don't produce any other callback in the meantime. TEST(InvalidationLoggerTest, TestCallbacks) { InvalidationLogger log; InvalidationLoggerObserverTest observer_test; log.RegisterObserver(&observer_test); log.OnStateChange(syncer::INVALIDATIONS_ENABLED); EXPECT_TRUE(observer_test.state_received); EXPECT_FALSE(observer_test.update_id_received); EXPECT_FALSE(observer_test.registration_change_received); EXPECT_FALSE(observer_test.invalidation_received); EXPECT_FALSE(observer_test.debug_message_received); EXPECT_FALSE(observer_test.detailed_status_received); observer_test.ResetStates(); log.OnInvalidation(syncer::ObjectIdInvalidationMap()); EXPECT_TRUE(observer_test.invalidation_received); EXPECT_FALSE(observer_test.state_received); EXPECT_FALSE(observer_test.update_id_received); EXPECT_FALSE(observer_test.registration_change_received); EXPECT_FALSE(observer_test.debug_message_received); EXPECT_FALSE(observer_test.detailed_status_received); log.UnregisterObserver(&observer_test); } // Test that after registering an observer and then unregistering it // no callbacks regarding that observer are called. // (i.e. the observer is cleanly removed) TEST(InvalidationLoggerTest, TestReleaseOfObserver) { InvalidationLogger log; InvalidationLoggerObserverTest observer_test; log.RegisterObserver(&observer_test); log.UnregisterObserver(&observer_test); log.OnInvalidation(syncer::ObjectIdInvalidationMap()); log.OnStateChange(syncer::INVALIDATIONS_ENABLED); log.OnRegistration(std::string()); log.OnUnregistration(std::string()); log.OnDebugMessage(base::DictionaryValue()); log.OnUpdateIds(std::map()); EXPECT_FALSE(observer_test.registration_change_received); EXPECT_FALSE(observer_test.update_id_received); EXPECT_FALSE(observer_test.invalidation_received); EXPECT_FALSE(observer_test.state_received); EXPECT_FALSE(observer_test.debug_message_received); EXPECT_FALSE(observer_test.detailed_status_received); } // Test the EmitContet in InvalidationLogger is actually // sending state and updateIds notifications. TEST(InvalidationLoggerTest, TestEmitContent) { InvalidationLogger log; InvalidationLoggerObserverTest observer_test; log.RegisterObserver(&observer_test); EXPECT_FALSE(observer_test.state_received); EXPECT_FALSE(observer_test.update_id_received); log.EmitContent(); // Expect state and registered handlers only because no Ids were registered. EXPECT_TRUE(observer_test.state_received); EXPECT_TRUE(observer_test.registration_change_received); EXPECT_FALSE(observer_test.update_id_received); EXPECT_FALSE(observer_test.invalidation_received); EXPECT_FALSE(observer_test.debug_message_received); EXPECT_FALSE(observer_test.detailed_status_received); observer_test.ResetStates(); std::map test_map; test_map["Test"] = syncer::ObjectIdSet(); log.OnUpdateIds(test_map); EXPECT_TRUE(observer_test.update_id_received); observer_test.ResetStates(); log.EmitContent(); // Expect now state, ids and registered handlers change. EXPECT_TRUE(observer_test.state_received); EXPECT_TRUE(observer_test.update_id_received); EXPECT_TRUE(observer_test.registration_change_received); EXPECT_FALSE(observer_test.invalidation_received); EXPECT_FALSE(observer_test.debug_message_received); EXPECT_FALSE(observer_test.detailed_status_received); log.UnregisterObserver(&observer_test); } // Test that the updateId notification actually sends the same ObjectId that // was sent to the Observer. // The ObserverTest rebuilds the map that was sent in pieces by the logger. TEST(InvalidationLoggerTest, TestUpdateIdsMap) { InvalidationLogger log; InvalidationLoggerObserverTest observer_test; std::map send_test_map; std::map expected_received_map; log.RegisterObserver(&observer_test); syncer::ObjectIdSet sync_set_A; syncer::ObjectIdCountMap counted_sync_set_A; ObjectId o1(1000, "DataType1"); sync_set_A.insert(o1); counted_sync_set_A[o1] = 0; ObjectId o2(1000, "DataType2"); sync_set_A.insert(o2); counted_sync_set_A[o2] = 0; syncer::ObjectIdSet sync_set_B; syncer::ObjectIdCountMap counted_sync_set_B; ObjectId o3(1020, "DataTypeA"); sync_set_B.insert(o3); counted_sync_set_B[o3] = 0; send_test_map["TestA"] = sync_set_A; send_test_map["TestB"] = sync_set_B; expected_received_map["TestA"] = counted_sync_set_A; expected_received_map["TestB"] = counted_sync_set_B; // Send the objects ids registered for the two different handler name. log.OnUpdateIds(send_test_map); EXPECT_EQ(expected_received_map, observer_test.update_id_replicated); syncer::ObjectIdSet sync_set_B2; syncer::ObjectIdCountMap counted_sync_set_B2; ObjectId o4(1020, "DataTypeF"); sync_set_B2.insert(o4); counted_sync_set_B2[o4] = 0; ObjectId o5(1020, "DataTypeG"); sync_set_B2.insert(o5); counted_sync_set_B2[o5] = 0; send_test_map["TestB"] = sync_set_B2; expected_received_map["TestB"] = counted_sync_set_B2; // Test now that if we replace the registered datatypes for TestB, the // original don't show up again. log.OnUpdateIds(send_test_map); EXPECT_EQ(expected_received_map, observer_test.update_id_replicated); // The emit content should return the same map too. observer_test.ResetStates(); log.EmitContent(); EXPECT_EQ(expected_received_map, observer_test.update_id_replicated); log.UnregisterObserver(&observer_test); } // Test that the invalidation notification changes the total count // of invalidations received for that datatype. TEST(InvalidationLoggerTest, TestInvalidtionsTotalCount) { InvalidationLogger log; InvalidationLoggerObserverTest observer_test; log.RegisterObserver(&observer_test); std::map send_test_map; std::map expected_received_map; syncer::ObjectIdSet sync_set; syncer::ObjectIdCountMap counted_sync_set; ObjectId o1(1020, "DataTypeA"); sync_set.insert(o1); counted_sync_set[o1] = 1; // Generate invalidation for datatype A only. syncer::ObjectIdInvalidationMap fake_invalidations = syncer::ObjectIdInvalidationMap::InvalidateAll(sync_set); ObjectId o2(1040, "DataTypeB"); sync_set.insert(o2); counted_sync_set[o2] = 0; // Registed the two objectIds and send an invalidation only for the // Datatype A. send_test_map["Test"] = sync_set; log.OnUpdateIds(send_test_map); log.OnInvalidation(fake_invalidations); expected_received_map["Test"] = counted_sync_set; // Reset the state of the observer to receive the ObjectIds with the // count of invalidations received (1 and 0). observer_test.ResetStates(); log.EmitContent(); EXPECT_EQ(expected_received_map, observer_test.update_id_replicated); log.UnregisterObserver(&observer_test); } // Test that registered handlers are being sent to the observers. TEST(InvalidationLoggerTest, TestRegisteredHandlers) { InvalidationLogger log; InvalidationLoggerObserverTest observer_test; log.RegisterObserver(&observer_test); log.OnRegistration(std::string("FakeHandler1")); std::multiset test_multiset; test_multiset.insert("FakeHandler1"); EXPECT_TRUE(observer_test.registration_change_received); EXPECT_EQ(observer_test.registered_handlers, test_multiset); observer_test.ResetStates(); log.OnRegistration(std::string("FakeHandler2")); test_multiset.insert("FakeHandler2"); EXPECT_TRUE(observer_test.registration_change_received); EXPECT_EQ(observer_test.registered_handlers, test_multiset); observer_test.ResetStates(); log.OnUnregistration(std::string("FakeHandler2")); test_multiset.erase("FakeHandler2"); EXPECT_TRUE(observer_test.registration_change_received); EXPECT_EQ(observer_test.registered_handlers, test_multiset); log.UnregisterObserver(&observer_test); } } // namespace invalidation