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