Home | History | Annotate | Download | only in cloud
      1 // Copyright 2013 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 <string>
      6 
      7 #include "base/basictypes.h"
      8 #include "base/bind.h"
      9 #include "base/memory/ref_counted.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "base/message_loop/message_loop.h"
     12 #include "base/metrics/histogram.h"
     13 #include "base/metrics/histogram_samples.h"
     14 #include "base/metrics/sample_map.h"
     15 #include "base/metrics/statistics_recorder.h"
     16 #include "base/run_loop.h"
     17 #include "base/test/simple_test_clock.h"
     18 #include "base/test/test_simple_task_runner.h"
     19 #include "base/time/time.h"
     20 #include "base/values.h"
     21 #include "chrome/browser/invalidation/fake_invalidation_service.h"
     22 #include "chrome/browser/policy/cloud/cloud_policy_invalidator.h"
     23 #include "chrome/browser/policy/cloud/user_cloud_policy_invalidator.h"
     24 #include "components/invalidation/invalidation_util.h"
     25 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
     26 #include "components/policy/core/common/cloud/cloud_policy_core.h"
     27 #include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
     28 #include "components/policy/core/common/cloud/enterprise_metrics.h"
     29 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
     30 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
     31 #include "components/policy/core/common/policy_types.h"
     32 #include "policy/policy_constants.h"
     33 #include "testing/gmock/include/gmock/gmock.h"
     34 #include "testing/gtest/include/gtest/gtest.h"
     35 
     36 namespace em = enterprise_management;
     37 
     38 namespace policy {
     39 
     40 class CloudPolicyInvalidatorTest : public testing::Test {
     41  protected:
     42   // Policy objects which can be used in tests.
     43   enum PolicyObject {
     44     POLICY_OBJECT_NONE,
     45     POLICY_OBJECT_A,
     46     POLICY_OBJECT_B
     47   };
     48 
     49   CloudPolicyInvalidatorTest();
     50 
     51   virtual void TearDown() OVERRIDE;
     52 
     53   // Starts the invalidator which will be tested.
     54   // |initialize| determines if the invalidator should be initialized.
     55   // |start_refresh_scheduler| determines if the refresh scheduler should start.
     56   // |highest_handled_invalidation_version| is the highest invalidation version
     57   // that was handled already before this invalidator was created.
     58   void StartInvalidator(bool initialize,
     59                         bool start_refresh_scheduler,
     60                         int64 highest_handled_invalidation_version);
     61   void StartInvalidator() {
     62     StartInvalidator(true, /* initialize */
     63                      true, /* start_refresh_scheduler */
     64                      0     /* highest_handled_invalidation_version */);
     65   }
     66 
     67   // Calls Initialize on the invalidator.
     68   void InitializeInvalidator();
     69 
     70   // Calls Shutdown on the invalidator. Test must call DestroyInvalidator
     71   // afterwards to prevent Shutdown from being called twice.
     72   void ShutdownInvalidator();
     73 
     74   // Destroys the invalidator.
     75   void DestroyInvalidator();
     76 
     77   // Connects the cloud policy core.
     78   void ConnectCore();
     79 
     80   // Starts the refresh scheduler.
     81   void StartRefreshScheduler();
     82 
     83   // Disconnects the cloud policy core.
     84   void DisconnectCore();
     85 
     86   // Simulates storing a new policy to the policy store.
     87   // |object| determines which policy object the store will report the
     88   // invalidator should register for. May be POLICY_OBJECT_NONE for no object.
     89   // |invalidation_version| determines what invalidation the store will report.
     90   // |policy_changed| determines whether a policy value different from the
     91   // current value will be stored.
     92   // |time| determines the timestamp the store will report.
     93   void StorePolicy(
     94       PolicyObject object,
     95       int64 invalidation_version,
     96       bool policy_changed,
     97       const base::Time& time);
     98   void StorePolicy(
     99       PolicyObject object,
    100       int64 invalidation_version,
    101       bool policy_changed) {
    102     StorePolicy(object,
    103                 invalidation_version,
    104                 policy_changed,
    105                 Now() - base::TimeDelta::FromMinutes(5));
    106   }
    107   void StorePolicy(PolicyObject object, int64 invalidation_version) {
    108     StorePolicy(object, invalidation_version, false);
    109   }
    110   void StorePolicy(PolicyObject object) {
    111     StorePolicy(object, 0);
    112   }
    113 
    114   // Disables the invalidation service. It is enabled by default.
    115   void DisableInvalidationService();
    116 
    117   // Enables the invalidation service. It is enabled by default.
    118   void EnableInvalidationService();
    119 
    120   // Causes the invalidation service to fire an invalidation.
    121   syncer::Invalidation FireInvalidation(
    122       PolicyObject object,
    123       int64 version,
    124       const std::string& payload);
    125 
    126   // Causes the invalidation service to fire an invalidation with unknown
    127   // version.
    128   syncer::Invalidation FireUnknownVersionInvalidation(PolicyObject object);
    129 
    130   // Checks the expected value of the currently set invalidation info.
    131   bool CheckInvalidationInfo(int64 version, const std::string& payload);
    132 
    133   // Checks that the policy was not refreshed due to an invalidation.
    134   bool CheckPolicyNotRefreshed();
    135 
    136   // Checks that the policy was refreshed due to an invalidation within an
    137   // appropriate timeframe depending on whether the invalidation had unknown
    138   // version.
    139   bool CheckPolicyRefreshed();
    140   bool CheckPolicyRefreshedWithUnknownVersion();
    141 
    142   bool IsUnsent(const syncer::Invalidation& invalidation);
    143 
    144   // Returns the invalidations enabled state set by the invalidator on the
    145   // refresh scheduler.
    146   bool InvalidationsEnabled();
    147 
    148   // Determines if the invalidation with the given ack handle has been
    149   // acknowledged.
    150   bool IsInvalidationAcknowledged(const syncer::Invalidation& invalidation);
    151 
    152   // Determines if the invalidator has registered for an object with the
    153   // invalidation service.
    154   bool IsInvalidatorRegistered();
    155 
    156   // Returns the highest invalidation version that was handled already according
    157   // to the |invalidator_|.
    158   int64 GetHighestHandledInvalidationVersion() const;
    159 
    160   // Advance the test clock.
    161   void AdvanceClock(base::TimeDelta delta);
    162 
    163   // Get the current time on the test clock.
    164   base::Time Now();
    165 
    166   // Translate a version number into an appropriate invalidation version (which
    167   // is based on the current time).
    168   int64 V(int version);
    169 
    170   // Get an invalidation version for the given time.
    171   int64 GetVersion(base::Time time);
    172 
    173   // Get the policy type that the |invalidator_| is responsible for.
    174   virtual em::DeviceRegisterRequest::Type GetPolicyType() const;
    175 
    176  private:
    177   // Checks that the policy was refreshed due to an invalidation with the given
    178   // base delay.
    179   bool CheckPolicyRefreshed(base::TimeDelta delay);
    180 
    181   // Checks that the policy was refreshed the given number of times.
    182   bool CheckPolicyRefreshCount(int count);
    183 
    184   // Returns the object id of the given policy object.
    185   const invalidation::ObjectId& GetPolicyObjectId(PolicyObject object) const;
    186 
    187   base::MessageLoop loop_;
    188 
    189   // Objects the invalidator depends on.
    190   invalidation::FakeInvalidationService invalidation_service_;
    191   MockCloudPolicyStore store_;
    192   CloudPolicyCore core_;
    193   MockCloudPolicyClient* client_;
    194   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
    195   base::SimpleTestClock* clock_;
    196 
    197   // The invalidator which will be tested.
    198   scoped_ptr<CloudPolicyInvalidator> invalidator_;
    199 
    200   // Object ids for the test policy objects.
    201   invalidation::ObjectId object_id_a_;
    202   invalidation::ObjectId object_id_b_;
    203 
    204   // Fake policy values which are alternated to cause the store to report a
    205   // changed policy.
    206   const char* policy_value_a_;
    207   const char* policy_value_b_;
    208 
    209   // The currently used policy value.
    210   const char* policy_value_cur_;
    211 };
    212 
    213 CloudPolicyInvalidatorTest::CloudPolicyInvalidatorTest()
    214     : core_(PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType,
    215                                std::string()),
    216             &store_,
    217             loop_.message_loop_proxy()),
    218       client_(NULL),
    219       task_runner_(new base::TestSimpleTaskRunner()),
    220       clock_(new base::SimpleTestClock()),
    221       object_id_a_(135, "asdf"),
    222       object_id_b_(246, "zxcv"),
    223       policy_value_a_("asdf"),
    224       policy_value_b_("zxcv"),
    225       policy_value_cur_(policy_value_a_) {
    226   clock_->SetNow(
    227       base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(987654321));
    228 }
    229 
    230 void CloudPolicyInvalidatorTest::TearDown() {
    231   if (invalidator_)
    232     invalidator_->Shutdown();
    233   core_.Disconnect();
    234 }
    235 
    236 void CloudPolicyInvalidatorTest::StartInvalidator(
    237     bool initialize,
    238     bool start_refresh_scheduler,
    239     int64 highest_handled_invalidation_version) {
    240   invalidator_.reset(new CloudPolicyInvalidator(
    241       GetPolicyType(),
    242       &core_,
    243       task_runner_,
    244       scoped_ptr<base::Clock>(clock_),
    245       highest_handled_invalidation_version));
    246   if (start_refresh_scheduler) {
    247     ConnectCore();
    248     StartRefreshScheduler();
    249   }
    250   if (initialize)
    251     InitializeInvalidator();
    252 }
    253 
    254 void CloudPolicyInvalidatorTest::InitializeInvalidator() {
    255   invalidator_->Initialize(&invalidation_service_);
    256 }
    257 
    258 void CloudPolicyInvalidatorTest::ShutdownInvalidator() {
    259   invalidator_->Shutdown();
    260 }
    261 
    262 void CloudPolicyInvalidatorTest::DestroyInvalidator() {
    263   invalidator_.reset();
    264 }
    265 
    266 void CloudPolicyInvalidatorTest::ConnectCore() {
    267   client_ = new MockCloudPolicyClient();
    268   client_->SetDMToken("dm");
    269   core_.Connect(scoped_ptr<CloudPolicyClient>(client_));
    270 }
    271 
    272 void CloudPolicyInvalidatorTest::StartRefreshScheduler() {
    273   core_.StartRefreshScheduler();
    274 }
    275 
    276 void CloudPolicyInvalidatorTest::DisconnectCore() {
    277   client_ = NULL;
    278   core_.Disconnect();
    279 }
    280 
    281 void CloudPolicyInvalidatorTest::StorePolicy(
    282     PolicyObject object,
    283     int64 invalidation_version,
    284     bool policy_changed,
    285     const base::Time& time) {
    286   em::PolicyData* data = new em::PolicyData();
    287   if (object != POLICY_OBJECT_NONE) {
    288     data->set_invalidation_source(GetPolicyObjectId(object).source());
    289     data->set_invalidation_name(GetPolicyObjectId(object).name());
    290   }
    291   data->set_timestamp((time - base::Time::UnixEpoch()).InMilliseconds());
    292   // Swap the policy value if a policy change is desired.
    293   if (policy_changed)
    294     policy_value_cur_ = policy_value_cur_ == policy_value_a_ ?
    295         policy_value_b_ : policy_value_a_;
    296   data->set_policy_value(policy_value_cur_);
    297   store_.invalidation_version_ = invalidation_version;
    298   store_.policy_.reset(data);
    299   base::DictionaryValue policies;
    300   policies.SetInteger(
    301       key::kMaxInvalidationFetchDelay,
    302       CloudPolicyInvalidator::kMaxFetchDelayMin);
    303   store_.policy_map_.LoadFrom(
    304       &policies,
    305       POLICY_LEVEL_MANDATORY,
    306       POLICY_SCOPE_MACHINE);
    307   store_.NotifyStoreLoaded();
    308 }
    309 
    310 void CloudPolicyInvalidatorTest::DisableInvalidationService() {
    311   invalidation_service_.SetInvalidatorState(
    312       syncer::TRANSIENT_INVALIDATION_ERROR);
    313 }
    314 
    315 void CloudPolicyInvalidatorTest::EnableInvalidationService() {
    316   invalidation_service_.SetInvalidatorState(syncer::INVALIDATIONS_ENABLED);
    317 }
    318 
    319 syncer::Invalidation CloudPolicyInvalidatorTest::FireInvalidation(
    320     PolicyObject object,
    321     int64 version,
    322     const std::string& payload) {
    323   syncer::Invalidation invalidation = syncer::Invalidation::Init(
    324       GetPolicyObjectId(object),
    325       version,
    326       payload);
    327   invalidation_service_.EmitInvalidationForTest(invalidation);
    328   return invalidation;
    329 }
    330 
    331 syncer::Invalidation CloudPolicyInvalidatorTest::FireUnknownVersionInvalidation(
    332     PolicyObject object) {
    333   syncer::Invalidation invalidation = syncer::Invalidation::InitUnknownVersion(
    334       GetPolicyObjectId(object));
    335   invalidation_service_.EmitInvalidationForTest(invalidation);
    336   return invalidation;
    337 }
    338 
    339 bool CloudPolicyInvalidatorTest::CheckInvalidationInfo(
    340     int64 version,
    341     const std::string& payload) {
    342   MockCloudPolicyClient* client =
    343       static_cast<MockCloudPolicyClient*>(core_.client());
    344   return version == client->invalidation_version_ &&
    345       payload == client->invalidation_payload_;
    346 }
    347 
    348 bool CloudPolicyInvalidatorTest::CheckPolicyNotRefreshed() {
    349   return CheckPolicyRefreshCount(0);
    350 }
    351 
    352 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshed() {
    353   return CheckPolicyRefreshed(base::TimeDelta());
    354 }
    355 
    356 bool CloudPolicyInvalidatorTest::IsUnsent(
    357     const syncer::Invalidation& invalidation) {
    358   return invalidation_service_.GetMockAckHandler()->IsUnsent(invalidation);
    359 }
    360 
    361 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshedWithUnknownVersion() {
    362   return CheckPolicyRefreshed(base::TimeDelta::FromMinutes(
    363         CloudPolicyInvalidator::kMissingPayloadDelay));
    364 }
    365 
    366 bool CloudPolicyInvalidatorTest::InvalidationsEnabled() {
    367   return core_.refresh_scheduler()->invalidations_available();
    368 }
    369 
    370 bool CloudPolicyInvalidatorTest::IsInvalidationAcknowledged(
    371     const syncer::Invalidation& invalidation) {
    372   // The acknowledgement task is run through a WeakHandle that posts back to our
    373   // own thread.  We need to run any posted tasks before we can check
    374   // acknowledgement status.
    375   loop_.RunUntilIdle();
    376 
    377   EXPECT_FALSE(IsUnsent(invalidation));
    378   return !invalidation_service_.GetMockAckHandler()->IsUnacked(invalidation);
    379 }
    380 
    381 bool CloudPolicyInvalidatorTest::IsInvalidatorRegistered() {
    382   return !invalidation_service_.invalidator_registrar()
    383       .GetRegisteredIds(invalidator_.get()).empty();
    384 }
    385 
    386 int64 CloudPolicyInvalidatorTest::GetHighestHandledInvalidationVersion() const {
    387   return invalidator_->highest_handled_invalidation_version();
    388 }
    389 
    390 void CloudPolicyInvalidatorTest::AdvanceClock(base::TimeDelta delta) {
    391   clock_->Advance(delta);
    392 }
    393 
    394 base::Time CloudPolicyInvalidatorTest::Now() {
    395   return clock_->Now();
    396 }
    397 
    398 int64 CloudPolicyInvalidatorTest::V(int version) {
    399   return GetVersion(Now()) + version;
    400 }
    401 
    402 int64 CloudPolicyInvalidatorTest::GetVersion(base::Time time) {
    403   return (time - base::Time::UnixEpoch()).InMicroseconds();
    404 }
    405 
    406 em::DeviceRegisterRequest::Type
    407 CloudPolicyInvalidatorTest::GetPolicyType() const {
    408   return UserCloudPolicyInvalidator::GetPolicyType();
    409 }
    410 
    411 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshed(base::TimeDelta delay) {
    412   base::TimeDelta max_delay = delay + base::TimeDelta::FromMilliseconds(
    413       CloudPolicyInvalidator::kMaxFetchDelayMin);
    414 
    415   if (task_runner_->GetPendingTasks().empty())
    416     return false;
    417   base::TimeDelta actual_delay = task_runner_->GetPendingTasks().back().delay;
    418   EXPECT_GE(actual_delay, delay);
    419   EXPECT_LE(actual_delay, max_delay);
    420 
    421   return CheckPolicyRefreshCount(1);
    422 }
    423 
    424 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshCount(int count) {
    425   if (!client_) {
    426     task_runner_->RunUntilIdle();
    427     return count == 0;
    428   }
    429 
    430   // Clear any non-invalidation refreshes which may be pending.
    431   EXPECT_CALL(*client_, FetchPolicy()).Times(testing::AnyNumber());
    432   base::RunLoop().RunUntilIdle();
    433   testing::Mock::VerifyAndClearExpectations(client_);
    434 
    435   // Run the invalidator tasks then check for invalidation refreshes.
    436   EXPECT_CALL(*client_, FetchPolicy()).Times(count);
    437   task_runner_->RunUntilIdle();
    438   base::RunLoop().RunUntilIdle();
    439   return testing::Mock::VerifyAndClearExpectations(client_);
    440 }
    441 
    442 const invalidation::ObjectId& CloudPolicyInvalidatorTest::GetPolicyObjectId(
    443     PolicyObject object) const {
    444   EXPECT_TRUE(object == POLICY_OBJECT_A || object == POLICY_OBJECT_B);
    445   return object == POLICY_OBJECT_A ? object_id_a_ : object_id_b_;
    446 }
    447 
    448 TEST_F(CloudPolicyInvalidatorTest, Uninitialized) {
    449   // No invalidations should be processed if the invalidator is not initialized.
    450   StartInvalidator(false, /* initialize */
    451                    true,  /* start_refresh_scheduler */
    452                    0      /* highest_handled_invalidation_version*/);
    453   StorePolicy(POLICY_OBJECT_A);
    454   EXPECT_FALSE(IsInvalidatorRegistered());
    455   EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_A)));
    456   EXPECT_TRUE(CheckPolicyNotRefreshed());
    457   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    458 }
    459 
    460 TEST_F(CloudPolicyInvalidatorTest, RefreshSchedulerNotStarted) {
    461   // No invalidations should be processed if the refresh scheduler is not
    462   // started.
    463   StartInvalidator(true,  /* initialize */
    464                    false, /* start_refresh_scheduler */
    465                    0      /* highest_handled_invalidation_version*/);
    466   StorePolicy(POLICY_OBJECT_A);
    467   EXPECT_FALSE(IsInvalidatorRegistered());
    468   EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_A)));
    469   EXPECT_TRUE(CheckPolicyNotRefreshed());
    470   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    471 }
    472 
    473 TEST_F(CloudPolicyInvalidatorTest, DisconnectCoreThenInitialize) {
    474   // No invalidations should be processed if the core is disconnected before
    475   // initialization.
    476   StartInvalidator(false, /* initialize */
    477                    true,  /* start_refresh_scheduler */
    478                    0      /* highest_handled_invalidation_version*/);
    479   DisconnectCore();
    480   InitializeInvalidator();
    481   StorePolicy(POLICY_OBJECT_A);
    482   EXPECT_FALSE(IsInvalidatorRegistered());
    483   EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_A)));
    484   EXPECT_TRUE(CheckPolicyNotRefreshed());
    485   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    486 }
    487 
    488 TEST_F(CloudPolicyInvalidatorTest, InitializeThenStartRefreshScheduler) {
    489   // Make sure registration occurs and invalidations are processed when
    490   // Initialize is called before starting the refresh scheduler.
    491   // Note that the reverse case (start refresh scheduler then initialize) is
    492   // the default behavior for the test fixture, so will be tested in most other
    493   // tests.
    494   StartInvalidator(true,  /* initialize */
    495                    false, /* start_refresh_scheduler */
    496                    0      /* highest_handled_invalidation_version*/);
    497   ConnectCore();
    498   StartRefreshScheduler();
    499   StorePolicy(POLICY_OBJECT_A);
    500   EXPECT_TRUE(IsInvalidatorRegistered());
    501   FireUnknownVersionInvalidation(POLICY_OBJECT_A);
    502   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
    503   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    504 }
    505 
    506 TEST_F(CloudPolicyInvalidatorTest, RegisterOnStoreLoaded) {
    507   // No registration when store is not loaded.
    508   StartInvalidator();
    509   EXPECT_FALSE(IsInvalidatorRegistered());
    510   EXPECT_FALSE(InvalidationsEnabled());
    511   EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_A)));
    512   EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_B)));
    513   EXPECT_TRUE(CheckPolicyNotRefreshed());
    514 
    515   // No registration when store is loaded with no invalidation object id.
    516   StorePolicy(POLICY_OBJECT_NONE);
    517   EXPECT_FALSE(IsInvalidatorRegistered());
    518   EXPECT_FALSE(InvalidationsEnabled());
    519   EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_A)));
    520   EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_B)));
    521   EXPECT_TRUE(CheckPolicyNotRefreshed());
    522 
    523   // Check registration when store is loaded for object A.
    524   StorePolicy(POLICY_OBJECT_A);
    525   EXPECT_TRUE(IsInvalidatorRegistered());
    526   EXPECT_TRUE(InvalidationsEnabled());
    527   FireUnknownVersionInvalidation(POLICY_OBJECT_A);
    528   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
    529   EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_B)));
    530   EXPECT_TRUE(CheckPolicyNotRefreshed());
    531   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    532 }
    533 
    534 TEST_F(CloudPolicyInvalidatorTest, ChangeRegistration) {
    535   // Register for object A.
    536   StartInvalidator();
    537   StorePolicy(POLICY_OBJECT_A);
    538   EXPECT_TRUE(IsInvalidatorRegistered());
    539   EXPECT_TRUE(InvalidationsEnabled());
    540   FireUnknownVersionInvalidation(POLICY_OBJECT_A);
    541   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
    542   EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_B)));
    543   EXPECT_TRUE(CheckPolicyNotRefreshed());
    544   syncer::Invalidation inv = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
    545 
    546   // Check re-registration for object B. Make sure the pending invalidation for
    547   // object A is acknowledged without making the callback.
    548   StorePolicy(POLICY_OBJECT_B);
    549   EXPECT_TRUE(IsInvalidatorRegistered());
    550   EXPECT_TRUE(InvalidationsEnabled());
    551   EXPECT_TRUE(IsInvalidationAcknowledged(inv));
    552   EXPECT_TRUE(CheckPolicyNotRefreshed());
    553 
    554   // Make sure future invalidations for object A are ignored and for object B
    555   // are processed.
    556   EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_A)));
    557   EXPECT_TRUE(CheckPolicyNotRefreshed());
    558   FireUnknownVersionInvalidation(POLICY_OBJECT_B);
    559   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
    560   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    561 }
    562 
    563 TEST_F(CloudPolicyInvalidatorTest, UnregisterOnStoreLoaded) {
    564   // Register for object A.
    565   StartInvalidator();
    566   StorePolicy(POLICY_OBJECT_A);
    567   EXPECT_TRUE(IsInvalidatorRegistered());
    568   EXPECT_TRUE(InvalidationsEnabled());
    569   FireUnknownVersionInvalidation(POLICY_OBJECT_A);
    570   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
    571 
    572   // Check unregistration when store is loaded with no invalidation object id.
    573   syncer::Invalidation inv = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
    574   EXPECT_FALSE(IsInvalidationAcknowledged(inv));
    575   StorePolicy(POLICY_OBJECT_NONE);
    576   EXPECT_FALSE(IsInvalidatorRegistered());
    577   EXPECT_TRUE(IsInvalidationAcknowledged(inv));
    578   EXPECT_FALSE(InvalidationsEnabled());
    579   EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_A)));
    580   EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_B)));
    581   EXPECT_TRUE(CheckPolicyNotRefreshed());
    582 
    583   // Check re-registration for object B.
    584   StorePolicy(POLICY_OBJECT_B);
    585   EXPECT_TRUE(IsInvalidatorRegistered());
    586   EXPECT_TRUE(InvalidationsEnabled());
    587   FireUnknownVersionInvalidation(POLICY_OBJECT_B);
    588   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
    589   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    590 }
    591 
    592 TEST_F(CloudPolicyInvalidatorTest, HandleInvalidation) {
    593   // Register and fire invalidation
    594   StorePolicy(POLICY_OBJECT_A);
    595   StartInvalidator();
    596   EXPECT_TRUE(InvalidationsEnabled());
    597   syncer::Invalidation inv =
    598       FireInvalidation(POLICY_OBJECT_A, V(12), "test_payload");
    599 
    600   // Make sure client info is set as soon as the invalidation is received.
    601   EXPECT_TRUE(CheckInvalidationInfo(V(12), "test_payload"));
    602   EXPECT_TRUE(CheckPolicyRefreshed());
    603 
    604   // Make sure invalidation is not acknowledged until the store is loaded.
    605   EXPECT_FALSE(IsInvalidationAcknowledged(inv));
    606   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    607   EXPECT_TRUE(CheckInvalidationInfo(V(12), "test_payload"));
    608   StorePolicy(POLICY_OBJECT_A, V(12));
    609   EXPECT_TRUE(IsInvalidationAcknowledged(inv));
    610   EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
    611   EXPECT_EQ(V(12), GetHighestHandledInvalidationVersion());
    612 }
    613 
    614 TEST_F(CloudPolicyInvalidatorTest, HandleInvalidationWithUnknownVersion) {
    615   // Register and fire invalidation with unknown version.
    616   StorePolicy(POLICY_OBJECT_A);
    617   StartInvalidator();
    618   syncer::Invalidation inv = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
    619 
    620   // Make sure client info is not set until after the invalidation callback is
    621   // made.
    622   EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
    623   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
    624   EXPECT_TRUE(CheckInvalidationInfo(-1, std::string()));
    625 
    626   // Make sure invalidation is not acknowledged until the store is loaded.
    627   EXPECT_FALSE(IsInvalidationAcknowledged(inv));
    628   StorePolicy(POLICY_OBJECT_A, -1);
    629   EXPECT_TRUE(IsInvalidationAcknowledged(inv));
    630   EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
    631   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    632 }
    633 
    634 TEST_F(CloudPolicyInvalidatorTest, HandleMultipleInvalidations) {
    635   // Generate multiple invalidations.
    636   StorePolicy(POLICY_OBJECT_A);
    637   StartInvalidator();
    638   syncer::Invalidation inv1 = FireInvalidation(POLICY_OBJECT_A, V(1), "test1");
    639   EXPECT_TRUE(CheckInvalidationInfo(V(1), "test1"));
    640   syncer::Invalidation inv2 = FireInvalidation(POLICY_OBJECT_A, V(2), "test2");
    641   EXPECT_TRUE(CheckInvalidationInfo(V(2), "test2"));
    642   syncer::Invalidation inv3 = FireInvalidation(POLICY_OBJECT_A, V(3), "test3");
    643   EXPECT_TRUE(CheckInvalidationInfo(V(3), "test3"));
    644 
    645   // Make sure the replaced invalidations are acknowledged.
    646   EXPECT_TRUE(IsInvalidationAcknowledged(inv1));
    647   EXPECT_TRUE(IsInvalidationAcknowledged(inv2));
    648 
    649   // Make sure the policy is refreshed once.
    650   EXPECT_TRUE(CheckPolicyRefreshed());
    651 
    652   // Make sure that the last invalidation is only acknowledged after the store
    653   // is loaded with the latest version.
    654   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    655   StorePolicy(POLICY_OBJECT_A, V(1));
    656   EXPECT_FALSE(IsInvalidationAcknowledged(inv3));
    657   EXPECT_EQ(V(1), GetHighestHandledInvalidationVersion());
    658   StorePolicy(POLICY_OBJECT_A, V(2));
    659   EXPECT_FALSE(IsInvalidationAcknowledged(inv3));
    660   EXPECT_EQ(V(2), GetHighestHandledInvalidationVersion());
    661   StorePolicy(POLICY_OBJECT_A, V(3));
    662   EXPECT_TRUE(IsInvalidationAcknowledged(inv3));
    663   EXPECT_EQ(V(3), GetHighestHandledInvalidationVersion());
    664 }
    665 
    666 TEST_F(CloudPolicyInvalidatorTest,
    667        HandleMultipleInvalidationsWithUnknownVersion) {
    668   // Validate that multiple invalidations with unknown version each generate
    669   // unique invalidation version numbers.
    670   StorePolicy(POLICY_OBJECT_A);
    671   StartInvalidator();
    672   syncer::Invalidation inv1 = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
    673   EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
    674   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
    675   EXPECT_TRUE(CheckInvalidationInfo(-1, std::string()));
    676   syncer::Invalidation inv2 = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
    677   EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
    678   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
    679   EXPECT_TRUE(CheckInvalidationInfo(-2, std::string()));
    680   syncer::Invalidation inv3 = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
    681   EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
    682   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
    683   EXPECT_TRUE(CheckInvalidationInfo(-3, std::string()));
    684 
    685   // Make sure the replaced invalidations are acknowledged.
    686   EXPECT_TRUE(IsInvalidationAcknowledged(inv1));
    687   EXPECT_TRUE(IsInvalidationAcknowledged(inv2));
    688 
    689   // Make sure that the last invalidation is only acknowledged after the store
    690   // is loaded with the last unknown version.
    691   StorePolicy(POLICY_OBJECT_A, -1);
    692   EXPECT_FALSE(IsInvalidationAcknowledged(inv3));
    693   StorePolicy(POLICY_OBJECT_A, -2);
    694   EXPECT_FALSE(IsInvalidationAcknowledged(inv3));
    695   StorePolicy(POLICY_OBJECT_A, -3);
    696   EXPECT_TRUE(IsInvalidationAcknowledged(inv3));
    697   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    698 }
    699 
    700 TEST_F(CloudPolicyInvalidatorTest,
    701        InitialHighestHandledInvalidationVersionNonZero) {
    702   StorePolicy(POLICY_OBJECT_A);
    703   StartInvalidator(true, /* initialize */
    704                    true, /* start_refresh_scheduler */
    705                    V(2)  /* highest_handled_invalidation_version*/);
    706 
    707   // Check that an invalidation whose version is lower than the highest handled
    708   // so far is acknowledged but ignored otherwise.
    709   syncer::Invalidation inv1 = FireInvalidation(POLICY_OBJECT_A, V(1), "test1");
    710   EXPECT_TRUE(CheckPolicyNotRefreshed());
    711   EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
    712   EXPECT_TRUE(IsInvalidationAcknowledged(inv1));
    713   EXPECT_EQ(V(2), GetHighestHandledInvalidationVersion());
    714 
    715   // Check that an invalidation with an unknown version is handled.
    716   syncer::Invalidation inv = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
    717   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
    718   EXPECT_TRUE(CheckInvalidationInfo(-1, std::string()));
    719   StorePolicy(POLICY_OBJECT_A, -1);
    720   EXPECT_TRUE(IsInvalidationAcknowledged(inv));
    721   EXPECT_EQ(V(2), GetHighestHandledInvalidationVersion());
    722 
    723   // Check that an invalidation whose version matches the highest handled so far
    724   // is acknowledged but ignored otherwise.
    725   syncer::Invalidation inv2 = FireInvalidation(POLICY_OBJECT_A, V(2), "test2");
    726   EXPECT_TRUE(CheckPolicyNotRefreshed());
    727   EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
    728   EXPECT_TRUE(IsInvalidationAcknowledged(inv2));
    729   EXPECT_EQ(V(2), GetHighestHandledInvalidationVersion());
    730 
    731   // Check that an invalidation whose version is higher than the highest handled
    732   // so far is handled, causing a policy refresh.
    733   syncer::Invalidation inv3 = FireInvalidation(POLICY_OBJECT_A, V(3), "test3");
    734   EXPECT_TRUE(CheckPolicyRefreshed());
    735   EXPECT_TRUE(CheckInvalidationInfo(V(3), "test3"));
    736   StorePolicy(POLICY_OBJECT_A, V(3));
    737   EXPECT_TRUE(IsInvalidationAcknowledged(inv3));
    738   EXPECT_EQ(V(3), GetHighestHandledInvalidationVersion());
    739 }
    740 
    741 TEST_F(CloudPolicyInvalidatorTest, AcknowledgeBeforeRefresh) {
    742   // Generate an invalidation.
    743   StorePolicy(POLICY_OBJECT_A);
    744   StartInvalidator();
    745   syncer::Invalidation inv = FireInvalidation(POLICY_OBJECT_A, V(3), "test");
    746 
    747   // Ensure that the policy is not refreshed and the invalidation is
    748   // acknowledged if the store is loaded with the latest version before the
    749   // refresh can occur.
    750   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    751   StorePolicy(POLICY_OBJECT_A, V(3));
    752   EXPECT_TRUE(IsInvalidationAcknowledged(inv));
    753   EXPECT_TRUE(CheckPolicyNotRefreshed());
    754   EXPECT_EQ(V(3), GetHighestHandledInvalidationVersion());
    755 }
    756 
    757 TEST_F(CloudPolicyInvalidatorTest, NoCallbackAfterShutdown) {
    758   // Generate an invalidation.
    759   StorePolicy(POLICY_OBJECT_A);
    760   StartInvalidator();
    761   syncer::Invalidation inv = FireInvalidation(POLICY_OBJECT_A, V(3), "test");
    762 
    763   // Ensure that the policy refresh is not made after the invalidator is shut
    764   // down.
    765   ShutdownInvalidator();
    766   EXPECT_TRUE(CheckPolicyNotRefreshed());
    767   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    768   DestroyInvalidator();
    769 }
    770 
    771 TEST_F(CloudPolicyInvalidatorTest, StateChanged) {
    772   // Test invalidation service state changes while not registered.
    773   StartInvalidator();
    774   DisableInvalidationService();
    775   EnableInvalidationService();
    776   EXPECT_FALSE(InvalidationsEnabled());
    777 
    778   // Test invalidation service state changes while registered.
    779   StorePolicy(POLICY_OBJECT_A);
    780   EXPECT_TRUE(InvalidationsEnabled());
    781   DisableInvalidationService();
    782   EXPECT_FALSE(InvalidationsEnabled());
    783   DisableInvalidationService();
    784   EXPECT_FALSE(InvalidationsEnabled());
    785   EnableInvalidationService();
    786   EXPECT_TRUE(InvalidationsEnabled());
    787   EnableInvalidationService();
    788   EXPECT_TRUE(InvalidationsEnabled());
    789 
    790   // Test registration changes with invalidation service enabled.
    791   StorePolicy(POLICY_OBJECT_NONE);
    792   EXPECT_FALSE(InvalidationsEnabled());
    793   StorePolicy(POLICY_OBJECT_NONE);
    794   EXPECT_FALSE(InvalidationsEnabled());
    795   StorePolicy(POLICY_OBJECT_A);
    796   EXPECT_TRUE(InvalidationsEnabled());
    797   StorePolicy(POLICY_OBJECT_A);
    798   EXPECT_TRUE(InvalidationsEnabled());
    799 
    800   // Test registration changes with invalidation service disabled.
    801   DisableInvalidationService();
    802   EXPECT_FALSE(InvalidationsEnabled());
    803   StorePolicy(POLICY_OBJECT_NONE);
    804   StorePolicy(POLICY_OBJECT_A);
    805   EXPECT_FALSE(InvalidationsEnabled());
    806   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    807 }
    808 
    809 TEST_F(CloudPolicyInvalidatorTest, Disconnect) {
    810   // Generate an invalidation.
    811   StorePolicy(POLICY_OBJECT_A);
    812   StartInvalidator();
    813   syncer::Invalidation inv = FireInvalidation(POLICY_OBJECT_A, V(1), "test");
    814   EXPECT_TRUE(InvalidationsEnabled());
    815 
    816   // Ensure that the policy is not refreshed after disconnecting the core, but
    817   // a call to indicate that invalidations are disabled is made.
    818   DisconnectCore();
    819   EXPECT_TRUE(CheckPolicyNotRefreshed());
    820 
    821   // Ensure that invalidation service events do not cause refreshes while the
    822   // invalidator is stopped.
    823   EXPECT_TRUE(IsUnsent(FireInvalidation(POLICY_OBJECT_A, V(2), "test")));
    824   EXPECT_TRUE(CheckPolicyNotRefreshed());
    825   DisableInvalidationService();
    826   EnableInvalidationService();
    827 
    828   // Connect and disconnect without starting the refresh scheduler.
    829   ConnectCore();
    830   EXPECT_TRUE(IsUnsent(FireInvalidation(POLICY_OBJECT_A, V(3), "test")));
    831   EXPECT_TRUE(CheckPolicyNotRefreshed());
    832   DisconnectCore();
    833   EXPECT_TRUE(IsUnsent(FireInvalidation(POLICY_OBJECT_A, V(4), "test")));
    834   EXPECT_TRUE(CheckPolicyNotRefreshed());
    835 
    836   // Ensure that the invalidator returns to normal after reconnecting.
    837   ConnectCore();
    838   StartRefreshScheduler();
    839   EXPECT_TRUE(CheckPolicyNotRefreshed());
    840   EXPECT_TRUE(InvalidationsEnabled());
    841   FireInvalidation(POLICY_OBJECT_A, V(5), "test");
    842   EXPECT_TRUE(CheckInvalidationInfo(V(5), "test"));
    843   EXPECT_TRUE(CheckPolicyRefreshed());
    844   DisableInvalidationService();
    845   EXPECT_FALSE(InvalidationsEnabled());
    846   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    847 }
    848 
    849 class CloudPolicyInvalidatorUserTypedTest
    850     : public CloudPolicyInvalidatorTest,
    851       public testing::WithParamInterface<em::DeviceRegisterRequest::Type>  {
    852  protected:
    853   CloudPolicyInvalidatorUserTypedTest();
    854   virtual ~CloudPolicyInvalidatorUserTypedTest();
    855 
    856   // CloudPolicyInvalidatorTest:
    857   virtual void SetUp() OVERRIDE;
    858 
    859   // Get the current count for the given metric.
    860   base::HistogramBase::Count GetCount(MetricPolicyRefresh metric);
    861   base::HistogramBase::Count GetInvalidationCount(PolicyInvalidationType type);
    862 
    863  private:
    864   // CloudPolicyInvalidatorTest:
    865   virtual em::DeviceRegisterRequest::Type GetPolicyType() const OVERRIDE;
    866 
    867   // Get histogram samples for the given histogram.
    868   scoped_ptr<base::HistogramSamples> GetHistogramSamples(
    869       const std::string& name) const;
    870 
    871   // Stores starting histogram counts for kMetricPolicyRefresh.
    872   scoped_ptr<base::HistogramSamples> refresh_samples_;
    873 
    874   // Stores starting histogram counts for kMetricPolicyInvalidations.
    875   scoped_ptr<base::HistogramSamples> invalidations_samples_;
    876 
    877   DISALLOW_COPY_AND_ASSIGN(CloudPolicyInvalidatorUserTypedTest);
    878 };
    879 
    880 CloudPolicyInvalidatorUserTypedTest::CloudPolicyInvalidatorUserTypedTest() {
    881 }
    882 
    883 CloudPolicyInvalidatorUserTypedTest::~CloudPolicyInvalidatorUserTypedTest() {
    884 }
    885 
    886 void CloudPolicyInvalidatorUserTypedTest::SetUp() {
    887   base::StatisticsRecorder::Initialize();
    888   refresh_samples_ = GetHistogramSamples(
    889       GetPolicyType() == em::DeviceRegisterRequest::DEVICE ?
    890           kMetricDevicePolicyRefresh : kMetricUserPolicyRefresh);
    891   invalidations_samples_ = GetHistogramSamples(
    892       GetPolicyType() == em::DeviceRegisterRequest::DEVICE ?
    893           kMetricDevicePolicyInvalidations : kMetricUserPolicyInvalidations);
    894 }
    895 
    896 base::HistogramBase::Count CloudPolicyInvalidatorUserTypedTest::GetCount(
    897     MetricPolicyRefresh metric) {
    898   return GetHistogramSamples(
    899       GetPolicyType() == em::DeviceRegisterRequest::DEVICE ?
    900           kMetricDevicePolicyRefresh : kMetricUserPolicyRefresh)->
    901               GetCount(metric) - refresh_samples_->GetCount(metric);
    902 }
    903 
    904 base::HistogramBase::Count
    905 CloudPolicyInvalidatorUserTypedTest::GetInvalidationCount(
    906     PolicyInvalidationType type) {
    907   return GetHistogramSamples(
    908       GetPolicyType() == em::DeviceRegisterRequest::DEVICE ?
    909           kMetricDevicePolicyInvalidations : kMetricUserPolicyInvalidations)->
    910           GetCount(type) - invalidations_samples_->GetCount(type);
    911 }
    912 
    913 em::DeviceRegisterRequest::Type
    914 CloudPolicyInvalidatorUserTypedTest::GetPolicyType() const {
    915   return GetParam();
    916 }
    917 
    918 scoped_ptr<base::HistogramSamples>
    919 CloudPolicyInvalidatorUserTypedTest::GetHistogramSamples(
    920     const std::string& name) const {
    921   base::HistogramBase* histogram =
    922       base::StatisticsRecorder::FindHistogram(name);
    923   if (!histogram)
    924     return scoped_ptr<base::HistogramSamples>(new base::SampleMap());
    925   return histogram->SnapshotSamples();
    926 }
    927 
    928 TEST_P(CloudPolicyInvalidatorUserTypedTest, RefreshMetricsUnregistered) {
    929   // Store loads occurring before invalidation registration are not counted.
    930   StartInvalidator();
    931   StorePolicy(POLICY_OBJECT_NONE, 0, false /* policy_changed */);
    932   StorePolicy(POLICY_OBJECT_NONE, 0, true /* policy_changed */);
    933   EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_CHANGED));
    934   EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS));
    935   EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_UNCHANGED));
    936   EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_CHANGED));
    937   EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_UNCHANGED));
    938   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    939 }
    940 
    941 TEST_P(CloudPolicyInvalidatorUserTypedTest, RefreshMetricsNoInvalidations) {
    942   // Store loads occurring while registered should be differentiated depending
    943   // on whether the invalidation service was enabled or not.
    944   StorePolicy(POLICY_OBJECT_A);
    945   StartInvalidator();
    946 
    947   // Initially, invalidations have not been enabled past the grace period, so
    948   // invalidations are OFF.
    949   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
    950   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
    951   EXPECT_EQ(1, GetCount(METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS));
    952 
    953   // If the clock advances less than the grace period, invalidations are OFF.
    954   AdvanceClock(base::TimeDelta::FromSeconds(1));
    955   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
    956   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
    957   EXPECT_EQ(2, GetCount(METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS));
    958 
    959   // After the grace period elapses, invalidations are ON.
    960   AdvanceClock(base::TimeDelta::FromSeconds(
    961       CloudPolicyInvalidator::kInvalidationGracePeriod));
    962   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
    963   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
    964   EXPECT_EQ(1, GetCount(METRIC_POLICY_REFRESH_CHANGED));
    965 
    966   // After the invalidation service is disabled, invalidations are OFF.
    967   DisableInvalidationService();
    968   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
    969   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
    970   EXPECT_EQ(3, GetCount(METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS));
    971 
    972   // Enabling the invalidation service results in a new grace period, so
    973   // invalidations are OFF.
    974   EnableInvalidationService();
    975   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
    976   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
    977   EXPECT_EQ(4, GetCount(METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS));
    978 
    979   // After the grace period elapses, invalidations are ON.
    980   AdvanceClock(base::TimeDelta::FromSeconds(
    981       CloudPolicyInvalidator::kInvalidationGracePeriod));
    982   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
    983   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
    984 
    985   EXPECT_EQ(2, GetCount(METRIC_POLICY_REFRESH_CHANGED));
    986   EXPECT_EQ(4, GetCount(METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS));
    987   EXPECT_EQ(6, GetCount(METRIC_POLICY_REFRESH_UNCHANGED));
    988   EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_CHANGED));
    989   EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_UNCHANGED));
    990   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
    991 }
    992 
    993 TEST_P(CloudPolicyInvalidatorUserTypedTest, RefreshMetricsInvalidation) {
    994   // Store loads after an invalidation are counted as invalidated, even if
    995   // the loads do not result in the invalidation being acknowledged.
    996   StartInvalidator();
    997   StorePolicy(POLICY_OBJECT_A);
    998   AdvanceClock(base::TimeDelta::FromSeconds(
    999       CloudPolicyInvalidator::kInvalidationGracePeriod));
   1000   FireInvalidation(POLICY_OBJECT_A, V(5), "test");
   1001   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
   1002   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
   1003   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
   1004   StorePolicy(POLICY_OBJECT_A, V(5), true /* policy_changed */);
   1005   EXPECT_EQ(V(5), GetHighestHandledInvalidationVersion());
   1006 
   1007   // Store loads after the invalidation is complete are not counted as
   1008   // invalidated.
   1009   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
   1010   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
   1011   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
   1012   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
   1013   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
   1014   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
   1015   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
   1016 
   1017   EXPECT_EQ(3, GetCount(METRIC_POLICY_REFRESH_CHANGED));
   1018   EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS));
   1019   EXPECT_EQ(4, GetCount(METRIC_POLICY_REFRESH_UNCHANGED));
   1020   EXPECT_EQ(2, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_CHANGED));
   1021   EXPECT_EQ(1, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_UNCHANGED));
   1022   EXPECT_EQ(V(5), GetHighestHandledInvalidationVersion());
   1023 }
   1024 
   1025 TEST_P(CloudPolicyInvalidatorUserTypedTest, ExpiredInvalidations) {
   1026   StorePolicy(POLICY_OBJECT_A, 0, false, Now());
   1027   StartInvalidator();
   1028 
   1029   // Invalidations fired before the last fetch time (adjusted by max time delta)
   1030   // should be ignored.
   1031   base::Time time = Now() - base::TimeDelta::FromSeconds(
   1032       CloudPolicyInvalidator::kMaxInvalidationTimeDelta + 300);
   1033   syncer::Invalidation inv =
   1034       FireInvalidation(POLICY_OBJECT_A, GetVersion(time), "test");
   1035   ASSERT_TRUE(IsInvalidationAcknowledged(inv));
   1036   ASSERT_TRUE(CheckPolicyNotRefreshed());
   1037 
   1038   time += base::TimeDelta::FromMinutes(5) - base::TimeDelta::FromSeconds(1);
   1039   inv = FireInvalidation(POLICY_OBJECT_A, GetVersion(time), "test");
   1040   ASSERT_TRUE(IsInvalidationAcknowledged(inv));
   1041   ASSERT_TRUE(CheckPolicyNotRefreshed());
   1042 
   1043   // Invalidations fired after the last fetch should not be ignored.
   1044   time += base::TimeDelta::FromSeconds(1);
   1045   inv = FireInvalidation(POLICY_OBJECT_A, GetVersion(time), "test");
   1046   ASSERT_FALSE(IsInvalidationAcknowledged(inv));
   1047   ASSERT_TRUE(CheckPolicyRefreshed());
   1048 
   1049   time += base::TimeDelta::FromMinutes(10);
   1050   inv = FireInvalidation(POLICY_OBJECT_A, GetVersion(time), "test");
   1051   ASSERT_FALSE(IsInvalidationAcknowledged(inv));
   1052   ASSERT_TRUE(CheckPolicyRefreshed());
   1053 
   1054   time += base::TimeDelta::FromMinutes(10);
   1055   inv = FireInvalidation(POLICY_OBJECT_A, GetVersion(time), "test");
   1056   ASSERT_FALSE(IsInvalidationAcknowledged(inv));
   1057   ASSERT_TRUE(CheckPolicyRefreshed());
   1058 
   1059   // Unknown version invalidations fired just after the last fetch time should
   1060   // be ignored.
   1061   inv = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
   1062   ASSERT_TRUE(IsInvalidationAcknowledged(inv));
   1063   ASSERT_TRUE(CheckPolicyNotRefreshed());
   1064 
   1065   AdvanceClock(base::TimeDelta::FromSeconds(
   1066       CloudPolicyInvalidator::kUnknownVersionIgnorePeriod - 1));
   1067   inv = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
   1068   ASSERT_TRUE(IsInvalidationAcknowledged(inv));
   1069   ASSERT_TRUE(CheckPolicyNotRefreshed());
   1070 
   1071   // Unknown version invalidations fired past the ignore period should not be
   1072   // ignored.
   1073   AdvanceClock(base::TimeDelta::FromSeconds(1));
   1074   inv = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
   1075   ASSERT_FALSE(IsInvalidationAcknowledged(inv));
   1076   ASSERT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
   1077 
   1078   // Verify that received invalidations metrics are correct.
   1079   EXPECT_EQ(1, GetInvalidationCount(POLICY_INVALIDATION_TYPE_NO_PAYLOAD));
   1080   EXPECT_EQ(3, GetInvalidationCount(POLICY_INVALIDATION_TYPE_NORMAL));
   1081   EXPECT_EQ(2,
   1082             GetInvalidationCount(POLICY_INVALIDATION_TYPE_NO_PAYLOAD_EXPIRED));
   1083   EXPECT_EQ(2, GetInvalidationCount(POLICY_INVALIDATION_TYPE_EXPIRED));
   1084   EXPECT_EQ(0, GetHighestHandledInvalidationVersion());
   1085 }
   1086 
   1087 #if defined(OS_CHROMEOS)
   1088 INSTANTIATE_TEST_CASE_P(
   1089     CloudPolicyInvalidatorUserTypedTestInstance,
   1090     CloudPolicyInvalidatorUserTypedTest,
   1091     testing::Values(em::DeviceRegisterRequest::USER,
   1092                     em::DeviceRegisterRequest::DEVICE));
   1093 #elif defined(OS_ANDROID)
   1094 INSTANTIATE_TEST_CASE_P(
   1095     CloudPolicyInvalidatorUserTypedTestInstance,
   1096     CloudPolicyInvalidatorUserTypedTest,
   1097     testing::Values(em::DeviceRegisterRequest::ANDROID_BROWSER));
   1098 #elif defined(OS_IOS)
   1099 INSTANTIATE_TEST_CASE_P(
   1100     CloudPolicyInvalidatorUserTypedTestInstance,
   1101     CloudPolicyInvalidatorUserTypedTest,
   1102     testing::Values(em::DeviceRegisterRequest::IOS_BROWSER));
   1103 #else
   1104 INSTANTIATE_TEST_CASE_P(
   1105     CloudPolicyInvalidatorUserTypedTestInstance,
   1106     CloudPolicyInvalidatorUserTypedTest,
   1107     testing::Values(em::DeviceRegisterRequest::BROWSER));
   1108 #endif
   1109 
   1110 }  // namespace policy
   1111