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/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"
38 class CloudPolicyInvalidatorTest : public testing::Test {
40 // Policy objects which can be used in tests.
47 CloudPolicyInvalidatorTest();
49 virtual void SetUp() OVERRIDE;
51 virtual void TearDown() OVERRIDE;
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 */);
61 // Calls Initialize on the invalidator.
62 void InitializeInvalidator();
64 // Calls Shutdown on the invalidator. Test must call DestroyInvalidator
65 // afterwards to prevent Shutdown from being called twice.
66 void ShutdownInvalidator();
68 // Destroys the invalidator.
69 void DestroyInvalidator();
71 // Connects the cloud policy core.
74 // Starts the refresh scheduler.
75 void StartRefreshScheduler();
77 // Disconnects the cloud policy core.
78 void DisconnectCore();
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.
89 int64 invalidation_version,
91 const base::Time& time);
94 int64 invalidation_version,
95 bool policy_changed) {
99 Now() - base::TimeDelta::FromMinutes(5));
101 void StorePolicy(PolicyObject object, int64 invalidation_version) {
102 StorePolicy(object, invalidation_version, false);
104 void StorePolicy(PolicyObject object) {
105 StorePolicy(object, 0);
108 // Disables the invalidation service. It is enabled by default.
109 void DisableInvalidationService();
111 // Enables the invalidation service. It is enabled by default.
112 void EnableInvalidationService();
114 // Causes the invalidation service to fire an invalidation.
115 syncer::Invalidation FireInvalidation(
118 const std::string& payload);
120 // Causes the invalidation service to fire an invalidation with unknown
122 syncer::Invalidation FireUnknownVersionInvalidation(PolicyObject object);
124 // Checks the expected value of the currently set invalidation info.
125 bool CheckInvalidationInfo(int64 version, const std::string& payload);
127 // Checks that the policy was not refreshed due to an invalidation.
128 bool CheckPolicyNotRefreshed();
130 // Checks that the policy was refreshed due to an invalidation within an
131 // appropriate timeframe depending on whether the invalidation had unknown
133 bool CheckPolicyRefreshed();
134 bool CheckPolicyRefreshedWithUnknownVersion();
136 bool IsUnsent(const syncer::Invalidation& invalidation);
138 // Returns the invalidations enabled state set by the invalidator on the
139 // refresh scheduler.
140 bool InvalidationsEnabled();
142 // Determines if the invalidation with the given ack handle has been
144 bool IsInvalidationAcknowledged(const syncer::Invalidation& invalidation);
146 // Determines if the invalidator has registered for an object with the
147 // invalidation service.
148 bool IsInvalidatorRegistered();
150 // Get the current count for the given metric.
151 base::HistogramBase::Count GetCount(MetricPolicyRefresh metric);
152 base::HistogramBase::Count GetInvalidationCount(PolicyInvalidationType type);
154 // Advance the test clock.
155 void AdvanceClock(base::TimeDelta delta);
157 // Get the current time on the test clock.
160 // Translate a version number into an appropriate invalidation version (which
161 // is based on the current time).
162 int64 V(int version);
164 // Get an invalidation version for the given time.
165 int64 GetVersion(base::Time time);
168 // Checks that the policy was refreshed due to an invalidation with the given
170 bool CheckPolicyRefreshed(base::TimeDelta delay);
172 // Checks that the policy was refreshed the given number of times.
173 bool CheckPolicyRefreshCount(int count);
175 // Returns the object id of the given policy object.
176 const invalidation::ObjectId& GetPolicyObjectId(PolicyObject object) const;
178 // Get histogram samples for the given histogram.
179 scoped_ptr<base::HistogramSamples> GetHistogramSamples(
180 const std::string& name) const;
182 base::MessageLoop loop_;
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_;
192 // The invalidator which will be tested.
193 scoped_ptr<CloudPolicyInvalidator> invalidator_;
195 // Object ids for the test policy objects.
196 invalidation::ObjectId object_id_a_;
197 invalidation::ObjectId object_id_b_;
199 // Fake policy values which are alternated to cause the store to report a
201 const char* policy_value_a_;
202 const char* policy_value_b_;
204 // The currently used policy value.
205 const char* policy_value_cur_;
207 // Stores starting histogram counts for kMetricPolicyRefresh.
208 scoped_ptr<base::HistogramSamples> refresh_samples_;
210 // Stores starting histogram counts for kMetricPolicyInvalidations.
211 scoped_ptr<base::HistogramSamples> invalidations_samples_;
214 CloudPolicyInvalidatorTest::CloudPolicyInvalidatorTest()
215 : core_(PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType,
218 loop_.message_loop_proxy()),
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_) {
228 base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(987654321));
231 void CloudPolicyInvalidatorTest::SetUp() {
232 base::StatisticsRecorder::Initialize();
233 refresh_samples_ = GetHistogramSamples(kMetricPolicyRefresh);
234 invalidations_samples_ = GetHistogramSamples(kMetricPolicyInvalidations);
237 void CloudPolicyInvalidatorTest::TearDown() {
239 invalidator_->Shutdown();
243 void CloudPolicyInvalidatorTest::StartInvalidator(
245 bool start_refresh_scheduler) {
246 invalidator_.reset(new CloudPolicyInvalidator(
249 scoped_ptr<base::Clock>(clock_)));
250 if (start_refresh_scheduler) {
252 StartRefreshScheduler();
255 InitializeInvalidator();
258 void CloudPolicyInvalidatorTest::InitializeInvalidator() {
259 invalidator_->Initialize(&invalidation_service_);
262 void CloudPolicyInvalidatorTest::ShutdownInvalidator() {
263 invalidator_->Shutdown();
266 void CloudPolicyInvalidatorTest::DestroyInvalidator() {
267 invalidator_.reset();
270 void CloudPolicyInvalidatorTest::ConnectCore() {
271 client_ = new MockCloudPolicyClient();
272 client_->SetDMToken("dm");
273 core_.Connect(scoped_ptr<CloudPolicyClient>(client_));
276 void CloudPolicyInvalidatorTest::StartRefreshScheduler() {
277 core_.StartRefreshScheduler();
280 void CloudPolicyInvalidatorTest::DisconnectCore() {
285 void CloudPolicyInvalidatorTest::StorePolicy(
287 int64 invalidation_version,
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());
296 data->set_timestamp((time - base::Time::UnixEpoch()).InMilliseconds());
297 // Swap the policy value if a policy change is desired.
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;
306 key::kMaxInvalidationFetchDelay,
307 CloudPolicyInvalidator::kMaxFetchDelayMin);
308 store_.policy_map_.LoadFrom(
310 POLICY_LEVEL_MANDATORY,
311 POLICY_SCOPE_MACHINE);
312 store_.NotifyStoreLoaded();
315 void CloudPolicyInvalidatorTest::DisableInvalidationService() {
316 invalidation_service_.SetInvalidatorState(
317 syncer::TRANSIENT_INVALIDATION_ERROR);
320 void CloudPolicyInvalidatorTest::EnableInvalidationService() {
321 invalidation_service_.SetInvalidatorState(syncer::INVALIDATIONS_ENABLED);
324 syncer::Invalidation CloudPolicyInvalidatorTest::FireInvalidation(
327 const std::string& payload) {
328 syncer::Invalidation invalidation = syncer::Invalidation::Init(
329 GetPolicyObjectId(object),
332 invalidation_service_.EmitInvalidationForTest(invalidation);
336 syncer::Invalidation CloudPolicyInvalidatorTest::FireUnknownVersionInvalidation(
337 PolicyObject object) {
338 syncer::Invalidation invalidation = syncer::Invalidation::InitUnknownVersion(
339 GetPolicyObjectId(object));
340 invalidation_service_.EmitInvalidationForTest(invalidation);
344 bool CloudPolicyInvalidatorTest::CheckInvalidationInfo(
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_;
353 bool CloudPolicyInvalidatorTest::CheckPolicyNotRefreshed() {
354 return CheckPolicyRefreshCount(0);
357 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshed() {
358 return CheckPolicyRefreshed(base::TimeDelta());
361 bool CloudPolicyInvalidatorTest::IsUnsent(
362 const syncer::Invalidation& invalidation) {
363 return invalidation_service_.GetMockAckHandler()->IsUnsent(invalidation);
366 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshedWithUnknownVersion() {
367 return CheckPolicyRefreshed(base::TimeDelta::FromMinutes(
368 CloudPolicyInvalidator::kMissingPayloadDelay));
371 bool CloudPolicyInvalidatorTest::InvalidationsEnabled() {
372 return core_.refresh_scheduler()->invalidations_available();
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();
382 EXPECT_FALSE(IsUnsent(invalidation));
383 return !invalidation_service_.GetMockAckHandler()->IsUnacked(invalidation);
386 bool CloudPolicyInvalidatorTest::IsInvalidatorRegistered() {
387 return !invalidation_service_.invalidator_registrar()
388 .GetRegisteredIds(invalidator_.get()).empty();
391 base::HistogramBase::Count CloudPolicyInvalidatorTest::GetCount(
392 MetricPolicyRefresh metric) {
393 return GetHistogramSamples(kMetricPolicyRefresh)->GetCount(metric) -
394 refresh_samples_->GetCount(metric);
397 base::HistogramBase::Count CloudPolicyInvalidatorTest::GetInvalidationCount(
398 PolicyInvalidationType type) {
399 return GetHistogramSamples(kMetricPolicyInvalidations)->GetCount(type) -
400 invalidations_samples_->GetCount(type);
403 void CloudPolicyInvalidatorTest::AdvanceClock(base::TimeDelta delta) {
404 clock_->Advance(delta);
407 base::Time CloudPolicyInvalidatorTest::Now() {
408 return clock_->Now();
411 int64 CloudPolicyInvalidatorTest::V(int version) {
412 return GetVersion(Now()) + version;
415 int64 CloudPolicyInvalidatorTest::GetVersion(base::Time time) {
416 return (time - base::Time::UnixEpoch()).InMicroseconds();
419 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshed(base::TimeDelta delay) {
420 base::TimeDelta max_delay = delay + base::TimeDelta::FromMilliseconds(
421 CloudPolicyInvalidator::kMaxFetchDelayMin);
423 if (task_runner_->GetPendingTasks().empty())
425 base::TimeDelta actual_delay = task_runner_->GetPendingTasks().back().delay;
426 EXPECT_GE(actual_delay, delay);
427 EXPECT_LE(actual_delay, max_delay);
429 return CheckPolicyRefreshCount(1);
432 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshCount(int count) {
434 task_runner_->RunUntilIdle();
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_);
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_);
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_;
456 scoped_ptr<base::HistogramSamples>
457 CloudPolicyInvalidatorTest::GetHistogramSamples(
458 const std::string& name) const {
459 base::HistogramBase* histogram =
460 base::StatisticsRecorder::FindHistogram(name);
462 return scoped_ptr<base::HistogramSamples>(new base::SampleMap());
463 return histogram->SnapshotSamples();
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());
475 TEST_F(CloudPolicyInvalidatorTest, RefreshSchedulerNotStarted) {
476 // No invalidations should be processed if the refresh scheduler is not
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());
485 TEST_F(CloudPolicyInvalidatorTest, DisconnectCoreThenInitialize) {
486 // No invalidations should be processed if the core is disconnected before
488 StartInvalidator(false /* initialize */, true /* start_refresh_scheduler */);
490 InitializeInvalidator();
491 StorePolicy(POLICY_OBJECT_A);
492 EXPECT_FALSE(IsInvalidatorRegistered());
493 EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_A)));
494 EXPECT_TRUE(CheckPolicyNotRefreshed());
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
503 StartInvalidator(true /* initialize */, false /* start_refresh_scheduler */);
505 StartRefreshScheduler();
506 StorePolicy(POLICY_OBJECT_A);
507 EXPECT_TRUE(IsInvalidatorRegistered());
508 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
509 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
512 TEST_F(CloudPolicyInvalidatorTest, RegisterOnStoreLoaded) {
513 // No registration when store is not loaded.
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());
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());
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());
539 TEST_F(CloudPolicyInvalidatorTest, ChangeRegistration) {
540 // Register for object A.
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);
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());
559 // Make sure future invalidations for object A are ignored and for object B
561 EXPECT_TRUE(IsUnsent(FireUnknownVersionInvalidation(POLICY_OBJECT_A)));
562 EXPECT_TRUE(CheckPolicyNotRefreshed());
563 FireUnknownVersionInvalidation(POLICY_OBJECT_B);
564 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
567 TEST_F(CloudPolicyInvalidatorTest, UnregisterOnStoreLoaded) {
568 // Register for object A.
570 StorePolicy(POLICY_OBJECT_A);
571 EXPECT_TRUE(IsInvalidatorRegistered());
572 EXPECT_TRUE(InvalidationsEnabled());
573 FireUnknownVersionInvalidation(POLICY_OBJECT_A);
574 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
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());
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());
595 TEST_F(CloudPolicyInvalidatorTest, HandleInvalidation) {
596 // Register and fire invalidation
597 StorePolicy(POLICY_OBJECT_A);
599 EXPECT_TRUE(InvalidationsEnabled());
600 syncer::Invalidation inv =
601 FireInvalidation(POLICY_OBJECT_A, V(12), "test_payload");
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());
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()));
615 TEST_F(CloudPolicyInvalidatorTest, HandleInvalidationWithUnknownVersion) {
616 // Register and fire invalidation with unknown version.
617 StorePolicy(POLICY_OBJECT_A);
619 syncer::Invalidation inv = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
621 // Make sure client info is not set until after the invalidation callback is
623 EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
624 EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
625 EXPECT_TRUE(CheckInvalidationInfo(-1, std::string()));
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()));
634 TEST_F(CloudPolicyInvalidatorTest, HandleMultipleInvalidations) {
635 // Generate multiple invalidations.
636 StorePolicy(POLICY_OBJECT_A);
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"));
645 // Make sure the replaced invalidations are acknowledged.
646 EXPECT_TRUE(IsInvalidationAcknowledged(inv1));
647 EXPECT_TRUE(IsInvalidationAcknowledged(inv2));
649 // Make sure the policy is refreshed once.
650 EXPECT_TRUE(CheckPolicyRefreshed());
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));
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);
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()));
681 // Make sure the replaced invalidations are acknowledged.
682 EXPECT_TRUE(IsInvalidationAcknowledged(inv1));
683 EXPECT_TRUE(IsInvalidationAcknowledged(inv2));
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));
695 TEST_F(CloudPolicyInvalidatorTest, AcknowledgeBeforeRefresh) {
696 // Generate an invalidation.
697 StorePolicy(POLICY_OBJECT_A);
699 syncer::Invalidation inv = FireInvalidation(POLICY_OBJECT_A, V(3), "test");
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());
709 TEST_F(CloudPolicyInvalidatorTest, NoCallbackAfterShutdown) {
710 // Generate an invalidation.
711 StorePolicy(POLICY_OBJECT_A);
713 syncer::Invalidation inv = FireInvalidation(POLICY_OBJECT_A, V(3), "test");
715 // Ensure that the policy refresh is not made after the invalidator is shut
717 ShutdownInvalidator();
718 EXPECT_TRUE(CheckPolicyNotRefreshed());
719 DestroyInvalidator();
722 TEST_F(CloudPolicyInvalidatorTest, StateChanged) {
723 // Test invalidation service state changes while not registered.
725 DisableInvalidationService();
726 EnableInvalidationService();
727 EXPECT_FALSE(InvalidationsEnabled());
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());
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());
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());
759 TEST_F(CloudPolicyInvalidatorTest, Disconnect) {
760 // Generate an invalidation.
761 StorePolicy(POLICY_OBJECT_A);
763 syncer::Invalidation inv = FireInvalidation(POLICY_OBJECT_A, V(1), "test");
764 EXPECT_TRUE(InvalidationsEnabled());
766 // Ensure that the policy is not refreshed after disconnecting the core, but
767 // a call to indicate that invalidations are disabled is made.
769 EXPECT_TRUE(CheckPolicyNotRefreshed());
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();
778 // Connect and disconnect without starting the refresh scheduler.
780 EXPECT_TRUE(IsUnsent(FireInvalidation(POLICY_OBJECT_A, V(3), "test")));
781 EXPECT_TRUE(CheckPolicyNotRefreshed());
783 EXPECT_TRUE(IsUnsent(FireInvalidation(POLICY_OBJECT_A, V(4), "test")));
784 EXPECT_TRUE(CheckPolicyNotRefreshed());
786 // Ensure that the invalidator returns to normal after reconnecting.
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());
798 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsUnregistered) {
799 // Store loads occurring before invalidation registration are not counted.
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));
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);
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));
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));
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));
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));
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));
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 */);
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));
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.
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 */);
873 // Store loads after the invalidation is complete are not counted as
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 */);
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));
890 TEST_F(CloudPolicyInvalidatorTest, ExpiredInvalidations) {
891 StorePolicy(POLICY_OBJECT_A, 0, false, Now());
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());
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());
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());
914 time += base::TimeDelta::FromMinutes(10);
915 inv = FireInvalidation(POLICY_OBJECT_A, GetVersion(time), "test");
916 ASSERT_FALSE(IsInvalidationAcknowledged(inv));
917 ASSERT_TRUE(CheckPolicyRefreshed());
919 time += base::TimeDelta::FromMinutes(10);
920 inv = FireInvalidation(POLICY_OBJECT_A, GetVersion(time), "test");
921 ASSERT_FALSE(IsInvalidationAcknowledged(inv));
922 ASSERT_TRUE(CheckPolicyRefreshed());
924 // Unknown version invalidations fired just after the last fetch time should
926 inv = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
927 ASSERT_TRUE(IsInvalidationAcknowledged(inv));
928 ASSERT_TRUE(CheckPolicyNotRefreshed());
930 AdvanceClock(base::TimeDelta::FromSeconds(
931 CloudPolicyInvalidator::kUnknownVersionIgnorePeriod - 1));
932 inv = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
933 ASSERT_TRUE(IsInvalidationAcknowledged(inv));
934 ASSERT_TRUE(CheckPolicyNotRefreshed());
936 // Unknown version invalidations fired past the ignore period should not be
938 AdvanceClock(base::TimeDelta::FromSeconds(1));
939 inv = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
940 ASSERT_FALSE(IsInvalidationAcknowledged(inv));
941 ASSERT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
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));
947 GetInvalidationCount(POLICY_INVALIDATION_TYPE_NO_PAYLOAD_EXPIRED));
948 EXPECT_EQ(2, GetInvalidationCount(POLICY_INVALIDATION_TYPE_EXPIRED));
951 } // namespace policy