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