Home | History | Annotate | Download | only in notifier
      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 "base/basictypes.h"
      6 #include "base/compiler_specific.h"
      7 #include "base/memory/scoped_ptr.h"
      8 #include "google/cacheinvalidation/types.pb.h"
      9 #include "sync/notifier/fake_invalidation_handler.h"
     10 #include "sync/notifier/invalidator_registrar.h"
     11 #include "sync/notifier/invalidator_test_template.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 namespace syncer {
     15 
     16 namespace {
     17 
     18 // We test InvalidatorRegistrar by wrapping it in an Invalidator and
     19 // running the usual Invalidator tests.
     20 
     21 // Thin Invalidator wrapper around InvalidatorRegistrar.
     22 class RegistrarInvalidator : public Invalidator {
     23  public:
     24   RegistrarInvalidator() {}
     25   virtual ~RegistrarInvalidator() {}
     26 
     27   InvalidatorRegistrar* GetRegistrar() {
     28     return &registrar_;
     29   }
     30 
     31   // Invalidator implementation.
     32   virtual void RegisterHandler(InvalidationHandler* handler) OVERRIDE {
     33     registrar_.RegisterHandler(handler);
     34   }
     35 
     36   virtual void UpdateRegisteredIds(InvalidationHandler* handler,
     37                                    const ObjectIdSet& ids) OVERRIDE {
     38     registrar_.UpdateRegisteredIds(handler, ids);
     39   }
     40 
     41   virtual void UnregisterHandler(InvalidationHandler* handler) OVERRIDE {
     42     registrar_.UnregisterHandler(handler);
     43   }
     44 
     45   virtual InvalidatorState GetInvalidatorState() const OVERRIDE {
     46     return registrar_.GetInvalidatorState();
     47   }
     48 
     49   virtual void UpdateCredentials(
     50       const std::string& email, const std::string& token) OVERRIDE {
     51     // Do nothing.
     52   }
     53 
     54  private:
     55   InvalidatorRegistrar registrar_;
     56 
     57   DISALLOW_COPY_AND_ASSIGN(RegistrarInvalidator);
     58 };
     59 
     60 class RegistrarInvalidatorTestDelegate {
     61  public:
     62   RegistrarInvalidatorTestDelegate() {}
     63 
     64   ~RegistrarInvalidatorTestDelegate() {
     65     DestroyInvalidator();
     66   }
     67 
     68   void CreateInvalidator(
     69       const std::string& invalidator_client_id,
     70       const std::string& initial_state,
     71       const base::WeakPtr<InvalidationStateTracker>&
     72           invalidation_state_tracker) {
     73     DCHECK(!invalidator_.get());
     74     invalidator_.reset(new RegistrarInvalidator());
     75   }
     76 
     77   RegistrarInvalidator* GetInvalidator() {
     78     return invalidator_.get();
     79   }
     80 
     81   void DestroyInvalidator() {
     82     invalidator_.reset();
     83   }
     84 
     85   void WaitForInvalidator() {
     86     // Do nothing.
     87   }
     88 
     89   void TriggerOnInvalidatorStateChange(InvalidatorState state) {
     90     invalidator_->GetRegistrar()->UpdateInvalidatorState(state);
     91   }
     92 
     93   void TriggerOnIncomingInvalidation(
     94       const ObjectIdInvalidationMap& invalidation_map) {
     95     invalidator_->GetRegistrar()->DispatchInvalidationsToHandlers(
     96         invalidation_map);
     97   }
     98 
     99  private:
    100   scoped_ptr<RegistrarInvalidator> invalidator_;
    101 };
    102 
    103 INSTANTIATE_TYPED_TEST_CASE_P(
    104     RegistrarInvalidatorTest, InvalidatorTest,
    105     RegistrarInvalidatorTestDelegate);
    106 
    107 class InvalidatorRegistrarTest : public testing::Test {};
    108 
    109 // Technically the tests below can be part of InvalidatorTest, but we
    110 // want to keep the number of death tests down.
    111 
    112 // When we expect a death via CHECK(), we can't match against the
    113 // CHECK() message since they are removed in official builds.
    114 
    115 #if GTEST_HAS_DEATH_TEST
    116 // Having registered handlers on destruction should cause a CHECK.
    117 TEST_F(InvalidatorRegistrarTest, RegisteredHandlerOnDestruction) {
    118   scoped_ptr<InvalidatorRegistrar> registrar(new InvalidatorRegistrar());
    119   FakeInvalidationHandler handler;
    120 
    121   registrar->RegisterHandler(&handler);
    122 
    123   EXPECT_DEATH({ registrar.reset(); }, "");
    124 
    125   ASSERT_TRUE(registrar.get());
    126   registrar->UnregisterHandler(&handler);
    127 }
    128 
    129 // Multiple registrations by different handlers on the same object ID should
    130 // cause a CHECK.
    131 TEST_F(InvalidatorRegistrarTest, MultipleRegistration) {
    132   const invalidation::ObjectId id1(ipc::invalidation::ObjectSource::TEST, "a");
    133   const invalidation::ObjectId id2(ipc::invalidation::ObjectSource::TEST, "a");
    134 
    135   InvalidatorRegistrar registrar;
    136 
    137   FakeInvalidationHandler handler1;
    138   registrar.RegisterHandler(&handler1);
    139 
    140   FakeInvalidationHandler handler2;
    141   registrar.RegisterHandler(&handler2);
    142 
    143   ObjectIdSet ids;
    144   ids.insert(id1);
    145   ids.insert(id2);
    146   registrar.UpdateRegisteredIds(&handler1, ids);
    147 
    148   registrar.DetachFromThreadForTest();
    149   EXPECT_DEATH({ registrar.UpdateRegisteredIds(&handler2, ids); }, "");
    150 
    151   registrar.UnregisterHandler(&handler2);
    152   registrar.UnregisterHandler(&handler1);
    153 }
    154 #endif  // GTEST_HAS_DEATH_TEST
    155 
    156 }  // namespace
    157 
    158 }  // namespace syncer
    159