| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright (c) 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/memory/ref_counted.h" | 
 |    9 #include "base/memory/scoped_ptr.h" | 
 |   10 #include "base/metrics/histogram.h" | 
 |   11 #include "base/metrics/histogram_samples.h" | 
 |   12 #include "base/metrics/sample_map.h" | 
 |   13 #include "base/metrics/statistics_recorder.h" | 
 |   14 #include "base/test/test_simple_task_runner.h" | 
 |   15 #include "base/time/time.h" | 
 |   16 #include "base/values.h" | 
 |   17 #include "chrome/browser/invalidation/fake_invalidation_service.h" | 
 |   18 #include "chrome/browser/policy/cloud/cloud_policy_core.h" | 
 |   19 #include "chrome/browser/policy/cloud/cloud_policy_invalidator.h" | 
 |   20 #include "chrome/browser/policy/cloud/cloud_policy_service.h" | 
 |   21 #include "chrome/browser/policy/cloud/enterprise_metrics.h" | 
 |   22 #include "chrome/browser/policy/cloud/mock_cloud_policy_client.h" | 
 |   23 #include "chrome/browser/policy/cloud/mock_cloud_policy_store.h" | 
 |   24 #include "chrome/browser/policy/policy_types.h" | 
 |   25 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" | 
 |   26 #include "policy/policy_constants.h" | 
 |   27 #include "sync/notifier/invalidation_util.h" | 
 |   28 #include "testing/gmock/include/gmock/gmock.h" | 
 |   29 #include "testing/gtest/include/gtest/gtest.h" | 
 |   30  | 
 |   31 namespace policy { | 
 |   32  | 
 |   33 class CloudPolicyInvalidatorTest : public testing::Test, | 
 |   34                                    public CloudPolicyInvalidationHandler { | 
 |   35  protected: | 
 |   36   // Policy objects which can be used in tests. | 
 |   37   enum PolicyObject { | 
 |   38     POLICY_OBJECT_NONE, | 
 |   39     POLICY_OBJECT_A, | 
 |   40     POLICY_OBJECT_B | 
 |   41   }; | 
 |   42  | 
 |   43   CloudPolicyInvalidatorTest(); | 
 |   44  | 
 |   45   virtual void SetUp() OVERRIDE; | 
 |   46  | 
 |   47   virtual void TearDown() OVERRIDE; | 
 |   48  | 
 |   49   // Starts the invalidator which will be tested. | 
 |   50   void StartInvalidator(bool initialize); | 
 |   51   void StartInvalidator() { | 
 |   52     StartInvalidator(true /* initialize */); | 
 |   53   } | 
 |   54  | 
 |   55   // Simulates storing a new policy to the policy store. | 
 |   56   // |object| determines which policy object the store will report the | 
 |   57   // invalidator should register for. May be POLICY_OBJECT_NONE for no object. | 
 |   58   // |invalidation_version| determines what invalidation the store will report. | 
 |   59   // |policy_changed| determines whether the store will report that the | 
 |   60   // policy changed. | 
 |   61   // |timestamp| determines the response timestamp the store will report. | 
 |   62   void StorePolicy( | 
 |   63       PolicyObject object, | 
 |   64       int64 invalidation_version, | 
 |   65       bool policy_changed, | 
 |   66       int64 timestamp); | 
 |   67   void StorePolicy( | 
 |   68       PolicyObject object, | 
 |   69       int64 invalidation_version, | 
 |   70       bool policy_changed) { | 
 |   71     StorePolicy(object, invalidation_version, policy_changed, ++timestamp_); | 
 |   72   } | 
 |   73   void StorePolicy(PolicyObject object, int64 invalidation_version) { | 
 |   74     StorePolicy(object, invalidation_version, false); | 
 |   75   } | 
 |   76   void StorePolicy(PolicyObject object) { | 
 |   77     StorePolicy(object, 0); | 
 |   78   } | 
 |   79  | 
 |   80   // Disables the invalidation service. It is enabled by default. | 
 |   81   void DisableInvalidationService(); | 
 |   82  | 
 |   83   // Enables the invalidation service. It is enabled by default. | 
 |   84   void EnableInvalidationService(); | 
 |   85  | 
 |   86   // Causes the invalidation service to fire an invalidation. Returns an ack | 
 |   87   // handle which be used to verify that the invalidation was acknowledged. | 
 |   88   syncer::AckHandle FireInvalidation( | 
 |   89       PolicyObject object, | 
 |   90       int64 version, | 
 |   91       const std::string& payload); | 
 |   92  | 
 |   93   // Causes the invalidation service to fire an invalidation with unknown | 
 |   94   // version. Returns an ack handle which be used to verify that the | 
 |   95   // invalidation was acknowledged. | 
 |   96   syncer::AckHandle FireInvalidation(PolicyObject object); | 
 |   97  | 
 |   98   // Checks the expected value of the currently set invalidation info. | 
 |   99   bool CheckInvalidationInfo(int64 version, const std::string& payload); | 
 |  100  | 
 |  101   // Checks that the invalidate callback was not called. | 
 |  102   bool CheckInvalidateNotCalled(); | 
 |  103  | 
 |  104   // Checks that the invalidate callback was called within an appropriate | 
 |  105   // timeframe depending on whether the invalidation had unknown version. | 
 |  106   bool CheckInvalidateCalled(bool unknown_version); | 
 |  107   bool CheckInvalidateCalled() { | 
 |  108     return CheckInvalidateCalled(true); | 
 |  109   } | 
 |  110  | 
 |  111   // Checks that the state changed callback of the invalidation handler was not | 
 |  112   // called. | 
 |  113   bool CheckStateChangedNotCalled(); | 
 |  114  | 
 |  115   // Checks that the state changed callback of the invalidation handler was | 
 |  116   // called with the given state. | 
 |  117   bool CheckStateChangedCalled(bool invalidations_enabled); | 
 |  118  | 
 |  119   // Determines if the invalidation with the given ack handle has been | 
 |  120   // acknowledged. | 
 |  121   bool IsInvalidationAcknowledged(const syncer::AckHandle& ack_handle); | 
 |  122  | 
 |  123   // Get the current count for the given metric. | 
 |  124   base::HistogramBase::Count GetCount(MetricPolicyRefresh metric); | 
 |  125   base::HistogramBase::Count GetCount(MetricPolicyInvalidations metric); | 
 |  126  | 
 |  127   // CloudPolicyInvalidationHandler: | 
 |  128   virtual void SetInvalidationInfo( | 
 |  129       int64 version, | 
 |  130       const std::string& payload) OVERRIDE; | 
 |  131   virtual void InvalidatePolicy() OVERRIDE; | 
 |  132   virtual void OnInvalidatorStateChanged(bool invalidations_enabled) OVERRIDE; | 
 |  133  | 
 |  134  private: | 
 |  135   // Returns the object id of the given policy object. | 
 |  136   const invalidation::ObjectId& GetPolicyObjectId(PolicyObject object) const; | 
 |  137  | 
 |  138   // Get histogram samples for the given histogram. | 
 |  139   scoped_ptr<base::HistogramSamples> GetHistogramSamples( | 
 |  140       const std::string& name) const; | 
 |  141  | 
 |  142   // Objects the invalidator depends on. | 
 |  143   invalidation::FakeInvalidationService invalidation_service_; | 
 |  144   MockCloudPolicyStore store_; | 
 |  145   scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | 
 |  146  | 
 |  147   // The invalidator which will be tested. | 
 |  148   scoped_ptr<CloudPolicyInvalidator> invalidator_; | 
 |  149  | 
 |  150   // The latest invalidation info set by the invalidator. | 
 |  151   int64 invalidation_version_; | 
 |  152   std::string invalidation_payload_; | 
 |  153  | 
 |  154   // Object ids for the test policy objects. | 
 |  155   invalidation::ObjectId object_id_a_; | 
 |  156   invalidation::ObjectId object_id_b_; | 
 |  157  | 
 |  158   // Increasing policy timestamp. | 
 |  159   int64 timestamp_; | 
 |  160  | 
 |  161   // Fake policy values which are alternated to cause the store to report a | 
 |  162   // changed policy. | 
 |  163   const char* policy_value_a_; | 
 |  164   const char* policy_value_b_; | 
 |  165  | 
 |  166   // The currently used policy value. | 
 |  167   const char* policy_value_cur_; | 
 |  168  | 
 |  169   // Stores how many times the invalidate callback was called. | 
 |  170   int invalidate_callback_count_; | 
 |  171  | 
 |  172   // Stores how many times the state change callback was called for each state. | 
 |  173   int state_change_enabled_callback_count_; | 
 |  174   int state_change_disabled_callback_count_; | 
 |  175  | 
 |  176   // Stores starting histogram counts for kMetricPolicyRefresh. | 
 |  177   scoped_ptr<base::HistogramSamples> refresh_samples_; | 
 |  178  | 
 |  179   // Stores starting histogram counts for kMetricPolicyInvalidations. | 
 |  180   scoped_ptr<base::HistogramSamples> invalidations_samples_; | 
 |  181 }; | 
 |  182  | 
 |  183 CloudPolicyInvalidatorTest::CloudPolicyInvalidatorTest() | 
 |  184     : task_runner_(new base::TestSimpleTaskRunner()), | 
 |  185       invalidation_version_(0), | 
 |  186       object_id_a_(135, "asdf"), | 
 |  187       object_id_b_(246, "zxcv"), | 
 |  188       timestamp_(123456), | 
 |  189       policy_value_a_("asdf"), | 
 |  190       policy_value_b_("zxcv"), | 
 |  191       policy_value_cur_(policy_value_a_), | 
 |  192       invalidate_callback_count_(0), | 
 |  193       state_change_enabled_callback_count_(0), | 
 |  194       state_change_disabled_callback_count_(0) {} | 
 |  195  | 
 |  196 void CloudPolicyInvalidatorTest::SetUp() { | 
 |  197   base::StatisticsRecorder::Initialize(); | 
 |  198   refresh_samples_ = GetHistogramSamples(kMetricPolicyRefresh); | 
 |  199   invalidations_samples_ = GetHistogramSamples(kMetricPolicyInvalidations); | 
 |  200 } | 
 |  201  | 
 |  202 void CloudPolicyInvalidatorTest::TearDown() { | 
 |  203   EXPECT_FALSE(invalidation_service_.ReceivedInvalidAcknowledgement()); | 
 |  204   if (invalidator_) | 
 |  205     invalidator_->Shutdown(); | 
 |  206 } | 
 |  207  | 
 |  208 void CloudPolicyInvalidatorTest::StartInvalidator(bool initialize) { | 
 |  209   invalidator_.reset(new CloudPolicyInvalidator( | 
 |  210       this /* invalidation_handler */, | 
 |  211       &store_, | 
 |  212       task_runner_)); | 
 |  213   if (initialize) | 
 |  214     invalidator_->InitializeWithService(&invalidation_service_); | 
 |  215 } | 
 |  216  | 
 |  217 void CloudPolicyInvalidatorTest::StorePolicy( | 
 |  218     PolicyObject object, | 
 |  219     int64 invalidation_version, | 
 |  220     bool policy_changed, | 
 |  221     int64 timestamp) { | 
 |  222   enterprise_management::PolicyData* data = | 
 |  223       new enterprise_management::PolicyData(); | 
 |  224   if (object != POLICY_OBJECT_NONE) { | 
 |  225     data->set_invalidation_source(GetPolicyObjectId(object).source()); | 
 |  226     data->set_invalidation_name(GetPolicyObjectId(object).name()); | 
 |  227   } | 
 |  228   data->set_timestamp(timestamp); | 
 |  229   // Swap the policy value if a policy change is desired. | 
 |  230   if (policy_changed) | 
 |  231     policy_value_cur_ = policy_value_cur_ == policy_value_a_ ? | 
 |  232         policy_value_b_ : policy_value_a_; | 
 |  233   data->set_policy_value(policy_value_cur_); | 
 |  234   store_.invalidation_version_ = invalidation_version; | 
 |  235   store_.policy_.reset(data); | 
 |  236   base::DictionaryValue policies; | 
 |  237   policies.SetInteger( | 
 |  238       key::kMaxInvalidationFetchDelay, | 
 |  239       CloudPolicyInvalidator::kMaxFetchDelayMin); | 
 |  240   store_.policy_map_.LoadFrom( | 
 |  241       &policies, | 
 |  242       POLICY_LEVEL_MANDATORY, | 
 |  243       POLICY_SCOPE_MACHINE); | 
 |  244   store_.NotifyStoreLoaded(); | 
 |  245 } | 
 |  246  | 
 |  247 void CloudPolicyInvalidatorTest::DisableInvalidationService() { | 
 |  248   invalidation_service_.SetInvalidatorState( | 
 |  249       syncer::TRANSIENT_INVALIDATION_ERROR); | 
 |  250 } | 
 |  251  | 
 |  252 void CloudPolicyInvalidatorTest::EnableInvalidationService() { | 
 |  253   invalidation_service_.SetInvalidatorState(syncer::INVALIDATIONS_ENABLED); | 
 |  254 } | 
 |  255  | 
 |  256 syncer::AckHandle CloudPolicyInvalidatorTest::FireInvalidation( | 
 |  257     PolicyObject object, | 
 |  258     int64 version, | 
 |  259     const std::string& payload) { | 
 |  260   return invalidation_service_.EmitInvalidationForTest( | 
 |  261       GetPolicyObjectId(object), | 
 |  262       version, | 
 |  263       payload); | 
 |  264 } | 
 |  265  | 
 |  266 syncer::AckHandle CloudPolicyInvalidatorTest::FireInvalidation( | 
 |  267     PolicyObject object) { | 
 |  268   return invalidation_service_.EmitInvalidationForTest( | 
 |  269       GetPolicyObjectId(object), | 
 |  270       syncer::Invalidation::kUnknownVersion, | 
 |  271       std::string()); | 
 |  272 } | 
 |  273  | 
 |  274 bool CloudPolicyInvalidatorTest::CheckInvalidationInfo( | 
 |  275     int64 version, | 
 |  276     const std::string& payload) { | 
 |  277   return version == invalidation_version_ && payload == invalidation_payload_; | 
 |  278 } | 
 |  279  | 
 |  280 bool CloudPolicyInvalidatorTest::CheckInvalidateNotCalled() { | 
 |  281   bool result = true; | 
 |  282   if (invalidate_callback_count_ != 0) | 
 |  283     result = false; | 
 |  284   task_runner_->RunUntilIdle(); | 
 |  285   if (invalidate_callback_count_ != 0) | 
 |  286     result = false; | 
 |  287   return result; | 
 |  288 } | 
 |  289  | 
 |  290 bool CloudPolicyInvalidatorTest::CheckInvalidateCalled(bool unknown_version) { | 
 |  291   base::TimeDelta min_delay; | 
 |  292   base::TimeDelta max_delay = base::TimeDelta::FromMilliseconds( | 
 |  293       CloudPolicyInvalidator::kMaxFetchDelayMin); | 
 |  294   if (unknown_version) { | 
 |  295     base::TimeDelta additional_delay = base::TimeDelta::FromMinutes( | 
 |  296         CloudPolicyInvalidator::kMissingPayloadDelay); | 
 |  297     min_delay += additional_delay; | 
 |  298     max_delay += additional_delay; | 
 |  299   } | 
 |  300  | 
 |  301   if (task_runner_->GetPendingTasks().empty()) | 
 |  302     return false; | 
 |  303   base::TimeDelta actual_delay = task_runner_->GetPendingTasks().back().delay; | 
 |  304   EXPECT_GE(actual_delay, min_delay); | 
 |  305   EXPECT_LE(actual_delay, max_delay); | 
 |  306  | 
 |  307   bool result = true; | 
 |  308   if (invalidate_callback_count_ != 0) | 
 |  309     result = false; | 
 |  310   task_runner_->RunUntilIdle(); | 
 |  311   if (invalidate_callback_count_ != 1) | 
 |  312     result = false; | 
 |  313   invalidate_callback_count_ = 0; | 
 |  314   return result; | 
 |  315 } | 
 |  316  | 
 |  317 bool CloudPolicyInvalidatorTest::CheckStateChangedNotCalled() { | 
 |  318   return state_change_enabled_callback_count_ == 0 && | 
 |  319       state_change_disabled_callback_count_ == 0; | 
 |  320 } | 
 |  321  | 
 |  322 bool CloudPolicyInvalidatorTest::CheckStateChangedCalled( | 
 |  323     bool invalidations_enabled) { | 
 |  324   int expected_enabled_count_ = invalidations_enabled ? 1 : 0; | 
 |  325   int expected_disabled_count_ = invalidations_enabled ? 0 : 1; | 
 |  326   bool result = state_change_enabled_callback_count_ == expected_enabled_count_ | 
 |  327       && state_change_disabled_callback_count_ == expected_disabled_count_; | 
 |  328   state_change_enabled_callback_count_ = 0; | 
 |  329   state_change_disabled_callback_count_ = 0; | 
 |  330   return result; | 
 |  331 } | 
 |  332  | 
 |  333 bool CloudPolicyInvalidatorTest::IsInvalidationAcknowledged( | 
 |  334     const syncer::AckHandle& ack_handle) { | 
 |  335   return invalidation_service_.IsInvalidationAcknowledged(ack_handle); | 
 |  336 } | 
 |  337  | 
 |  338 base::HistogramBase::Count CloudPolicyInvalidatorTest::GetCount( | 
 |  339     MetricPolicyRefresh metric) { | 
 |  340   return GetHistogramSamples(kMetricPolicyRefresh)->GetCount(metric) - | 
 |  341       refresh_samples_->GetCount(metric); | 
 |  342 } | 
 |  343  | 
 |  344 base::HistogramBase::Count CloudPolicyInvalidatorTest::GetCount( | 
 |  345     MetricPolicyInvalidations metric) { | 
 |  346   return GetHistogramSamples(kMetricPolicyInvalidations)->GetCount(metric) - | 
 |  347       invalidations_samples_->GetCount(metric); | 
 |  348 } | 
 |  349  | 
 |  350 void CloudPolicyInvalidatorTest::SetInvalidationInfo( | 
 |  351     int64 version, | 
 |  352     const std::string& payload) { | 
 |  353   invalidation_version_ = version; | 
 |  354   invalidation_payload_ = payload; | 
 |  355 } | 
 |  356  | 
 |  357 void CloudPolicyInvalidatorTest::InvalidatePolicy() { | 
 |  358   ++invalidate_callback_count_; | 
 |  359 } | 
 |  360  | 
 |  361 void CloudPolicyInvalidatorTest::OnInvalidatorStateChanged( | 
 |  362     bool invalidations_enabled) { | 
 |  363   if (invalidator_.get()) | 
 |  364     EXPECT_EQ(invalidations_enabled, invalidator_->invalidations_enabled()); | 
 |  365   if (invalidations_enabled) | 
 |  366     ++state_change_enabled_callback_count_; | 
 |  367   else | 
 |  368     ++state_change_disabled_callback_count_; | 
 |  369 } | 
 |  370  | 
 |  371 const invalidation::ObjectId& CloudPolicyInvalidatorTest::GetPolicyObjectId( | 
 |  372     PolicyObject object) const { | 
 |  373   EXPECT_TRUE(object == POLICY_OBJECT_A || object == POLICY_OBJECT_B); | 
 |  374   return object == POLICY_OBJECT_A ? object_id_a_ : object_id_b_; | 
 |  375 } | 
 |  376  | 
 |  377 scoped_ptr<base::HistogramSamples> | 
 |  378     CloudPolicyInvalidatorTest::GetHistogramSamples( | 
 |  379         const std::string& name) const { | 
 |  380   base::HistogramBase* histogram = | 
 |  381       base::StatisticsRecorder::FindHistogram(name); | 
 |  382   if (!histogram) | 
 |  383     return scoped_ptr<base::HistogramSamples>(new base::SampleMap()); | 
 |  384   return histogram->SnapshotSamples(); | 
 |  385 } | 
 |  386  | 
 |  387 TEST_F(CloudPolicyInvalidatorTest, Uninitialized) { | 
 |  388   // No invalidations should be processed if the invalidator is not intialized. | 
 |  389   StartInvalidator(false /* initialize */); | 
 |  390   StorePolicy(POLICY_OBJECT_A); | 
 |  391   FireInvalidation(POLICY_OBJECT_A); | 
 |  392   EXPECT_TRUE(CheckInvalidateNotCalled()); | 
 |  393 } | 
 |  394  | 
 |  395 TEST_F(CloudPolicyInvalidatorTest, RegisterOnStoreLoaded) { | 
 |  396   // No registration when store is not loaded. | 
 |  397   StartInvalidator(); | 
 |  398   EXPECT_TRUE(CheckStateChangedNotCalled()); | 
 |  399   FireInvalidation(POLICY_OBJECT_A); | 
 |  400   FireInvalidation(POLICY_OBJECT_B); | 
 |  401   EXPECT_TRUE(CheckInvalidateNotCalled()); | 
 |  402  | 
 |  403   // No registration when store is loaded with no invalidation object id. | 
 |  404   StorePolicy(POLICY_OBJECT_NONE); | 
 |  405   EXPECT_TRUE(CheckStateChangedNotCalled()); | 
 |  406   FireInvalidation(POLICY_OBJECT_A); | 
 |  407   FireInvalidation(POLICY_OBJECT_B); | 
 |  408   EXPECT_TRUE(CheckInvalidateNotCalled()); | 
 |  409  | 
 |  410   // Check registration when store is loaded for object A. | 
 |  411   StorePolicy(POLICY_OBJECT_A); | 
 |  412   EXPECT_TRUE(CheckStateChangedCalled(true)); | 
 |  413   FireInvalidation(POLICY_OBJECT_A); | 
 |  414   EXPECT_TRUE(CheckInvalidateCalled()); | 
 |  415   FireInvalidation(POLICY_OBJECT_B); | 
 |  416   EXPECT_TRUE(CheckInvalidateNotCalled()); | 
 |  417 } | 
 |  418  | 
 |  419 TEST_F(CloudPolicyInvalidatorTest, ChangeRegistration) { | 
 |  420   // Register for object A. | 
 |  421   StartInvalidator(); | 
 |  422   StorePolicy(POLICY_OBJECT_A); | 
 |  423   EXPECT_TRUE(CheckStateChangedCalled(true)); | 
 |  424   FireInvalidation(POLICY_OBJECT_A); | 
 |  425   EXPECT_TRUE(CheckInvalidateCalled()); | 
 |  426   FireInvalidation(POLICY_OBJECT_B); | 
 |  427   EXPECT_TRUE(CheckInvalidateNotCalled()); | 
 |  428   syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A); | 
 |  429  | 
 |  430   // Check re-registration for object B. Make sure the pending invalidation for | 
 |  431   // object A is acknowledged without making the callback. | 
 |  432   StorePolicy(POLICY_OBJECT_B); | 
 |  433   EXPECT_TRUE(CheckStateChangedNotCalled()); | 
 |  434   EXPECT_TRUE(IsInvalidationAcknowledged(ack)); | 
 |  435   EXPECT_TRUE(CheckInvalidateNotCalled()); | 
 |  436  | 
 |  437   // Make sure future invalidations for object A are ignored and for object B | 
 |  438   // are processed. | 
 |  439   FireInvalidation(POLICY_OBJECT_A); | 
 |  440   EXPECT_TRUE(CheckInvalidateNotCalled()); | 
 |  441   FireInvalidation(POLICY_OBJECT_B); | 
 |  442   EXPECT_TRUE(CheckInvalidateCalled()); | 
 |  443 } | 
 |  444  | 
 |  445 TEST_F(CloudPolicyInvalidatorTest, UnregisterOnStoreLoaded) { | 
 |  446   // Register for object A. | 
 |  447   StartInvalidator(); | 
 |  448   StorePolicy(POLICY_OBJECT_A); | 
 |  449   EXPECT_TRUE(CheckStateChangedCalled(true)); | 
 |  450   FireInvalidation(POLICY_OBJECT_A); | 
 |  451   EXPECT_TRUE(CheckInvalidateCalled()); | 
 |  452  | 
 |  453   // Check unregistration when store is loaded with no invalidation object id. | 
 |  454   syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A); | 
 |  455   EXPECT_FALSE(IsInvalidationAcknowledged(ack)); | 
 |  456   StorePolicy(POLICY_OBJECT_NONE); | 
 |  457   EXPECT_TRUE(IsInvalidationAcknowledged(ack)); | 
 |  458   EXPECT_TRUE(CheckStateChangedCalled(false)); | 
 |  459   FireInvalidation(POLICY_OBJECT_A); | 
 |  460   FireInvalidation(POLICY_OBJECT_B); | 
 |  461   EXPECT_TRUE(CheckInvalidateNotCalled()); | 
 |  462  | 
 |  463   // Check re-registration for object B. | 
 |  464   StorePolicy(POLICY_OBJECT_B); | 
 |  465   EXPECT_TRUE(CheckStateChangedCalled(true)); | 
 |  466   FireInvalidation(POLICY_OBJECT_B); | 
 |  467   EXPECT_TRUE(CheckInvalidateCalled()); | 
 |  468 } | 
 |  469  | 
 |  470 TEST_F(CloudPolicyInvalidatorTest, HandleInvalidation) { | 
 |  471   // Register and fire invalidation | 
 |  472   StorePolicy(POLICY_OBJECT_A); | 
 |  473   StartInvalidator(); | 
 |  474   EXPECT_TRUE(CheckStateChangedCalled(true)); | 
 |  475   syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 12, "test_payload"); | 
 |  476  | 
 |  477   // Make sure client info is set as soon as the invalidation is received. | 
 |  478   EXPECT_TRUE(CheckInvalidationInfo(12, "test_payload")); | 
 |  479   EXPECT_TRUE(CheckInvalidateCalled(false /* unknown_version */)); | 
 |  480  | 
 |  481   // Make sure invalidation is not acknowledged until the store is loaded. | 
 |  482   EXPECT_FALSE(IsInvalidationAcknowledged(ack)); | 
 |  483   EXPECT_TRUE(CheckInvalidationInfo(12, "test_payload")); | 
 |  484   StorePolicy(POLICY_OBJECT_A, 12); | 
 |  485   EXPECT_TRUE(IsInvalidationAcknowledged(ack)); | 
 |  486   EXPECT_TRUE(CheckInvalidationInfo(0, std::string())); | 
 |  487 } | 
 |  488  | 
 |  489 TEST_F(CloudPolicyInvalidatorTest, HandleInvalidationWithUnknownVersion) { | 
 |  490   // Register and fire invalidation with unknown version. | 
 |  491   StorePolicy(POLICY_OBJECT_A); | 
 |  492   StartInvalidator(); | 
 |  493   syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A); | 
 |  494  | 
 |  495   // Make sure client info is not set until after the invalidation callback is | 
 |  496   // made. | 
 |  497   EXPECT_TRUE(CheckInvalidationInfo(0, std::string())); | 
 |  498   EXPECT_TRUE(CheckInvalidateCalled()); | 
 |  499   EXPECT_TRUE(CheckInvalidationInfo(-1, std::string())); | 
 |  500  | 
 |  501   // Make sure invalidation is not acknowledged until the store is loaded. | 
 |  502   EXPECT_FALSE(IsInvalidationAcknowledged(ack)); | 
 |  503   StorePolicy(POLICY_OBJECT_A, -1); | 
 |  504   EXPECT_TRUE(IsInvalidationAcknowledged(ack)); | 
 |  505   EXPECT_TRUE(CheckInvalidationInfo(0, std::string())); | 
 |  506 } | 
 |  507  | 
 |  508 TEST_F(CloudPolicyInvalidatorTest, HandleMultipleInvalidations) { | 
 |  509   // Generate multiple invalidations. | 
 |  510   StorePolicy(POLICY_OBJECT_A); | 
 |  511   StartInvalidator(); | 
 |  512   syncer::AckHandle ack1 = FireInvalidation(POLICY_OBJECT_A, 1, "test1"); | 
 |  513   EXPECT_TRUE(CheckInvalidationInfo(1, "test1")); | 
 |  514   syncer::AckHandle ack2 = FireInvalidation(POLICY_OBJECT_A, 2, "test2"); | 
 |  515   EXPECT_TRUE(CheckInvalidationInfo(2, "test2")); | 
 |  516   syncer::AckHandle ack3= FireInvalidation(POLICY_OBJECT_A, 3, "test3"); | 
 |  517   EXPECT_TRUE(CheckInvalidationInfo(3, "test3")); | 
 |  518  | 
 |  519   // Make sure the replaced invalidations are acknowledged. | 
 |  520   EXPECT_TRUE(IsInvalidationAcknowledged(ack1)); | 
 |  521   EXPECT_TRUE(IsInvalidationAcknowledged(ack2)); | 
 |  522  | 
 |  523   // Make sure the invalidate callback is called once. | 
 |  524   EXPECT_TRUE(CheckInvalidateCalled(false /* unknown_version */)); | 
 |  525  | 
 |  526   // Make sure that the last invalidation is only acknowledged after the store | 
 |  527   // is loaded with the latest version. | 
 |  528   StorePolicy(POLICY_OBJECT_A, 1); | 
 |  529   EXPECT_FALSE(IsInvalidationAcknowledged(ack3)); | 
 |  530   StorePolicy(POLICY_OBJECT_A, 2); | 
 |  531   EXPECT_FALSE(IsInvalidationAcknowledged(ack3)); | 
 |  532   StorePolicy(POLICY_OBJECT_A, 3); | 
 |  533   EXPECT_TRUE(IsInvalidationAcknowledged(ack3)); | 
 |  534 } | 
 |  535  | 
 |  536 TEST_F(CloudPolicyInvalidatorTest, | 
 |  537        HandleMultipleInvalidationsWithUnknownVersion) { | 
 |  538   // Validate that multiple invalidations with unknown version each generate | 
 |  539   // unique invalidation version numbers. | 
 |  540   StorePolicy(POLICY_OBJECT_A); | 
 |  541   StartInvalidator(); | 
 |  542   syncer::AckHandle ack1 = FireInvalidation(POLICY_OBJECT_A); | 
 |  543   EXPECT_TRUE(CheckInvalidationInfo(0, std::string())); | 
 |  544   EXPECT_TRUE(CheckInvalidateCalled()); | 
 |  545   EXPECT_TRUE(CheckInvalidationInfo(-1, std::string())); | 
 |  546   syncer::AckHandle ack2 = FireInvalidation(POLICY_OBJECT_A); | 
 |  547   EXPECT_TRUE(CheckInvalidationInfo(0, std::string())); | 
 |  548   EXPECT_TRUE(CheckInvalidateCalled()); | 
 |  549   EXPECT_TRUE(CheckInvalidationInfo(-2, std::string())); | 
 |  550   syncer::AckHandle ack3 = FireInvalidation(POLICY_OBJECT_A); | 
 |  551   EXPECT_TRUE(CheckInvalidationInfo(0, std::string())); | 
 |  552   EXPECT_TRUE(CheckInvalidateCalled()); | 
 |  553   EXPECT_TRUE(CheckInvalidationInfo(-3, std::string())); | 
 |  554  | 
 |  555   // Make sure the replaced invalidations are acknowledged. | 
 |  556   EXPECT_TRUE(IsInvalidationAcknowledged(ack1)); | 
 |  557   EXPECT_TRUE(IsInvalidationAcknowledged(ack2)); | 
 |  558  | 
 |  559   // Make sure that the last invalidation is only acknowledged after the store | 
 |  560   // is loaded with the last unknown version. | 
 |  561   StorePolicy(POLICY_OBJECT_A, -1); | 
 |  562   EXPECT_FALSE(IsInvalidationAcknowledged(ack3)); | 
 |  563   StorePolicy(POLICY_OBJECT_A, -2); | 
 |  564   EXPECT_FALSE(IsInvalidationAcknowledged(ack3)); | 
 |  565   StorePolicy(POLICY_OBJECT_A, -3); | 
 |  566   EXPECT_TRUE(IsInvalidationAcknowledged(ack3)); | 
 |  567 } | 
 |  568  | 
 |  569 TEST_F(CloudPolicyInvalidatorTest, AcknowledgeBeforeInvalidateCallback) { | 
 |  570   // Generate an invalidation. | 
 |  571   StorePolicy(POLICY_OBJECT_A); | 
 |  572   StartInvalidator(); | 
 |  573   syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 3, "test"); | 
 |  574  | 
 |  575   // Ensure that the invalidate callback is not made and the invalidation is | 
 |  576   // acknowledged if the store is loaded with the latest version before the | 
 |  577   // callback is invoked. | 
 |  578   StorePolicy(POLICY_OBJECT_A, 3); | 
 |  579   EXPECT_TRUE(IsInvalidationAcknowledged(ack)); | 
 |  580   EXPECT_TRUE(CheckInvalidateNotCalled()); | 
 |  581 } | 
 |  582  | 
 |  583 TEST_F(CloudPolicyInvalidatorTest, StateChanged) { | 
 |  584   // Before registration, changes to the invalidation service state should not | 
 |  585   // generate change state notifications. | 
 |  586   StartInvalidator(); | 
 |  587   DisableInvalidationService(); | 
 |  588   EnableInvalidationService(); | 
 |  589   EXPECT_TRUE(CheckStateChangedNotCalled()); | 
 |  590  | 
 |  591   // After registration, changes to the invalidation service state should | 
 |  592   // generate notifications. | 
 |  593   StorePolicy(POLICY_OBJECT_A); | 
 |  594   EXPECT_TRUE(CheckStateChangedCalled(true)); | 
 |  595   DisableInvalidationService(); | 
 |  596   EXPECT_TRUE(CheckStateChangedCalled(false)); | 
 |  597   DisableInvalidationService(); | 
 |  598   EXPECT_TRUE(CheckStateChangedNotCalled()); | 
 |  599   EnableInvalidationService(); | 
 |  600   EXPECT_TRUE(CheckStateChangedCalled(true)); | 
 |  601   EnableInvalidationService(); | 
 |  602   EXPECT_TRUE(CheckStateChangedNotCalled()); | 
 |  603  | 
 |  604   // When the invalidation service is enabled, changes to the registration | 
 |  605   // state should generate notifications. | 
 |  606   StorePolicy(POLICY_OBJECT_NONE); | 
 |  607   EXPECT_TRUE(CheckStateChangedCalled(false)); | 
 |  608   StorePolicy(POLICY_OBJECT_NONE); | 
 |  609   EXPECT_TRUE(CheckStateChangedNotCalled()); | 
 |  610   StorePolicy(POLICY_OBJECT_A); | 
 |  611   EXPECT_TRUE(CheckStateChangedCalled(true)); | 
 |  612   StorePolicy(POLICY_OBJECT_A); | 
 |  613   EXPECT_TRUE(CheckStateChangedNotCalled()); | 
 |  614  | 
 |  615   // When the invalidation service is disabled, changes to the registration | 
 |  616   // state should not generate notifications. | 
 |  617   DisableInvalidationService(); | 
 |  618   EXPECT_TRUE(CheckStateChangedCalled(false)); | 
 |  619   StorePolicy(POLICY_OBJECT_NONE); | 
 |  620   StorePolicy(POLICY_OBJECT_A); | 
 |  621   EXPECT_TRUE(CheckStateChangedNotCalled()); | 
 |  622 } | 
 |  623  | 
 |  624 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsUnregistered) { | 
 |  625   // Store loads occurring before invalidation registration are not counted. | 
 |  626   StartInvalidator(); | 
 |  627   StorePolicy(POLICY_OBJECT_NONE, 0, false /* policy_changed */); | 
 |  628   StorePolicy(POLICY_OBJECT_NONE, 0, true /* policy_changed */); | 
 |  629   EXPECT_EQ(0, GetCount(kMetricPolicyRefreshChanged)); | 
 |  630   EXPECT_EQ(0, GetCount(kMetricPolicyRefreshChangedNoInvalidations)); | 
 |  631   EXPECT_EQ(0, GetCount(kMetricPolicyRefreshUnchanged)); | 
 |  632   EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedChanged)); | 
 |  633   EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedUnchanged)); | 
 |  634 } | 
 |  635  | 
 |  636 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsNoInvalidations) { | 
 |  637   // Store loads occurring while registered should be differentiated depending | 
 |  638   // on whether the invalidation service was enabled or not. | 
 |  639   StorePolicy(POLICY_OBJECT_A); | 
 |  640   StartInvalidator(); | 
 |  641   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | 
 |  642   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | 
 |  643   DisableInvalidationService(); | 
 |  644   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | 
 |  645   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | 
 |  646   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | 
 |  647   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | 
 |  648   EXPECT_EQ(1, GetCount(kMetricPolicyRefreshChanged)); | 
 |  649   EXPECT_EQ(2, GetCount(kMetricPolicyRefreshChangedNoInvalidations)); | 
 |  650   EXPECT_EQ(3, GetCount(kMetricPolicyRefreshUnchanged)); | 
 |  651   EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedChanged)); | 
 |  652   EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedUnchanged)); | 
 |  653 } | 
 |  654  | 
 |  655 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsStoreSameTimestamp) { | 
 |  656   // Store loads with the same timestamp as the load which causes registration | 
 |  657   // are not counted. | 
 |  658   StartInvalidator(); | 
 |  659   StorePolicy( | 
 |  660       POLICY_OBJECT_A, 0, false /* policy_changed */, 12 /* timestamp */); | 
 |  661   StorePolicy( | 
 |  662       POLICY_OBJECT_A, 0, false /* policy_changed */, 12 /* timestamp */); | 
 |  663   StorePolicy( | 
 |  664       POLICY_OBJECT_A, 0, true /* policy_changed */, 12 /* timestamp */); | 
 |  665  | 
 |  666   // The next load with a different timestamp counts. | 
 |  667   StorePolicy( | 
 |  668       POLICY_OBJECT_A, 0, true /* policy_changed */, 13 /* timestamp */); | 
 |  669  | 
 |  670   EXPECT_EQ(1, GetCount(kMetricPolicyRefreshChanged)); | 
 |  671   EXPECT_EQ(0, GetCount(kMetricPolicyRefreshChangedNoInvalidations)); | 
 |  672   EXPECT_EQ(0, GetCount(kMetricPolicyRefreshUnchanged)); | 
 |  673   EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedChanged)); | 
 |  674   EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedUnchanged)); | 
 |  675 } | 
 |  676  | 
 |  677 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsInvalidation) { | 
 |  678   // Store loads after an invalidation are counted as invalidated, even if | 
 |  679   // the loads do not result in the invalidation being acknowledged. | 
 |  680   StartInvalidator(); | 
 |  681   StorePolicy(POLICY_OBJECT_A); | 
 |  682   FireInvalidation(POLICY_OBJECT_A, 5, "test"); | 
 |  683   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | 
 |  684   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | 
 |  685   StorePolicy(POLICY_OBJECT_A, 5, true /* policy_changed */); | 
 |  686  | 
 |  687   // Store loads after the invalidation is complete are not counted as | 
 |  688   // invalidated. | 
 |  689   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | 
 |  690   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | 
 |  691   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | 
 |  692   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | 
 |  693   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | 
 |  694   StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | 
 |  695   StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | 
 |  696  | 
 |  697   EXPECT_EQ(3, GetCount(kMetricPolicyRefreshChanged)); | 
 |  698   EXPECT_EQ(0, GetCount(kMetricPolicyRefreshChangedNoInvalidations)); | 
 |  699   EXPECT_EQ(4, GetCount(kMetricPolicyRefreshUnchanged)); | 
 |  700   EXPECT_EQ(2, GetCount(kMetricPolicyRefreshInvalidatedChanged)); | 
 |  701   EXPECT_EQ(1, GetCount(kMetricPolicyRefreshInvalidatedUnchanged)); | 
 |  702 } | 
 |  703  | 
 |  704 TEST_F(CloudPolicyInvalidatorTest, InvalidationMetrics) { | 
 |  705   // Generate a mix of versioned and unknown-version invalidations. | 
 |  706   StorePolicy(POLICY_OBJECT_A); | 
 |  707   StartInvalidator(); | 
 |  708   FireInvalidation(POLICY_OBJECT_B); | 
 |  709   FireInvalidation(POLICY_OBJECT_A); | 
 |  710   FireInvalidation(POLICY_OBJECT_B, 1, "test"); | 
 |  711   FireInvalidation(POLICY_OBJECT_A, 1, "test"); | 
 |  712   FireInvalidation(POLICY_OBJECT_A, 2, "test"); | 
 |  713   FireInvalidation(POLICY_OBJECT_A); | 
 |  714   FireInvalidation(POLICY_OBJECT_A); | 
 |  715   FireInvalidation(POLICY_OBJECT_A, 3, "test"); | 
 |  716   FireInvalidation(POLICY_OBJECT_A, 4, "test"); | 
 |  717  | 
 |  718   // Verify that received invalidations metrics are correct. | 
 |  719   EXPECT_EQ(3, GetCount(kMetricPolicyInvalidationsNoPayload)); | 
 |  720   EXPECT_EQ(4, GetCount(kMetricPolicyInvalidationsPayload)); | 
 |  721 } | 
 |  722  | 
 |  723 }  // namespace policy | 
| OLD | NEW |