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