- add sources.
[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/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"
34
35 namespace policy {
36
37 class CloudPolicyInvalidatorTest : public testing::Test {
38  protected:
39   // Policy objects which can be used in tests.
40   enum PolicyObject {
41     POLICY_OBJECT_NONE,
42     POLICY_OBJECT_A,
43     POLICY_OBJECT_B
44   };
45
46   CloudPolicyInvalidatorTest();
47
48   virtual void SetUp() OVERRIDE;
49
50   virtual void TearDown() OVERRIDE;
51
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 */);
58   }
59
60   // Calls Initialize on the invalidator.
61   void InitializeInvalidator();
62
63   // Calls Shutdown on the invalidator. Test must call DestroyInvalidator
64   // afterwards to prevent Shutdown from being called twice.
65   void ShutdownInvalidator();
66
67   // Destroys the invalidator.
68   void DestroyInvalidator();
69
70   // Connects the cloud policy core.
71   void ConnectCore();
72
73   // Starts the refresh scheduler.
74   void StartRefreshScheduler();
75
76   // Disconnects the cloud policy core.
77   void DisconnectCore();
78
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.
86   void StorePolicy(
87       PolicyObject object,
88       int64 invalidation_version,
89       bool policy_changed,
90       int64 timestamp);
91   void StorePolicy(
92       PolicyObject object,
93       int64 invalidation_version,
94       bool policy_changed) {
95     StorePolicy(object, invalidation_version, policy_changed, ++timestamp_);
96   }
97   void StorePolicy(PolicyObject object, int64 invalidation_version) {
98     StorePolicy(object, invalidation_version, false);
99   }
100   void StorePolicy(PolicyObject object) {
101     StorePolicy(object, 0);
102   }
103
104   // Disables the invalidation service. It is enabled by default.
105   void DisableInvalidationService();
106
107   // Enables the invalidation service. It is enabled by default.
108   void EnableInvalidationService();
109
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(
113       PolicyObject object,
114       int64 version,
115       const std::string& payload);
116
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);
121
122   // Checks the expected value of the currently set invalidation info.
123   bool CheckInvalidationInfo(int64 version, const std::string& payload);
124
125   // Checks that the policy was not refreshed due to an invalidation.
126   bool CheckPolicyNotRefreshed();
127
128   // Checks that the policy was refreshed due to an invalidation within an
129   // appropriate timeframe depending on whether the invalidation had unknown
130   // version.
131   bool CheckPolicyRefreshed();
132   bool CheckPolicyRefreshedWithUnknownVersion();
133
134   // Returns the invalidations enabled state set by the invalidator on the
135   // refresh scheduler.
136   bool InvalidationsEnabled();
137
138   // Determines if the invalidation with the given ack handle has been
139   // acknowledged.
140   bool IsInvalidationAcknowledged(const syncer::AckHandle& ack_handle);
141
142   // Determines if the invalidator has registered for an object with the
143   // invalidation service.
144   bool IsInvalidatorRegistered();
145
146   // Get the current count for the given metric.
147   base::HistogramBase::Count GetCount(MetricPolicyRefresh metric);
148   base::HistogramBase::Count GetInvalidationCount(bool with_payload);
149
150  private:
151   // Checks that the policy was refreshed due to an invalidation with the given
152   // base delay.
153   bool CheckPolicyRefreshed(base::TimeDelta delay);
154
155   // Checks that the policy was refreshed the given number of times.
156   bool CheckPolicyRefreshCount(int count);
157
158   // Returns the object id of the given policy object.
159   const invalidation::ObjectId& GetPolicyObjectId(PolicyObject object) const;
160
161   // Get histogram samples for the given histogram.
162   scoped_ptr<base::HistogramSamples> GetHistogramSamples(
163       const std::string& name) const;
164
165   base::MessageLoop loop_;
166
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_;
173
174   // The invalidator which will be tested.
175   scoped_ptr<CloudPolicyInvalidator> invalidator_;
176
177   // Object ids for the test policy objects.
178   invalidation::ObjectId object_id_a_;
179   invalidation::ObjectId object_id_b_;
180
181   // Increasing policy timestamp.
182   int64 timestamp_;
183
184   // Fake policy values which are alternated to cause the store to report a
185   // changed policy.
186   const char* policy_value_a_;
187   const char* policy_value_b_;
188
189   // The currently used policy value.
190   const char* policy_value_cur_;
191
192   // Stores starting histogram counts for kMetricPolicyRefresh.
193   scoped_ptr<base::HistogramSamples> refresh_samples_;
194
195   // Stores starting histogram counts for kMetricPolicyInvalidations.
196   scoped_ptr<base::HistogramSamples> invalidations_samples_;
197 };
198
199 CloudPolicyInvalidatorTest::CloudPolicyInvalidatorTest()
200     : core_(PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType,
201                                std::string()),
202             &store_,
203             loop_.message_loop_proxy()),
204       client_(NULL),
205       task_runner_(new base::TestSimpleTaskRunner()),
206       object_id_a_(135, "asdf"),
207       object_id_b_(246, "zxcv"),
208       timestamp_(123456),
209       policy_value_a_("asdf"),
210       policy_value_b_("zxcv"),
211       policy_value_cur_(policy_value_a_) {}
212
213 void CloudPolicyInvalidatorTest::SetUp() {
214   base::StatisticsRecorder::Initialize();
215   refresh_samples_ = GetHistogramSamples(kMetricPolicyRefresh);
216   invalidations_samples_ = GetHistogramSamples(kMetricPolicyInvalidations);
217 }
218
219 void CloudPolicyInvalidatorTest::TearDown() {
220   EXPECT_FALSE(invalidation_service_.ReceivedInvalidAcknowledgement());
221   if (invalidator_)
222     invalidator_->Shutdown();
223   core_.Disconnect();
224 }
225
226 void CloudPolicyInvalidatorTest::StartInvalidator(
227     bool initialize,
228     bool start_refresh_scheduler) {
229   invalidator_.reset(new CloudPolicyInvalidator(&core_, task_runner_));
230   if (start_refresh_scheduler) {
231     ConnectCore();
232     StartRefreshScheduler();
233   }
234   if (initialize)
235     InitializeInvalidator();
236 }
237
238 void CloudPolicyInvalidatorTest::InitializeInvalidator() {
239   invalidator_->Initialize(&invalidation_service_);
240 }
241
242 void CloudPolicyInvalidatorTest::ShutdownInvalidator() {
243   invalidator_->Shutdown();
244 }
245
246 void CloudPolicyInvalidatorTest::DestroyInvalidator() {
247   invalidator_.reset();
248 }
249
250 void CloudPolicyInvalidatorTest::ConnectCore() {
251   client_ = new MockCloudPolicyClient();
252   client_->SetDMToken("dm");
253   core_.Connect(scoped_ptr<CloudPolicyClient>(client_));
254 }
255
256 void CloudPolicyInvalidatorTest::StartRefreshScheduler() {
257   core_.StartRefreshScheduler();
258 }
259
260 void CloudPolicyInvalidatorTest::DisconnectCore() {
261   client_ = NULL;
262   core_.Disconnect();
263 }
264
265 void CloudPolicyInvalidatorTest::StorePolicy(
266     PolicyObject object,
267     int64 invalidation_version,
268     bool policy_changed,
269     int64 timestamp) {
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());
275   }
276   data->set_timestamp(timestamp);
277   // Swap the policy value if a policy change is desired.
278   if (policy_changed)
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;
285   policies.SetInteger(
286       key::kMaxInvalidationFetchDelay,
287       CloudPolicyInvalidator::kMaxFetchDelayMin);
288   store_.policy_map_.LoadFrom(
289       &policies,
290       POLICY_LEVEL_MANDATORY,
291       POLICY_SCOPE_MACHINE);
292   store_.NotifyStoreLoaded();
293 }
294
295 void CloudPolicyInvalidatorTest::DisableInvalidationService() {
296   invalidation_service_.SetInvalidatorState(
297       syncer::TRANSIENT_INVALIDATION_ERROR);
298 }
299
300 void CloudPolicyInvalidatorTest::EnableInvalidationService() {
301   invalidation_service_.SetInvalidatorState(syncer::INVALIDATIONS_ENABLED);
302 }
303
304 syncer::AckHandle CloudPolicyInvalidatorTest::FireInvalidation(
305     PolicyObject object,
306     int64 version,
307     const std::string& payload) {
308   syncer::Invalidation invalidation = syncer::Invalidation::Init(
309       GetPolicyObjectId(object),
310       version,
311       payload);
312   invalidation_service_.EmitInvalidationForTest(invalidation);
313   return invalidation.ack_handle();
314 }
315
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();
322 }
323
324 bool CloudPolicyInvalidatorTest::CheckInvalidationInfo(
325     int64 version,
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_;
331 }
332
333 bool CloudPolicyInvalidatorTest::CheckPolicyNotRefreshed() {
334   return CheckPolicyRefreshCount(0);
335 }
336
337 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshed() {
338   return CheckPolicyRefreshed(base::TimeDelta());
339 }
340
341 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshedWithUnknownVersion() {
342   return CheckPolicyRefreshed(base::TimeDelta::FromMinutes(
343         CloudPolicyInvalidator::kMissingPayloadDelay));
344 }
345
346 bool CloudPolicyInvalidatorTest::InvalidationsEnabled() {
347   return core_.refresh_scheduler()->invalidations_available();
348 }
349
350 bool CloudPolicyInvalidatorTest::IsInvalidationAcknowledged(
351     const syncer::AckHandle& ack_handle) {
352   return invalidation_service_.IsInvalidationAcknowledged(ack_handle);
353 }
354
355 bool CloudPolicyInvalidatorTest::IsInvalidatorRegistered() {
356   return !invalidation_service_.invalidator_registrar()
357       .GetRegisteredIds(invalidator_.get()).empty();
358 }
359
360 base::HistogramBase::Count CloudPolicyInvalidatorTest::GetCount(
361     MetricPolicyRefresh metric) {
362   return GetHistogramSamples(kMetricPolicyRefresh)->GetCount(metric) -
363       refresh_samples_->GetCount(metric);
364 }
365
366 base::HistogramBase::Count CloudPolicyInvalidatorTest::GetInvalidationCount(
367     bool with_payload) {
368   int metric = with_payload ? 1 : 0;
369   return GetHistogramSamples(kMetricPolicyInvalidations)->GetCount(metric) -
370       invalidations_samples_->GetCount(metric);
371 }
372
373 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshed(base::TimeDelta delay) {
374   base::TimeDelta max_delay = delay + base::TimeDelta::FromMilliseconds(
375       CloudPolicyInvalidator::kMaxFetchDelayMin);
376
377   if (task_runner_->GetPendingTasks().empty())
378     return false;
379   base::TimeDelta actual_delay = task_runner_->GetPendingTasks().back().delay;
380   EXPECT_GE(actual_delay, delay);
381   EXPECT_LE(actual_delay, max_delay);
382
383   return CheckPolicyRefreshCount(1);
384 }
385
386 bool CloudPolicyInvalidatorTest::CheckPolicyRefreshCount(int count) {
387   if (!client_) {
388     task_runner_->RunUntilIdle();
389     return count == 0;
390   }
391
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_);
396
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_);
402 }
403
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_;
408 }
409
410 scoped_ptr<base::HistogramSamples>
411     CloudPolicyInvalidatorTest::GetHistogramSamples(
412         const std::string& name) const {
413   base::HistogramBase* histogram =
414       base::StatisticsRecorder::FindHistogram(name);
415   if (!histogram)
416     return scoped_ptr<base::HistogramSamples>(new base::SampleMap());
417   return histogram->SnapshotSamples();
418 }
419
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());
427 }
428
429 TEST_F(CloudPolicyInvalidatorTest, RefreshSchedulerNotStarted) {
430   // No invalidations should be processed if the refresh scheduler is not
431   // started.
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());
437 }
438
439 TEST_F(CloudPolicyInvalidatorTest, DisconnectCoreThenInitialize) {
440   // No invalidations should be processed if the core is disconnected before
441   // initialization.
442   StartInvalidator(false /* initialize */, true /* start_refresh_scheduler */);
443   DisconnectCore();
444   InitializeInvalidator();
445   StorePolicy(POLICY_OBJECT_A);
446   EXPECT_FALSE(IsInvalidatorRegistered());
447   FireUnknownVersionInvalidation(POLICY_OBJECT_A);
448   EXPECT_TRUE(CheckPolicyNotRefreshed());
449 }
450
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
456   // tests.
457   StartInvalidator(true /* initialize */, false /* start_refresh_scheduler */);
458   ConnectCore();
459   StartRefreshScheduler();
460   StorePolicy(POLICY_OBJECT_A);
461   EXPECT_TRUE(IsInvalidatorRegistered());
462   FireUnknownVersionInvalidation(POLICY_OBJECT_A);
463   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
464 }
465
466 TEST_F(CloudPolicyInvalidatorTest, RegisterOnStoreLoaded) {
467   // No registration when store is not loaded.
468   StartInvalidator();
469   EXPECT_FALSE(IsInvalidatorRegistered());
470   EXPECT_FALSE(InvalidationsEnabled());
471   FireUnknownVersionInvalidation(POLICY_OBJECT_A);
472   FireUnknownVersionInvalidation(POLICY_OBJECT_B);
473   EXPECT_TRUE(CheckPolicyNotRefreshed());
474
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());
482
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());
491 }
492
493 TEST_F(CloudPolicyInvalidatorTest, ChangeRegistration) {
494   // Register for object A.
495   StartInvalidator();
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);
504
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());
512
513   // Make sure future invalidations for object A are ignored and for object B
514   // are processed.
515   FireUnknownVersionInvalidation(POLICY_OBJECT_A);
516   EXPECT_TRUE(CheckPolicyNotRefreshed());
517   FireUnknownVersionInvalidation(POLICY_OBJECT_B);
518   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
519 }
520
521 TEST_F(CloudPolicyInvalidatorTest, UnregisterOnStoreLoaded) {
522   // Register for object A.
523   StartInvalidator();
524   StorePolicy(POLICY_OBJECT_A);
525   EXPECT_TRUE(IsInvalidatorRegistered());
526   EXPECT_TRUE(InvalidationsEnabled());
527   FireUnknownVersionInvalidation(POLICY_OBJECT_A);
528   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
529
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());
540
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());
547 }
548
549 TEST_F(CloudPolicyInvalidatorTest, HandleInvalidation) {
550   // Register and fire invalidation
551   StorePolicy(POLICY_OBJECT_A);
552   StartInvalidator();
553   EXPECT_TRUE(InvalidationsEnabled());
554   syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 12, "test_payload");
555
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());
559
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()));
566 }
567
568 TEST_F(CloudPolicyInvalidatorTest, HandleInvalidationWithUnknownVersion) {
569   // Register and fire invalidation with unknown version.
570   StorePolicy(POLICY_OBJECT_A);
571   StartInvalidator();
572   syncer::AckHandle ack = FireUnknownVersionInvalidation(POLICY_OBJECT_A);
573
574   // Make sure client info is not set until after the invalidation callback is
575   // made.
576   EXPECT_TRUE(CheckInvalidationInfo(0, std::string()));
577   EXPECT_TRUE(CheckPolicyRefreshedWithUnknownVersion());
578   EXPECT_TRUE(CheckInvalidationInfo(-1, std::string()));
579
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()));
585 }
586
587 TEST_F(CloudPolicyInvalidatorTest, HandleMultipleInvalidations) {
588   // Generate multiple invalidations.
589   StorePolicy(POLICY_OBJECT_A);
590   StartInvalidator();
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"));
597
598   // Make sure the replaced invalidations are acknowledged.
599   EXPECT_TRUE(IsInvalidationAcknowledged(ack1));
600   EXPECT_TRUE(IsInvalidationAcknowledged(ack2));
601
602   // Make sure the policy is refreshed once.
603   EXPECT_TRUE(CheckPolicyRefreshed());
604
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));
613 }
614
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);
620   StartInvalidator();
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()));
633
634   // Make sure the replaced invalidations are acknowledged.
635   EXPECT_TRUE(IsInvalidationAcknowledged(ack1));
636   EXPECT_TRUE(IsInvalidationAcknowledged(ack2));
637
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));
646 }
647
648 TEST_F(CloudPolicyInvalidatorTest, AcknowledgeBeforeRefresh) {
649   // Generate an invalidation.
650   StorePolicy(POLICY_OBJECT_A);
651   StartInvalidator();
652   syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 3, "test");
653
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());
660 }
661
662 TEST_F(CloudPolicyInvalidatorTest, NoCallbackAfterShutdown) {
663   // Generate an invalidation.
664   StorePolicy(POLICY_OBJECT_A);
665   StartInvalidator();
666   syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 3, "test");
667
668   // Ensure that the policy refresh is not made after the invalidator is shut
669   // down.
670   ShutdownInvalidator();
671   EXPECT_TRUE(CheckPolicyNotRefreshed());
672   DestroyInvalidator();
673 }
674
675 TEST_F(CloudPolicyInvalidatorTest, StateChanged) {
676   // Test invalidation service state changes while not registered.
677   StartInvalidator();
678   DisableInvalidationService();
679   EnableInvalidationService();
680   EXPECT_FALSE(InvalidationsEnabled());
681
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());
693
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());
703
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());
710 }
711
712 TEST_F(CloudPolicyInvalidatorTest, Disconnect) {
713   // Generate an invalidation.
714   StorePolicy(POLICY_OBJECT_A);
715   StartInvalidator();
716   syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 1, "test");
717   EXPECT_TRUE(InvalidationsEnabled());
718
719   // Ensure that the policy is not refreshed after disconnecting the core, but
720   // a call to indicate that invalidations are disabled is made.
721   DisconnectCore();
722   EXPECT_TRUE(CheckPolicyNotRefreshed());
723
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();
730
731   // Connect and disconnect without starting the refresh scheduler.
732   ConnectCore();
733   FireInvalidation(POLICY_OBJECT_A, 3, "test");
734   EXPECT_TRUE(CheckPolicyNotRefreshed());
735   DisconnectCore();
736   FireInvalidation(POLICY_OBJECT_A, 4, "test");
737   EXPECT_TRUE(CheckPolicyNotRefreshed());
738
739   // Ensure that the invalidator returns to normal after reconnecting.
740   ConnectCore();
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());
749 }
750
751 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsUnregistered) {
752   // Store loads occurring before invalidation registration are not counted.
753   StartInvalidator();
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));
761 }
762
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);
767   StartInvalidator();
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));
780 }
781
782 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsStoreSameTimestamp) {
783   // Store loads with the same timestamp as the load which causes registration
784   // are not counted.
785   StartInvalidator();
786   StorePolicy(
787       POLICY_OBJECT_A, 0, false /* policy_changed */, 12 /* timestamp */);
788   StorePolicy(
789       POLICY_OBJECT_A, 0, false /* policy_changed */, 12 /* timestamp */);
790   StorePolicy(
791       POLICY_OBJECT_A, 0, true /* policy_changed */, 12 /* timestamp */);
792
793   // The next load with a different timestamp counts.
794   StorePolicy(
795       POLICY_OBJECT_A, 0, true /* policy_changed */, 13 /* timestamp */);
796
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));
802 }
803
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.
807   StartInvalidator();
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 */);
813
814   // Store loads after the invalidation is complete are not counted as
815   // invalidated.
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 */);
823
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));
829 }
830
831 TEST_F(CloudPolicyInvalidatorTest, InvalidationMetrics) {
832   // Generate a mix of versioned and unknown-version invalidations.
833   StorePolicy(POLICY_OBJECT_A);
834   StartInvalidator();
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");
844
845   // Verify that received invalidations metrics are correct.
846   EXPECT_EQ(3, GetInvalidationCount(false /* with_payload */));
847   EXPECT_EQ(4, GetInvalidationCount(true /* with_payload */));
848 }
849
850 }  // namespace policy