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