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