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