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.
7 #include "base/basictypes.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"
37 class CloudPolicyInvalidatorTest : public testing::Test {
39 // Policy objects which can be used in tests.
46 CloudPolicyInvalidatorTest();
48 virtual void SetUp() OVERRIDE;
50 virtual void TearDown() OVERRIDE;
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 */);
60 // Calls Initialize on the invalidator.
61 void InitializeInvalidator();
63 // Calls Shutdown on the invalidator. Test must call DestroyInvalidator
64 // afterwards to prevent Shutdown from being called twice.
65 void ShutdownInvalidator();
67 // Destroys the invalidator.
68 void DestroyInvalidator();
70 // Connects the cloud policy core.
73 // Starts the refresh scheduler.
74 void StartRefreshScheduler();
76 // Disconnects the cloud policy core.
77 void DisconnectCore();
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.
88 int64 invalidation_version,
93 int64 invalidation_version,
94 bool policy_changed) {
95 StorePolicy(object, invalidation_version, policy_changed, ++timestamp_);
97 void StorePolicy(PolicyObject object, int64 invalidation_version) {
98 StorePolicy(object, invalidation_version, false);
100 void StorePolicy(PolicyObject object) {
101 StorePolicy(object, 0);
104 // Disables the invalidation service. It is enabled by default.
105 void DisableInvalidationService();
107 // Enables the invalidation service. It is enabled by default.
108 void EnableInvalidationService();
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(
115 const std::string& payload);
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 FireUnknownVersionInvalidation(PolicyObject object);
122 // Checks the expected value of the currently set invalidation info.
123 bool CheckInvalidationInfo(int64 version, const std::string& payload);
125 // Checks that the policy was not refreshed due to an invalidation.
126 bool CheckPolicyNotRefreshed();
128 // Checks that the policy was refreshed due to an invalidation within an
129 // appropriate timeframe depending on whether the invalidation had unknown
131 bool CheckPolicyRefreshed();
132 bool CheckPolicyRefreshedWithUnknownVersion();
134 // Returns the invalidations enabled state set by the invalidator on the
135 // refresh scheduler.
136 bool InvalidationsEnabled();
138 // Determines if the invalidation with the given ack handle has been
140 bool IsInvalidationAcknowledged(const syncer::AckHandle& ack_handle);
142 // Determines if the invalidator has registered for an object with the
143 // invalidation service.
144 bool IsInvalidatorRegistered();
146 // Get the current count for the given metric.
147 base::HistogramBase::Count GetCount(MetricPolicyRefresh metric);
148 base::HistogramBase::Count GetInvalidationCount(bool with_payload);
151 // Checks that the policy was refreshed due to an invalidation with the given
153 bool CheckPolicyRefreshed(base::TimeDelta delay);
155 // Checks that the policy was refreshed the given number of times.
156 bool CheckPolicyRefreshCount(int count);
158 // Returns the object id of the given policy object.
159 const invalidation::ObjectId& GetPolicyObjectId(PolicyObject object) const;
161 // Get histogram samples for the given histogram.
162 scoped_ptr<base::HistogramSamples> GetHistogramSamples(
163 const std::string& name) const;
165 base::MessageLoop loop_;
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_;
174 // The invalidator which will be tested.
175 scoped_ptr<CloudPolicyInvalidator> invalidator_;
177 // Object ids for the test policy objects.
178 invalidation::ObjectId object_id_a_;
179 invalidation::ObjectId object_id_b_;
181 // Increasing policy timestamp.
184 // Fake policy values which are alternated to cause the store to report a
186 const char* policy_value_a_;
187 const char* policy_value_b_;
189 // The currently used policy value.
190 const char* policy_value_cur_;
192 // Stores starting histogram counts for kMetricPolicyRefresh.
193 scoped_ptr<base::HistogramSamples> refresh_samples_;
195 // Stores starting histogram counts for kMetricPolicyInvalidations.
196 scoped_ptr<base::HistogramSamples> invalidations_samples_;
199 CloudPolicyInvalidatorTest::CloudPolicyInvalidatorTest()
200 : core_(PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType,
203 loop_.message_loop_proxy()),
205 task_runner_(new base::TestSimpleTaskRunner()),
206 object_id_a_(135, "asdf"),
207 object_id_b_(246, "zxcv"),
209 policy_value_a_("asdf"),
210 policy_value_b_("zxcv"),
211 policy_value_cur_(policy_value_a_) {}
213 void CloudPolicyInvalidatorTest::SetUp() {
214 base::StatisticsRecorder::Initialize();
215 refresh_samples_ = GetHistogramSamples(kMetricPolicyRefresh);
216 invalidations_samples_ = GetHistogramSamples(kMetricPolicyInvalidations);
219 void CloudPolicyInvalidatorTest::TearDown() {
220 EXPECT_FALSE(invalidation_service_.ReceivedInvalidAcknowledgement());
222 invalidator_->Shutdown();
226 void CloudPolicyInvalidatorTest::StartInvalidator(
228 bool start_refresh_scheduler) {
229 invalidator_.reset(new CloudPolicyInvalidator(&core_, task_runner_));
230 if (start_refresh_scheduler) {
232 StartRefreshScheduler();
235 InitializeInvalidator();
238 void CloudPolicyInvalidatorTest::InitializeInvalidator() {
239 invalidator_->Initialize(&invalidation_service_);
242 void CloudPolicyInvalidatorTest::ShutdownInvalidator() {
243 invalidator_->Shutdown();
246 void CloudPolicyInvalidatorTest::DestroyInvalidator() {
247 invalidator_.reset();
250 void CloudPolicyInvalidatorTest::ConnectCore() {
251 client_ = new MockCloudPolicyClient();
252 client_->SetDMToken("dm");
253 core_.Connect(scoped_ptr<CloudPolicyClient>(client_));
256 void CloudPolicyInvalidatorTest::StartRefreshScheduler() {
257 core_.StartRefreshScheduler();
260 void CloudPolicyInvalidatorTest::DisconnectCore() {
265 void CloudPolicyInvalidatorTest::StorePolicy(
267 int64 invalidation_version,
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());
276 data->set_timestamp(timestamp);
277 // Swap the policy value if a policy change is desired.
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;
286 key::kMaxInvalidationFetchDelay,
287 CloudPolicyInvalidator::kMaxFetchDelayMin);
288 store_.policy_map_.LoadFrom(
290 POLICY_LEVEL_MANDATORY,
291 POLICY_SCOPE_MACHINE);
292 store_.NotifyStoreLoaded();
295 void CloudPolicyInvalidatorTest::DisableInvalidationService() {
296 invalidation_service_.SetInvalidatorState(
297 syncer::TRANSIENT_INVALIDATION_ERROR);
300 void CloudPolicyInvalidatorTest::EnableInvalidationService() {
301 invalidation_service_.SetInvalidatorState(syncer::INVALIDATIONS_ENABLED);
304 syncer::AckHandle CloudPolicyInvalidatorTest::FireInvalidation(
307 const std::string& payload) {
308 syncer::Invalidation invalidation = syncer::Invalidation::Init(
309 GetPolicyObjectId(object),
312 invalidation_service_.EmitInvalidationForTest(invalidation);
313 return invalidation.ack_handle();
316 syncer::AckHandle CloudPolicyInvalidatorTest::FireUnknownVersionInvalidation(
317 PolicyObject object) {
318 syncer::Invalidation invalidation =
319 syncer::Invalidation::InitUnknownVersion(GetPolicyObjectId(object));
320 invalidation_service_.EmitInvalidationForTest(invalidation);
321 return invalidation.ack_handle();
324 bool CloudPolicyInvalidatorTest::CheckInvalidationInfo(
326 const std::string& payload) {
327 MockCloudPolicyClient* client =
328 static_cast<MockCloudPolicyClient*>(core_.client());
329 return version == client->invalidation_version_ &&
330 payload == client->invalidation_payload_;
333 bool CloudPolicyInvalidatorTest::CheckPolicyNotRefreshed() {
334 return CheckPolicyRefreshCount(0);
337 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshed() {
338 return CheckPolicyRefreshed(base::TimeDelta());
341 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshedWithUnknownVersion() {
342 return CheckPolicyRefreshed(base::TimeDelta::FromMinutes(
343 CloudPolicyInvalidator::kMissingPayloadDelay));
346 bool CloudPolicyInvalidatorTest::InvalidationsEnabled() {
347 return core_.refresh_scheduler()->invalidations_available();
350 bool CloudPolicyInvalidatorTest::IsInvalidationAcknowledged(
351 const syncer::AckHandle& ack_handle) {
352 return invalidation_service_.IsInvalidationAcknowledged(ack_handle);
355 bool CloudPolicyInvalidatorTest::IsInvalidatorRegistered() {
356 return !invalidation_service_.invalidator_registrar()
357 .GetRegisteredIds(invalidator_.get()).empty();
360 base::HistogramBase::Count CloudPolicyInvalidatorTest::GetCount(
361 MetricPolicyRefresh metric) {
362 return GetHistogramSamples(kMetricPolicyRefresh)->GetCount(metric) -
363 refresh_samples_->GetCount(metric);
366 base::HistogramBase::Count CloudPolicyInvalidatorTest::GetInvalidationCount(
368 int metric = with_payload ? 1 : 0;
369 return GetHistogramSamples(kMetricPolicyInvalidations)->GetCount(metric) -
370 invalidations_samples_->GetCount(metric);
373 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshed(base::TimeDelta delay) {
374 base::TimeDelta max_delay = delay + base::TimeDelta::FromMilliseconds(
375 CloudPolicyInvalidator::kMaxFetchDelayMin);
377 if (task_runner_->GetPendingTasks().empty())
379 base::TimeDelta actual_delay = task_runner_->GetPendingTasks().back().delay;
380 EXPECT_GE(actual_delay, delay);
381 EXPECT_LE(actual_delay, max_delay);
383 return CheckPolicyRefreshCount(1);
386 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshCount(int count) {
388 task_runner_->RunUntilIdle();
392 // Clear any non-invalidation refreshes which may be pending.
393 EXPECT_CALL(*client_, FetchPolicy()).Times(testing::AnyNumber());
394 base::RunLoop().RunUntilIdle();
395 testing::Mock::VerifyAndClearExpectations(client_);
397 // Run the invalidator tasks then check for invalidation refreshes.
398 EXPECT_CALL(*client_, FetchPolicy()).Times(count);
399 task_runner_->RunUntilIdle();
400 base::RunLoop().RunUntilIdle();
401 return testing::Mock::VerifyAndClearExpectations(client_);
404 const invalidation::ObjectId& CloudPolicyInvalidatorTest::GetPolicyObjectId(
405 PolicyObject object) const {
406 EXPECT_TRUE(object == POLICY_OBJECT_A || object == POLICY_OBJECT_B);
407 return object == POLICY_OBJECT_A ? object_id_a_ : object_id_b_;
410 scoped_ptr<base::HistogramSamples>
411 CloudPolicyInvalidatorTest::GetHistogramSamples(
412 const std::string& name) const {
413 base::HistogramBase* histogram =
414 base::StatisticsRecorder::FindHistogram(name);
416 return scoped_ptr<base::HistogramSamples>(new base::SampleMap());
417 return histogram->SnapshotSamples();
420 TEST_F(CloudPolicyInvalidatorTest, Uninitialized) {
421 // No invalidations should be processed if the invalidator is not initialized.
422 StartInvalidator(false /* initialize */, true /* start_refresh_scheduler */);
423 StorePolicy(POLICY_OBJECT_A);
424 EXPECT_FALSE(IsInvalidatorRegistered());
425 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
426 EXPECT_TRUE(CheckPolicyNotRefreshed());
429 TEST_F(CloudPolicyInvalidatorTest, RefreshSchedulerNotStarted) {
430 // No invalidations should be processed if the refresh scheduler is not
432 StartInvalidator(true /* initialize */, false /* start_refresh_scheduler */);
433 StorePolicy(POLICY_OBJECT_A);
434 EXPECT_FALSE(IsInvalidatorRegistered());
435 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
436 EXPECT_TRUE(CheckPolicyNotRefreshed());
439 TEST_F(CloudPolicyInvalidatorTest, DisconnectCoreThenInitialize) {
440 // No invalidations should be processed if the core is disconnected before
442 StartInvalidator(false /* initialize */, true /* start_refresh_scheduler */);
444 InitializeInvalidator();
445 StorePolicy(POLICY_OBJECT_A);
446 EXPECT_FALSE(IsInvalidatorRegistered());
447 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
448 EXPECT_TRUE(CheckPolicyNotRefreshed());
451 TEST_F(CloudPolicyInvalidatorTest, InitializeThenStartRefreshScheduler) {
452 // Make sure registration occurs and invalidations are processed when
453 // Initialize is called before starting the refresh scheduler.
454 // Note that the reverse case (start refresh scheduler then initialize) is
455 // the default behavior for the test fixture, so will be tested in most other
457 StartInvalidator(true /* initialize */, false /* start_refresh_scheduler */);
459 StartRefreshScheduler();
460 StorePolicy(POLICY_OBJECT_A);
461 EXPECT_TRUE(IsInvalidatorRegistered());
462 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
463 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
466 TEST_F(CloudPolicyInvalidatorTest, RegisterOnStoreLoaded) {
467 // No registration when store is not loaded.
469 EXPECT_FALSE(IsInvalidatorRegistered());
470 EXPECT_FALSE(InvalidationsEnabled());
471 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
472 FireUnknownVersionInvalidation(POLICY_OBJECT_B);
473 EXPECT_TRUE(CheckPolicyNotRefreshed());
475 // No registration when store is loaded with no invalidation object id.
476 StorePolicy(POLICY_OBJECT_NONE);
477 EXPECT_FALSE(IsInvalidatorRegistered());
478 EXPECT_FALSE(InvalidationsEnabled());
479 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
480 FireUnknownVersionInvalidation(POLICY_OBJECT_B);
481 EXPECT_TRUE(CheckPolicyNotRefreshed());
483 // Check registration when store is loaded for object A.
484 StorePolicy(POLICY_OBJECT_A);
485 EXPECT_TRUE(IsInvalidatorRegistered());
486 EXPECT_TRUE(InvalidationsEnabled());
487 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
488 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
489 FireUnknownVersionInvalidation(POLICY_OBJECT_B);
490 EXPECT_TRUE(CheckPolicyNotRefreshed());
493 TEST_F(CloudPolicyInvalidatorTest, ChangeRegistration) {
494 // Register for object A.
496 StorePolicy(POLICY_OBJECT_A);
497 EXPECT_TRUE(IsInvalidatorRegistered());
498 EXPECT_TRUE(InvalidationsEnabled());
499 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
500 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
501 FireUnknownVersionInvalidation(POLICY_OBJECT_B);
502 EXPECT_TRUE(CheckPolicyNotRefreshed());
503 syncer::AckHandle ack = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
505 // Check re-registration for object B. Make sure the pending invalidation for
506 // object A is acknowledged without making the callback.
507 StorePolicy(POLICY_OBJECT_B);
508 EXPECT_TRUE(IsInvalidatorRegistered());
509 EXPECT_TRUE(InvalidationsEnabled());
510 EXPECT_TRUE(IsInvalidationAcknowledged(ack));
511 EXPECT_TRUE(CheckPolicyNotRefreshed());
513 // Make sure future invalidations for object A are ignored and for object B
515 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
516 EXPECT_TRUE(CheckPolicyNotRefreshed());
517 FireUnknownVersionInvalidation(POLICY_OBJECT_B);
518 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
521 TEST_F(CloudPolicyInvalidatorTest, UnregisterOnStoreLoaded) {
522 // Register for object A.
524 StorePolicy(POLICY_OBJECT_A);
525 EXPECT_TRUE(IsInvalidatorRegistered());
526 EXPECT_TRUE(InvalidationsEnabled());
527 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
528 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
530 // Check unregistration when store is loaded with no invalidation object id.
531 syncer::AckHandle ack = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
532 EXPECT_FALSE(IsInvalidationAcknowledged(ack));
533 StorePolicy(POLICY_OBJECT_NONE);
534 EXPECT_FALSE(IsInvalidatorRegistered());
535 EXPECT_TRUE(IsInvalidationAcknowledged(ack));
536 EXPECT_FALSE(InvalidationsEnabled());
537 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
538 FireUnknownVersionInvalidation(POLICY_OBJECT_B);
539 EXPECT_TRUE(CheckPolicyNotRefreshed());
541 // Check re-registration for object B.
542 StorePolicy(POLICY_OBJECT_B);
543 EXPECT_TRUE(IsInvalidatorRegistered());
544 EXPECT_TRUE(InvalidationsEnabled());
545 FireUnknownVersionInvalidation(POLICY_OBJECT_B);
546 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
549 TEST_F(CloudPolicyInvalidatorTest, HandleInvalidation) {
550 // Register and fire invalidation
551 StorePolicy(POLICY_OBJECT_A);
553 EXPECT_TRUE(InvalidationsEnabled());
554 syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 12, "test_payload");
556 // Make sure client info is set as soon as the invalidation is received.
557 EXPECT_TRUE(CheckInvalidationInfo(12, "test_payload"));
558 EXPECT_TRUE(CheckPolicyRefreshed());
560 // Make sure invalidation is not acknowledged until the store is loaded.
561 EXPECT_FALSE(IsInvalidationAcknowledged(ack));
562 EXPECT_TRUE(CheckInvalidationInfo(12, "test_payload"));
563 StorePolicy(POLICY_OBJECT_A, 12);
564 EXPECT_TRUE(IsInvalidationAcknowledged(ack));
565 EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
568 TEST_F(CloudPolicyInvalidatorTest, HandleInvalidationWithUnknownVersion) {
569 // Register and fire invalidation with unknown version.
570 StorePolicy(POLICY_OBJECT_A);
572 syncer::AckHandle ack = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
574 // Make sure client info is not set until after the invalidation callback is
576 EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
577 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
578 EXPECT_TRUE(CheckInvalidationInfo(-1, std::string()));
580 // Make sure invalidation is not acknowledged until the store is loaded.
581 EXPECT_FALSE(IsInvalidationAcknowledged(ack));
582 StorePolicy(POLICY_OBJECT_A, -1);
583 EXPECT_TRUE(IsInvalidationAcknowledged(ack));
584 EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
587 TEST_F(CloudPolicyInvalidatorTest, HandleMultipleInvalidations) {
588 // Generate multiple invalidations.
589 StorePolicy(POLICY_OBJECT_A);
591 syncer::AckHandle ack1 = FireInvalidation(POLICY_OBJECT_A, 1, "test1");
592 EXPECT_TRUE(CheckInvalidationInfo(1, "test1"));
593 syncer::AckHandle ack2 = FireInvalidation(POLICY_OBJECT_A, 2, "test2");
594 EXPECT_TRUE(CheckInvalidationInfo(2, "test2"));
595 syncer::AckHandle ack3= FireInvalidation(POLICY_OBJECT_A, 3, "test3");
596 EXPECT_TRUE(CheckInvalidationInfo(3, "test3"));
598 // Make sure the replaced invalidations are acknowledged.
599 EXPECT_TRUE(IsInvalidationAcknowledged(ack1));
600 EXPECT_TRUE(IsInvalidationAcknowledged(ack2));
602 // Make sure the policy is refreshed once.
603 EXPECT_TRUE(CheckPolicyRefreshed());
605 // Make sure that the last invalidation is only acknowledged after the store
606 // is loaded with the latest version.
607 StorePolicy(POLICY_OBJECT_A, 1);
608 EXPECT_FALSE(IsInvalidationAcknowledged(ack3));
609 StorePolicy(POLICY_OBJECT_A, 2);
610 EXPECT_FALSE(IsInvalidationAcknowledged(ack3));
611 StorePolicy(POLICY_OBJECT_A, 3);
612 EXPECT_TRUE(IsInvalidationAcknowledged(ack3));
615 TEST_F(CloudPolicyInvalidatorTest,
616 HandleMultipleInvalidationsWithUnknownVersion) {
617 // Validate that multiple invalidations with unknown version each generate
618 // unique invalidation version numbers.
619 StorePolicy(POLICY_OBJECT_A);
621 syncer::AckHandle ack1 = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
622 EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
623 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
624 EXPECT_TRUE(CheckInvalidationInfo(-1, std::string()));
625 syncer::AckHandle ack2 = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
626 EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
627 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
628 EXPECT_TRUE(CheckInvalidationInfo(-2, std::string()));
629 syncer::AckHandle ack3 = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
630 EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
631 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
632 EXPECT_TRUE(CheckInvalidationInfo(-3, std::string()));
634 // Make sure the replaced invalidations are acknowledged.
635 EXPECT_TRUE(IsInvalidationAcknowledged(ack1));
636 EXPECT_TRUE(IsInvalidationAcknowledged(ack2));
638 // Make sure that the last invalidation is only acknowledged after the store
639 // is loaded with the last unknown version.
640 StorePolicy(POLICY_OBJECT_A, -1);
641 EXPECT_FALSE(IsInvalidationAcknowledged(ack3));
642 StorePolicy(POLICY_OBJECT_A, -2);
643 EXPECT_FALSE(IsInvalidationAcknowledged(ack3));
644 StorePolicy(POLICY_OBJECT_A, -3);
645 EXPECT_TRUE(IsInvalidationAcknowledged(ack3));
648 TEST_F(CloudPolicyInvalidatorTest, AcknowledgeBeforeRefresh) {
649 // Generate an invalidation.
650 StorePolicy(POLICY_OBJECT_A);
652 syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 3, "test");
654 // Ensure that the policy is not refreshed and the invalidation is
655 // acknowledged if the store is loaded with the latest version before the
656 // refresh can occur.
657 StorePolicy(POLICY_OBJECT_A, 3);
658 EXPECT_TRUE(IsInvalidationAcknowledged(ack));
659 EXPECT_TRUE(CheckPolicyNotRefreshed());
662 TEST_F(CloudPolicyInvalidatorTest, NoCallbackAfterShutdown) {
663 // Generate an invalidation.
664 StorePolicy(POLICY_OBJECT_A);
666 syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 3, "test");
668 // Ensure that the policy refresh is not made after the invalidator is shut
670 ShutdownInvalidator();
671 EXPECT_TRUE(CheckPolicyNotRefreshed());
672 DestroyInvalidator();
675 TEST_F(CloudPolicyInvalidatorTest, StateChanged) {
676 // Test invalidation service state changes while not registered.
678 DisableInvalidationService();
679 EnableInvalidationService();
680 EXPECT_FALSE(InvalidationsEnabled());
682 // Test invalidation service state changes while registered.
683 StorePolicy(POLICY_OBJECT_A);
684 EXPECT_TRUE(InvalidationsEnabled());
685 DisableInvalidationService();
686 EXPECT_FALSE(InvalidationsEnabled());
687 DisableInvalidationService();
688 EXPECT_FALSE(InvalidationsEnabled());
689 EnableInvalidationService();
690 EXPECT_TRUE(InvalidationsEnabled());
691 EnableInvalidationService();
692 EXPECT_TRUE(InvalidationsEnabled());
694 // Test registration changes with invalidation service enabled.
695 StorePolicy(POLICY_OBJECT_NONE);
696 EXPECT_FALSE(InvalidationsEnabled());
697 StorePolicy(POLICY_OBJECT_NONE);
698 EXPECT_FALSE(InvalidationsEnabled());
699 StorePolicy(POLICY_OBJECT_A);
700 EXPECT_TRUE(InvalidationsEnabled());
701 StorePolicy(POLICY_OBJECT_A);
702 EXPECT_TRUE(InvalidationsEnabled());
704 // Test registration changes with invalidation service disabled.
705 DisableInvalidationService();
706 EXPECT_FALSE(InvalidationsEnabled());
707 StorePolicy(POLICY_OBJECT_NONE);
708 StorePolicy(POLICY_OBJECT_A);
709 EXPECT_FALSE(InvalidationsEnabled());
712 TEST_F(CloudPolicyInvalidatorTest, Disconnect) {
713 // Generate an invalidation.
714 StorePolicy(POLICY_OBJECT_A);
716 syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 1, "test");
717 EXPECT_TRUE(InvalidationsEnabled());
719 // Ensure that the policy is not refreshed after disconnecting the core, but
720 // a call to indicate that invalidations are disabled is made.
722 EXPECT_TRUE(CheckPolicyNotRefreshed());
724 // Ensure that invalidation service events do not cause refreshes while the
725 // invalidator is stopped.
726 FireInvalidation(POLICY_OBJECT_A, 2, "test");
727 EXPECT_TRUE(CheckPolicyNotRefreshed());
728 DisableInvalidationService();
729 EnableInvalidationService();
731 // Connect and disconnect without starting the refresh scheduler.
733 FireInvalidation(POLICY_OBJECT_A, 3, "test");
734 EXPECT_TRUE(CheckPolicyNotRefreshed());
736 FireInvalidation(POLICY_OBJECT_A, 4, "test");
737 EXPECT_TRUE(CheckPolicyNotRefreshed());
739 // Ensure that the invalidator returns to normal after reconnecting.
741 StartRefreshScheduler();
742 EXPECT_TRUE(CheckPolicyNotRefreshed());
743 EXPECT_TRUE(InvalidationsEnabled());
744 FireInvalidation(POLICY_OBJECT_A, 5, "test");
745 EXPECT_TRUE(CheckInvalidationInfo(5, "test"));
746 EXPECT_TRUE(CheckPolicyRefreshed());
747 DisableInvalidationService();
748 EXPECT_FALSE(InvalidationsEnabled());
751 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsUnregistered) {
752 // Store loads occurring before invalidation registration are not counted.
754 StorePolicy(POLICY_OBJECT_NONE, 0, false /* policy_changed */);
755 StorePolicy(POLICY_OBJECT_NONE, 0, true /* policy_changed */);
756 EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_CHANGED));
757 EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS));
758 EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_UNCHANGED));
759 EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_CHANGED));
760 EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_UNCHANGED));
763 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsNoInvalidations) {
764 // Store loads occurring while registered should be differentiated depending
765 // on whether the invalidation service was enabled or not.
766 StorePolicy(POLICY_OBJECT_A);
768 StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
769 StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
770 DisableInvalidationService();
771 StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
772 StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
773 StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
774 StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
775 EXPECT_EQ(1, GetCount(METRIC_POLICY_REFRESH_CHANGED));
776 EXPECT_EQ(2, GetCount(METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS));
777 EXPECT_EQ(3, GetCount(METRIC_POLICY_REFRESH_UNCHANGED));
778 EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_CHANGED));
779 EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_UNCHANGED));
782 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsStoreSameTimestamp) {
783 // Store loads with the same timestamp as the load which causes registration
787 POLICY_OBJECT_A, 0, false /* policy_changed */, 12 /* timestamp */);
789 POLICY_OBJECT_A, 0, false /* policy_changed */, 12 /* timestamp */);
791 POLICY_OBJECT_A, 0, true /* policy_changed */, 12 /* timestamp */);
793 // The next load with a different timestamp counts.
795 POLICY_OBJECT_A, 0, true /* policy_changed */, 13 /* timestamp */);
797 EXPECT_EQ(1, GetCount(METRIC_POLICY_REFRESH_CHANGED));
798 EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS));
799 EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_UNCHANGED));
800 EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_CHANGED));
801 EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_UNCHANGED));
804 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsInvalidation) {
805 // Store loads after an invalidation are counted as invalidated, even if
806 // the loads do not result in the invalidation being acknowledged.
808 StorePolicy(POLICY_OBJECT_A);
809 FireInvalidation(POLICY_OBJECT_A, 5, "test");
810 StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
811 StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
812 StorePolicy(POLICY_OBJECT_A, 5, true /* policy_changed */);
814 // Store loads after the invalidation is complete are not counted as
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 StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
822 StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
824 EXPECT_EQ(3, GetCount(METRIC_POLICY_REFRESH_CHANGED));
825 EXPECT_EQ(0, GetCount(METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS));
826 EXPECT_EQ(4, GetCount(METRIC_POLICY_REFRESH_UNCHANGED));
827 EXPECT_EQ(2, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_CHANGED));
828 EXPECT_EQ(1, GetCount(METRIC_POLICY_REFRESH_INVALIDATED_UNCHANGED));
831 TEST_F(CloudPolicyInvalidatorTest, InvalidationMetrics) {
832 // Generate a mix of versioned and unknown-version invalidations.
833 StorePolicy(POLICY_OBJECT_A);
835 FireUnknownVersionInvalidation(POLICY_OBJECT_B);
836 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
837 FireInvalidation(POLICY_OBJECT_B, 1, "test");
838 FireInvalidation(POLICY_OBJECT_A, 1, "test");
839 FireInvalidation(POLICY_OBJECT_A, 2, "test");
840 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
841 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
842 FireInvalidation(POLICY_OBJECT_A, 3, "test");
843 FireInvalidation(POLICY_OBJECT_A, 4, "test");
845 // Verify that received invalidations metrics are correct.
846 EXPECT_EQ(3, GetInvalidationCount(false /* with_payload */));
847 EXPECT_EQ(4, GetInvalidationCount(true /* with_payload */));
850 } // namespace policy