cloud_policy_invalidator_unittest.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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
36namespace policy {
37
38class 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
214CloudPolicyInvalidatorTest::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
231void CloudPolicyInvalidatorTest::SetUp() {
232  base::StatisticsRecorder::Initialize();
233  refresh_samples_ = GetHistogramSamples(kMetricPolicyRefresh);
234  invalidations_samples_ = GetHistogramSamples(kMetricPolicyInvalidations);
235}
236
237void CloudPolicyInvalidatorTest::TearDown() {
238  if (invalidator_)
239    invalidator_->Shutdown();
240  core_.Disconnect();
241}
242
243void 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
258void CloudPolicyInvalidatorTest::InitializeInvalidator() {
259  invalidator_->Initialize(&invalidation_service_);
260}
261
262void CloudPolicyInvalidatorTest::ShutdownInvalidator() {
263  invalidator_->Shutdown();
264}
265
266void CloudPolicyInvalidatorTest::DestroyInvalidator() {
267  invalidator_.reset();
268}
269
270void CloudPolicyInvalidatorTest::ConnectCore() {
271  client_ = new MockCloudPolicyClient();
272  client_->SetDMToken("dm");
273  core_.Connect(scoped_ptr<CloudPolicyClient>(client_));
274}
275
276void CloudPolicyInvalidatorTest::StartRefreshScheduler() {
277  core_.StartRefreshScheduler();
278}
279
280void CloudPolicyInvalidatorTest::DisconnectCore() {
281  client_ = NULL;
282  core_.Disconnect();
283}
284
285void 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
315void CloudPolicyInvalidatorTest::DisableInvalidationService() {
316  invalidation_service_.SetInvalidatorState(
317      syncer::TRANSIENT_INVALIDATION_ERROR);
318}
319
320void CloudPolicyInvalidatorTest::EnableInvalidationService() {
321  invalidation_service_.SetInvalidatorState(syncer::INVALIDATIONS_ENABLED);
322}
323
324syncer::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
336syncer::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
344bool 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
353bool CloudPolicyInvalidatorTest::CheckPolicyNotRefreshed() {
354  return CheckPolicyRefreshCount(0);
355}
356
357bool CloudPolicyInvalidatorTest::CheckPolicyRefreshed() {
358  return CheckPolicyRefreshed(base::TimeDelta());
359}
360
361bool CloudPolicyInvalidatorTest::IsUnsent(
362    const syncer::Invalidation& invalidation) {
363  return invalidation_service_.GetMockAckHandler()->IsUnsent(invalidation);
364}
365
366bool CloudPolicyInvalidatorTest::CheckPolicyRefreshedWithUnknownVersion() {
367  return CheckPolicyRefreshed(base::TimeDelta::FromMinutes(
368        CloudPolicyInvalidator::kMissingPayloadDelay));
369}
370
371bool CloudPolicyInvalidatorTest::InvalidationsEnabled() {
372  return core_.refresh_scheduler()->invalidations_available();
373}
374
375bool 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
386bool CloudPolicyInvalidatorTest::IsInvalidatorRegistered() {
387  return !invalidation_service_.invalidator_registrar()
388      .GetRegisteredIds(invalidator_.get()).empty();
389}
390
391base::HistogramBase::Count CloudPolicyInvalidatorTest::GetCount(
392    MetricPolicyRefresh metric) {
393  return GetHistogramSamples(kMetricPolicyRefresh)->GetCount(metric) -
394      refresh_samples_->GetCount(metric);
395}
396
397base::HistogramBase::Count CloudPolicyInvalidatorTest::GetInvalidationCount(
398    PolicyInvalidationType type) {
399  return GetHistogramSamples(kMetricPolicyInvalidations)->GetCount(type) -
400      invalidations_samples_->GetCount(type);
401}
402
403void CloudPolicyInvalidatorTest::AdvanceClock(base::TimeDelta delta) {
404  clock_->Advance(delta);
405}
406
407base::Time CloudPolicyInvalidatorTest::Now() {
408  return clock_->Now();
409}
410
411int64 CloudPolicyInvalidatorTest::V(int version) {
412  return GetVersion(Now()) + version;
413}
414
415int64 CloudPolicyInvalidatorTest::GetVersion(base::Time time) {
416  return (time - base::Time::UnixEpoch()).InMicroseconds();
417}
418
419bool 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
432bool 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
450const 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
456scoped_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
466TEST_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
475TEST_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
485TEST_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
497TEST_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
512TEST_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
539TEST_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
567TEST_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
595TEST_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
615TEST_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
634TEST_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
662TEST_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
695TEST_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
709TEST_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
722TEST_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
759TEST_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
798TEST_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
810TEST_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
861TEST_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
890TEST_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
952