OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 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/memory/ref_counted.h" | |
9 #include "base/memory/scoped_ptr.h" | |
10 #include "base/metrics/histogram.h" | |
11 #include "base/metrics/histogram_samples.h" | |
12 #include "base/metrics/sample_map.h" | |
13 #include "base/metrics/statistics_recorder.h" | |
14 #include "base/test/test_simple_task_runner.h" | |
15 #include "base/time/time.h" | |
16 #include "base/values.h" | |
17 #include "chrome/browser/invalidation/fake_invalidation_service.h" | |
18 #include "chrome/browser/policy/cloud/cloud_policy_core.h" | |
19 #include "chrome/browser/policy/cloud/cloud_policy_invalidator.h" | |
20 #include "chrome/browser/policy/cloud/cloud_policy_service.h" | |
21 #include "chrome/browser/policy/cloud/enterprise_metrics.h" | |
22 #include "chrome/browser/policy/cloud/mock_cloud_policy_client.h" | |
23 #include "chrome/browser/policy/cloud/mock_cloud_policy_store.h" | |
24 #include "chrome/browser/policy/policy_types.h" | |
25 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" | |
26 #include "policy/policy_constants.h" | |
27 #include "sync/notifier/invalidation_util.h" | |
28 #include "testing/gmock/include/gmock/gmock.h" | |
29 #include "testing/gtest/include/gtest/gtest.h" | |
30 | |
31 namespace policy { | |
32 | |
33 class CloudPolicyInvalidatorTest : public testing::Test, | |
34 public CloudPolicyInvalidationHandler { | |
35 protected: | |
36 // Policy objects which can be used in tests. | |
37 enum PolicyObject { | |
38 POLICY_OBJECT_NONE, | |
39 POLICY_OBJECT_A, | |
40 POLICY_OBJECT_B | |
41 }; | |
42 | |
43 CloudPolicyInvalidatorTest(); | |
44 | |
45 virtual void SetUp() OVERRIDE; | |
46 | |
47 virtual void TearDown() OVERRIDE; | |
48 | |
49 // Starts the invalidator which will be tested. | |
50 void StartInvalidator(); | |
51 | |
52 // Simulates storing a new policy to the policy store. | |
53 // |object| determines which policy object the store will report the | |
54 // invalidator should register for. May be POLICY_OBJECT_NONE for no object. | |
55 // |invalidation_version| determines what invalidation the store will report. | |
56 // |policy_changed| determines whether the store will report that the | |
57 // policy changed. | |
58 // |timestamp| determines the response timestamp the store will report. | |
59 void StorePolicy( | |
60 PolicyObject object, | |
61 int64 invalidation_version, | |
62 bool policy_changed, | |
63 int64 timestamp); | |
64 void StorePolicy( | |
65 PolicyObject object, | |
66 int64 invalidation_version, | |
67 bool policy_changed) { | |
68 StorePolicy(object, invalidation_version, policy_changed, ++timestamp_); | |
69 } | |
70 void StorePolicy(PolicyObject object, int64 invalidation_version) { | |
71 StorePolicy(object, invalidation_version, false); | |
72 } | |
73 void StorePolicy(PolicyObject object) { | |
74 StorePolicy(object, 0); | |
75 } | |
76 | |
77 // Disables the invalidation service. It is enabled by default. | |
78 void DisableInvalidationService(); | |
79 | |
80 // Enables the invalidation service. It is enabled by default. | |
81 void EnableInvalidationService(); | |
82 | |
83 // Causes the invalidation service to fire an invalidation. Returns an ack | |
84 // handle which be used to verify that the invalidation was acknowledged. | |
85 syncer::AckHandle FireInvalidation( | |
86 PolicyObject object, | |
87 int64 version, | |
88 const std::string& payload); | |
89 | |
90 // Causes the invalidation service to fire an invalidation with unknown | |
91 // version. Returns an ack handle which be used to verify that the | |
92 // invalidation was acknowledged. | |
93 syncer::AckHandle FireInvalidation(PolicyObject object); | |
94 | |
95 // Verifies expectations for the currently set invalidation info. | |
96 void ExpectInvalidationInfo(int64 version, const std::string& payload); | |
97 | |
98 // Verifies expectation that the invalidate callback was not called. | |
99 void ExpectInvalidateNotCalled(); | |
100 | |
101 // Verifies the expectation that the invalidate callback of the invalidation | |
102 // handler was called within an appropriate timeframe depending on whether the | |
103 // invalidation had unknown version. | |
104 void ExpectInvalidateCalled(bool unknown_version); | |
105 void ExpectInvalidateCalled() { | |
106 ExpectInvalidateCalled(true); | |
107 } | |
108 | |
109 // Verifies the expectation that the state changed callback of the | |
110 // invalidation handler was not called. | |
111 void ExpectStateChangedNotCalled(); | |
112 | |
113 // Verifies the expectation that the state changed callback of the | |
114 // invalidation handler was called with the given state. | |
115 void ExpectStateChangedCalled(bool invalidations_enabled); | |
116 | |
117 // Determines if the invalidation with the given ack handle has been | |
118 // acknowledged. | |
119 bool IsInvalidationAcknowledged(const syncer::AckHandle& ack_handle); | |
120 | |
121 // Get the current count for the given metric. | |
122 base::HistogramBase::Count GetCount(MetricPolicyRefresh metric); | |
123 base::HistogramBase::Count GetCount(MetricPolicyInvalidations metric); | |
124 | |
125 // CloudPolicyInvalidationHandler: | |
126 virtual void SetInvalidationInfo( | |
127 int64 version, | |
128 const std::string& payload) OVERRIDE; | |
129 virtual void InvalidatePolicy() OVERRIDE; | |
130 virtual void OnInvalidatorStateChanged(bool invalidations_enabled) OVERRIDE; | |
131 | |
132 private: | |
133 // Returns the object id of the given policy object. | |
134 const invalidation::ObjectId& GetPolicyObjectId(PolicyObject object) const; | |
135 | |
136 // Get histogram samples for the given histogram. | |
137 scoped_ptr<base::HistogramSamples> GetHistogramSamples( | |
138 const std::string& name) const; | |
139 | |
140 // Objects the invalidator depends on. | |
141 invalidation::FakeInvalidationService invalidation_service_; | |
142 MockCloudPolicyStore store_; | |
143 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | |
144 | |
145 // The invalidator which will be tested. | |
146 scoped_ptr<CloudPolicyInvalidator> invalidator_; | |
147 | |
148 // The latest invalidation info set by the invalidator. | |
149 int64 invalidation_version_; | |
150 std::string invalidation_payload_; | |
151 | |
152 // Object ids for the test policy objects. | |
153 invalidation::ObjectId object_id_a_; | |
154 invalidation::ObjectId object_id_b_; | |
155 | |
156 // Increasing policy timestamp. | |
157 int64 timestamp_; | |
158 | |
159 // Fake policy values which are alternated to cause the store to report a | |
160 // changed policy. | |
161 const char* policy_value_a_; | |
162 const char* policy_value_b_; | |
163 | |
164 // The currently used policy value. | |
165 const char* policy_value_cur_; | |
166 | |
167 // Stores how many times the invalidate callback was called. | |
168 int invalidate_callback_count_; | |
169 | |
170 // Stores how many times the state change callback was called for each state. | |
171 int state_change_enabled_callback_count_; | |
172 int state_change_disabled_callback_count_; | |
173 | |
174 // Stores starting histogram counts for kMetricPolicyRefresh. | |
175 scoped_ptr<base::HistogramSamples> refresh_samples_; | |
176 | |
177 // Stores starting histogram counts for kMetricPolicyInvalidations. | |
178 scoped_ptr<base::HistogramSamples> invalidations_samples_; | |
179 }; | |
180 | |
181 CloudPolicyInvalidatorTest::CloudPolicyInvalidatorTest() | |
182 : task_runner_(new base::TestSimpleTaskRunner()), | |
183 invalidation_version_(0), | |
184 object_id_a_(135, "asdf"), | |
185 object_id_b_(246, "zxcv"), | |
186 timestamp_(123456), | |
187 policy_value_a_("asdf"), | |
188 policy_value_b_("zxcv"), | |
189 policy_value_cur_(policy_value_a_), | |
190 invalidate_callback_count_(0), | |
191 state_change_enabled_callback_count_(0), | |
192 state_change_disabled_callback_count_(0) {} | |
193 | |
194 void CloudPolicyInvalidatorTest::SetUp() { | |
195 base::StatisticsRecorder::Initialize(); | |
196 refresh_samples_ = GetHistogramSamples(kMetricPolicyRefresh); | |
197 invalidations_samples_ = GetHistogramSamples(kMetricPolicyInvalidations); | |
198 } | |
199 | |
200 void CloudPolicyInvalidatorTest::TearDown() { | |
201 EXPECT_FALSE(invalidation_service_.ReceivedInvalidAcknowledgement()); | |
202 if (invalidator_) | |
203 invalidator_->Shutdown(); | |
204 } | |
205 | |
206 void CloudPolicyInvalidatorTest::StartInvalidator() { | |
207 invalidator_.reset(new CloudPolicyInvalidator( | |
208 &invalidation_service_, | |
209 &store_, | |
210 task_runner_, | |
211 this /* invalidation_handler */)); | |
212 } | |
213 | |
214 void CloudPolicyInvalidatorTest::StorePolicy( | |
215 PolicyObject object, | |
216 int64 invalidation_version, | |
217 bool policy_changed, | |
218 int64 timestamp) { | |
219 enterprise_management::PolicyData* data = | |
220 new enterprise_management::PolicyData(); | |
221 if (object != POLICY_OBJECT_NONE) { | |
222 data->set_invalidation_source(GetPolicyObjectId(object).source()); | |
223 data->set_invalidation_name(GetPolicyObjectId(object).name()); | |
224 } | |
225 data->set_timestamp(timestamp); | |
226 // Swap the policy value if a policy change is desired. | |
227 if (policy_changed) | |
228 policy_value_cur_ = policy_value_cur_ == policy_value_a_ ? | |
229 policy_value_b_ : policy_value_a_; | |
230 data->set_policy_value(policy_value_cur_); | |
231 store_.invalidation_version_ = invalidation_version; | |
232 store_.policy_.reset(data); | |
233 base::DictionaryValue policies; | |
234 policies.SetInteger( | |
235 key::kMaxInvalidationFetchDelay, | |
236 CloudPolicyInvalidator::kMaxFetchDelayMin); | |
237 store_.policy_map_.LoadFrom( | |
238 &policies, | |
239 POLICY_LEVEL_MANDATORY, | |
240 POLICY_SCOPE_MACHINE); | |
241 store_.NotifyStoreLoaded(); | |
242 } | |
243 | |
244 void CloudPolicyInvalidatorTest::DisableInvalidationService() { | |
245 invalidation_service_.SetInvalidatorState( | |
246 syncer::TRANSIENT_INVALIDATION_ERROR); | |
247 } | |
248 | |
249 void CloudPolicyInvalidatorTest::EnableInvalidationService() { | |
250 invalidation_service_.SetInvalidatorState(syncer::INVALIDATIONS_ENABLED); | |
251 } | |
252 | |
253 syncer::AckHandle CloudPolicyInvalidatorTest::FireInvalidation( | |
254 PolicyObject object, | |
255 int64 version, | |
256 const std::string& payload) { | |
257 return invalidation_service_.EmitInvalidationForTest( | |
258 GetPolicyObjectId(object), | |
259 version, | |
260 payload); | |
261 } | |
262 | |
263 syncer::AckHandle CloudPolicyInvalidatorTest::FireInvalidation( | |
264 PolicyObject object) { | |
265 return invalidation_service_.EmitInvalidationForTest( | |
266 GetPolicyObjectId(object), | |
267 syncer::Invalidation::kUnknownVersion, | |
268 std::string()); | |
269 } | |
270 | |
271 void CloudPolicyInvalidatorTest::ExpectInvalidationInfo( | |
272 int64 version, | |
273 const std::string& payload) { | |
274 EXPECT_EQ(version, invalidation_version_); | |
275 EXPECT_EQ(payload, invalidation_payload_); | |
276 } | |
277 | |
278 void CloudPolicyInvalidatorTest::ExpectInvalidateNotCalled() { | |
279 EXPECT_EQ(0, invalidate_callback_count_); | |
280 task_runner_->RunUntilIdle(); | |
281 EXPECT_EQ(0, invalidate_callback_count_); | |
282 } | |
283 | |
284 void CloudPolicyInvalidatorTest::ExpectInvalidateCalled(bool unknown_version) { | |
285 base::TimeDelta min_delay; | |
286 base::TimeDelta max_delay = base::TimeDelta::FromMilliseconds( | |
287 CloudPolicyInvalidator::kMaxFetchDelayMin); | |
288 if (unknown_version) { | |
289 base::TimeDelta additional_delay = base::TimeDelta::FromMinutes( | |
290 CloudPolicyInvalidator::kMissingPayloadDelay); | |
291 min_delay += additional_delay; | |
292 max_delay += additional_delay; | |
293 } | |
294 | |
295 ASSERT_FALSE(task_runner_->GetPendingTasks().empty()); | |
296 base::TimeDelta actual_delay = task_runner_->GetPendingTasks().back().delay; | |
297 EXPECT_GE(actual_delay, min_delay); | |
298 EXPECT_LE(actual_delay, max_delay); | |
299 | |
300 EXPECT_EQ(0, invalidate_callback_count_); | |
301 task_runner_->RunUntilIdle(); | |
302 EXPECT_EQ(1, invalidate_callback_count_); | |
303 invalidate_callback_count_ = 0; | |
304 } | |
305 | |
306 void CloudPolicyInvalidatorTest::ExpectStateChangedNotCalled() { | |
307 EXPECT_EQ(0, state_change_enabled_callback_count_); | |
308 EXPECT_EQ(0, state_change_disabled_callback_count_); | |
309 } | |
310 | |
311 void CloudPolicyInvalidatorTest::ExpectStateChangedCalled( | |
312 bool invalidations_enabled) { | |
313 if (invalidations_enabled) { | |
314 EXPECT_EQ(1, state_change_enabled_callback_count_); | |
315 EXPECT_EQ(0, state_change_disabled_callback_count_); | |
316 } else { | |
317 EXPECT_EQ(0, state_change_enabled_callback_count_); | |
318 EXPECT_EQ(1, state_change_disabled_callback_count_); | |
319 } | |
320 state_change_enabled_callback_count_ = 0; | |
321 state_change_disabled_callback_count_ = 0; | |
322 } | |
323 | |
324 bool CloudPolicyInvalidatorTest::IsInvalidationAcknowledged( | |
325 const syncer::AckHandle& ack_handle) { | |
326 return invalidation_service_.IsInvalidationAcknowledged(ack_handle); | |
327 } | |
328 | |
329 base::HistogramBase::Count CloudPolicyInvalidatorTest::GetCount( | |
330 MetricPolicyRefresh metric) { | |
331 return GetHistogramSamples(kMetricPolicyRefresh)->GetCount(metric) - | |
332 refresh_samples_->GetCount(metric); | |
333 } | |
334 | |
335 base::HistogramBase::Count CloudPolicyInvalidatorTest::GetCount( | |
336 MetricPolicyInvalidations metric) { | |
337 return GetHistogramSamples(kMetricPolicyInvalidations)->GetCount(metric) - | |
338 invalidations_samples_->GetCount(metric); | |
339 } | |
340 | |
341 void CloudPolicyInvalidatorTest::SetInvalidationInfo( | |
342 int64 version, | |
343 const std::string& payload) { | |
344 invalidation_version_ = version; | |
345 invalidation_payload_ = payload; | |
346 } | |
347 | |
348 void CloudPolicyInvalidatorTest::InvalidatePolicy() { | |
349 ++invalidate_callback_count_; | |
350 } | |
351 | |
352 void CloudPolicyInvalidatorTest::OnInvalidatorStateChanged( | |
353 bool invalidations_enabled) { | |
354 if (invalidator_.get()) | |
355 EXPECT_EQ(invalidations_enabled, invalidator_->invalidations_enabled()); | |
356 if (invalidations_enabled) | |
357 ++state_change_enabled_callback_count_; | |
358 else | |
359 ++state_change_disabled_callback_count_; | |
360 } | |
361 | |
362 const invalidation::ObjectId& CloudPolicyInvalidatorTest::GetPolicyObjectId( | |
363 PolicyObject object) const { | |
364 EXPECT_TRUE(object == POLICY_OBJECT_A || object == POLICY_OBJECT_B); | |
365 return object == POLICY_OBJECT_A ? object_id_a_ : object_id_b_; | |
366 } | |
367 | |
368 scoped_ptr<base::HistogramSamples> | |
369 CloudPolicyInvalidatorTest::GetHistogramSamples( | |
370 const std::string& name) const { | |
371 base::HistogramBase* histogram = | |
372 base::StatisticsRecorder::FindHistogram(name); | |
373 if (!histogram) | |
374 return scoped_ptr<base::HistogramSamples>(new base::SampleMap()); | |
375 return histogram->SnapshotSamples(); | |
376 } | |
377 | |
378 TEST_F(CloudPolicyInvalidatorTest, RegisterOnStoreLoaded) { | |
379 // No registration when store is not loaded. | |
380 StartInvalidator(); | |
381 ExpectStateChangedNotCalled(); | |
382 FireInvalidation(POLICY_OBJECT_A); | |
383 FireInvalidation(POLICY_OBJECT_B); | |
384 ExpectInvalidateNotCalled(); | |
385 | |
386 // No registration when store is loaded with no invalidation object id. | |
387 StorePolicy(POLICY_OBJECT_NONE); | |
388 ExpectStateChangedNotCalled(); | |
389 FireInvalidation(POLICY_OBJECT_A); | |
390 FireInvalidation(POLICY_OBJECT_B); | |
391 ExpectInvalidateNotCalled(); | |
392 | |
393 // Check registration when store is loaded for object A. | |
394 StorePolicy(POLICY_OBJECT_A); | |
395 ExpectStateChangedCalled(true); | |
396 FireInvalidation(POLICY_OBJECT_A); | |
397 ExpectInvalidateCalled(); | |
398 FireInvalidation(POLICY_OBJECT_B); | |
399 ExpectInvalidateNotCalled(); | |
400 } | |
401 | |
402 TEST_F(CloudPolicyInvalidatorTest, ChangeRegistration) { | |
403 // Register for object A. | |
404 StartInvalidator(); | |
405 StorePolicy(POLICY_OBJECT_A); | |
406 ExpectStateChangedCalled(true); | |
407 FireInvalidation(POLICY_OBJECT_A); | |
408 ExpectInvalidateCalled(); | |
409 FireInvalidation(POLICY_OBJECT_B); | |
410 ExpectInvalidateNotCalled(); | |
411 syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A); | |
412 | |
413 // Check re-registration for object B. Make sure the pending invalidation for | |
414 // object A is acknowledged without making the callback. | |
415 StorePolicy(POLICY_OBJECT_B); | |
416 ExpectStateChangedNotCalled(); | |
417 EXPECT_TRUE(IsInvalidationAcknowledged(ack)); | |
418 ExpectInvalidateNotCalled(); | |
419 | |
420 // Make sure future invalidations for object A are ignored and for object B | |
421 // are processed. | |
422 FireInvalidation(POLICY_OBJECT_A); | |
423 ExpectInvalidateNotCalled(); | |
424 FireInvalidation(POLICY_OBJECT_B); | |
425 ExpectInvalidateCalled(); | |
426 } | |
427 | |
428 TEST_F(CloudPolicyInvalidatorTest, UnregisterOnStoreLoaded) { | |
429 // Register for object A. | |
430 StartInvalidator(); | |
431 StorePolicy(POLICY_OBJECT_A); | |
432 ExpectStateChangedCalled(true); | |
433 FireInvalidation(POLICY_OBJECT_A); | |
434 ExpectInvalidateCalled(); | |
435 | |
436 // Check unregistration when store is loaded with no invalidation object id. | |
437 syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A); | |
438 EXPECT_FALSE(IsInvalidationAcknowledged(ack)); | |
439 StorePolicy(POLICY_OBJECT_NONE); | |
440 EXPECT_TRUE(IsInvalidationAcknowledged(ack)); | |
441 ExpectStateChangedCalled(false); | |
442 FireInvalidation(POLICY_OBJECT_A); | |
443 FireInvalidation(POLICY_OBJECT_B); | |
444 ExpectInvalidateNotCalled(); | |
445 | |
446 // Check re-registration for object B. | |
447 StorePolicy(POLICY_OBJECT_B); | |
448 ExpectStateChangedCalled(true); | |
449 FireInvalidation(POLICY_OBJECT_B); | |
450 ExpectInvalidateCalled(); | |
451 } | |
452 | |
453 TEST_F(CloudPolicyInvalidatorTest, HandleInvalidation) { | |
454 // Register and fire invalidation | |
455 StorePolicy(POLICY_OBJECT_A); | |
456 StartInvalidator(); | |
457 ExpectStateChangedCalled(true); | |
458 syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 12, "test_payload"); | |
459 | |
460 // Make sure client info is set as soon as the invalidation is received. | |
461 ExpectInvalidationInfo(12, "test_payload"); | |
rlarocque
2013/07/25 19:23:40
When you wrap your expectations in functions, the
Steve Condie
2013/07/26 01:39:25
Thanks for the suggestion. For the most part, thes
rlarocque
2013/07/29 18:29:54
You've gained better line numbers, but now the tes
Steve Condie
2013/07/29 18:53:07
I actually think seeing the name of the function i
| |
462 ExpectInvalidateCalled(false /* unknown_version */); | |
463 | |
464 // Make sure invalidation is not acknowledged until the store is loaded. | |
465 EXPECT_FALSE(IsInvalidationAcknowledged(ack)); | |
466 ExpectInvalidationInfo(12, "test_payload"); | |
467 StorePolicy(POLICY_OBJECT_A, 12); | |
468 EXPECT_TRUE(IsInvalidationAcknowledged(ack)); | |
469 ExpectInvalidationInfo(0, std::string()); | |
470 } | |
471 | |
472 TEST_F(CloudPolicyInvalidatorTest, HandleInvalidationWithUnknownVersion) { | |
473 // Register and fire invalidation with unknown version. | |
474 StorePolicy(POLICY_OBJECT_A); | |
475 StartInvalidator(); | |
476 syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A); | |
477 | |
478 // Make sure client info is not set until after the invalidation callback is | |
479 // made. | |
480 ExpectInvalidationInfo(0, std::string()); | |
481 ExpectInvalidateCalled(); | |
482 ExpectInvalidationInfo(-1, std::string()); | |
483 | |
484 // Make sure invalidation is not acknowledged until the store is loaded. | |
485 EXPECT_FALSE(IsInvalidationAcknowledged(ack)); | |
486 StorePolicy(POLICY_OBJECT_A, -1); | |
487 EXPECT_TRUE(IsInvalidationAcknowledged(ack)); | |
488 ExpectInvalidationInfo(0, std::string()); | |
489 } | |
490 | |
491 TEST_F(CloudPolicyInvalidatorTest, HandleMultipleInvalidations) { | |
492 // Generate multiple invalidations. | |
493 StorePolicy(POLICY_OBJECT_A); | |
494 StartInvalidator(); | |
495 syncer::AckHandle ack1 = FireInvalidation(POLICY_OBJECT_A, 1, "test1"); | |
496 ExpectInvalidationInfo(1, "test1"); | |
497 syncer::AckHandle ack2 = FireInvalidation(POLICY_OBJECT_A, 2, "test2"); | |
498 ExpectInvalidationInfo(2, "test2"); | |
499 syncer::AckHandle ack3= FireInvalidation(POLICY_OBJECT_A, 3, "test3"); | |
500 ExpectInvalidationInfo(3, "test3"); | |
501 | |
502 // Make sure the replaced invalidations are acknowledged. | |
503 EXPECT_TRUE(IsInvalidationAcknowledged(ack1)); | |
504 EXPECT_TRUE(IsInvalidationAcknowledged(ack2)); | |
505 | |
506 // Make sure the invalidate callback is called once. | |
507 ExpectInvalidateCalled(false /* unknown_version */); | |
508 | |
509 // Make sure that the last invalidation is only acknowledged after the store | |
510 // is loaded with the latest version. | |
511 StorePolicy(POLICY_OBJECT_A, 1); | |
512 EXPECT_FALSE(IsInvalidationAcknowledged(ack3)); | |
513 StorePolicy(POLICY_OBJECT_A, 2); | |
514 EXPECT_FALSE(IsInvalidationAcknowledged(ack3)); | |
515 StorePolicy(POLICY_OBJECT_A, 3); | |
516 EXPECT_TRUE(IsInvalidationAcknowledged(ack3)); | |
517 } | |
518 | |
519 TEST_F(CloudPolicyInvalidatorTest, | |
520 HandleMultipleInvalidationsWithUnknownVersion) { | |
521 // Validate that multiple invalidations with unknown version each generate | |
522 // unique invalidation version numbers. | |
523 StorePolicy(POLICY_OBJECT_A); | |
524 StartInvalidator(); | |
525 syncer::AckHandle ack1 = FireInvalidation(POLICY_OBJECT_A); | |
526 ExpectInvalidationInfo(0, std::string()); | |
527 ExpectInvalidateCalled(); | |
528 ExpectInvalidationInfo(-1, std::string()); | |
529 syncer::AckHandle ack2 = FireInvalidation(POLICY_OBJECT_A); | |
530 ExpectInvalidationInfo(0, std::string()); | |
531 ExpectInvalidateCalled(); | |
532 ExpectInvalidationInfo(-2, std::string()); | |
533 syncer::AckHandle ack3 = FireInvalidation(POLICY_OBJECT_A); | |
534 ExpectInvalidationInfo(0, std::string()); | |
535 ExpectInvalidateCalled(); | |
536 ExpectInvalidationInfo(-3, std::string()); | |
537 | |
538 // Make sure the replaced invalidations are acknowledged. | |
539 EXPECT_TRUE(IsInvalidationAcknowledged(ack1)); | |
540 EXPECT_TRUE(IsInvalidationAcknowledged(ack2)); | |
541 | |
542 // Make sure that the last invalidation is only acknowledged after the store | |
543 // is loaded with the last unknown version. | |
544 StorePolicy(POLICY_OBJECT_A, -1); | |
545 EXPECT_FALSE(IsInvalidationAcknowledged(ack3)); | |
546 StorePolicy(POLICY_OBJECT_A, -2); | |
547 EXPECT_FALSE(IsInvalidationAcknowledged(ack3)); | |
548 StorePolicy(POLICY_OBJECT_A, -3); | |
549 EXPECT_TRUE(IsInvalidationAcknowledged(ack3)); | |
550 } | |
551 | |
552 TEST_F(CloudPolicyInvalidatorTest, AcknowledgeBeforeInvalidateCallback) { | |
553 // Generate an invalidation. | |
554 StorePolicy(POLICY_OBJECT_A); | |
555 StartInvalidator(); | |
556 syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 3, "test"); | |
557 | |
558 // Ensure that the invalidate callback is not made and the invalidation is | |
559 // acknowledged if the store is loaded with the latest version before the | |
560 // callback is invoked. | |
561 StorePolicy(POLICY_OBJECT_A, 3); | |
562 EXPECT_TRUE(IsInvalidationAcknowledged(ack)); | |
563 ExpectInvalidateNotCalled(); | |
564 } | |
565 | |
566 TEST_F(CloudPolicyInvalidatorTest, StateChanged) { | |
567 // Before registration, changes to the invalidation service state should not | |
568 // generate change state notifications. | |
569 StartInvalidator(); | |
570 DisableInvalidationService(); | |
571 EnableInvalidationService(); | |
572 ExpectStateChangedNotCalled(); | |
573 | |
574 // After registration, changes to the invalidation service state should | |
575 // generate notifications. | |
576 StorePolicy(POLICY_OBJECT_A); | |
577 ExpectStateChangedCalled(true); | |
578 DisableInvalidationService(); | |
579 ExpectStateChangedCalled(false); | |
580 DisableInvalidationService(); | |
581 ExpectStateChangedNotCalled(); | |
582 EnableInvalidationService(); | |
583 ExpectStateChangedCalled(true); | |
584 EnableInvalidationService(); | |
585 ExpectStateChangedNotCalled(); | |
586 | |
587 // When the invalidation service is enabled, changes to the registration | |
588 // state should generate notifications. | |
589 StorePolicy(POLICY_OBJECT_NONE); | |
590 ExpectStateChangedCalled(false); | |
591 StorePolicy(POLICY_OBJECT_NONE); | |
592 ExpectStateChangedNotCalled(); | |
593 StorePolicy(POLICY_OBJECT_A); | |
594 ExpectStateChangedCalled(true); | |
595 StorePolicy(POLICY_OBJECT_A); | |
596 ExpectStateChangedNotCalled(); | |
597 | |
598 // When the invalidation service is disabled, changes to the registration | |
599 // state should not generate notifications. | |
600 DisableInvalidationService(); | |
601 ExpectStateChangedCalled(false); | |
602 StorePolicy(POLICY_OBJECT_NONE); | |
603 StorePolicy(POLICY_OBJECT_A); | |
604 ExpectStateChangedNotCalled(); | |
605 } | |
606 | |
607 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsUnregistered) { | |
608 // Store loads occurring before invalidation registration are not counted. | |
609 StartInvalidator(); | |
610 StorePolicy(POLICY_OBJECT_NONE, 0, false /* policy_changed */); | |
611 StorePolicy(POLICY_OBJECT_NONE, 0, true /* policy_changed */); | |
612 EXPECT_EQ(0, GetCount(kMetricPolicyRefreshChanged)); | |
613 EXPECT_EQ(0, GetCount(kMetricPolicyRefreshChangedNoInvalidations)); | |
614 EXPECT_EQ(0, GetCount(kMetricPolicyRefreshUnchanged)); | |
615 EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedChanged)); | |
616 EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedUnchanged)); | |
617 } | |
618 | |
619 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsNoInvalidations) { | |
620 // Store loads occurring while registered should be differentiated depending | |
621 // on whether the invalidation service was enabled or not. | |
622 StorePolicy(POLICY_OBJECT_A); | |
623 StartInvalidator(); | |
624 StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | |
625 StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | |
626 DisableInvalidationService(); | |
627 StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | |
628 StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | |
629 StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | |
630 StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | |
631 EXPECT_EQ(1, GetCount(kMetricPolicyRefreshChanged)); | |
632 EXPECT_EQ(2, GetCount(kMetricPolicyRefreshChangedNoInvalidations)); | |
633 EXPECT_EQ(3, GetCount(kMetricPolicyRefreshUnchanged)); | |
634 EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedChanged)); | |
635 EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedUnchanged)); | |
636 } | |
637 | |
638 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsStoreSameTimestamp) { | |
639 // Store loads with the same timestamp as the load which causes registration | |
640 // are not counted. | |
641 StartInvalidator(); | |
642 StorePolicy( | |
643 POLICY_OBJECT_A, 0, false /* policy_changed */, 12 /* timestamp */); | |
644 StorePolicy( | |
645 POLICY_OBJECT_A, 0, false /* policy_changed */, 12 /* timestamp */); | |
646 StorePolicy( | |
647 POLICY_OBJECT_A, 0, true /* policy_changed */, 12 /* timestamp */); | |
648 | |
649 // The next load with a different timestamp counts. | |
650 StorePolicy( | |
651 POLICY_OBJECT_A, 0, true /* policy_changed */, 13 /* timestamp */); | |
652 | |
653 EXPECT_EQ(1, GetCount(kMetricPolicyRefreshChanged)); | |
654 EXPECT_EQ(0, GetCount(kMetricPolicyRefreshChangedNoInvalidations)); | |
655 EXPECT_EQ(0, GetCount(kMetricPolicyRefreshUnchanged)); | |
656 EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedChanged)); | |
657 EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedUnchanged)); | |
658 } | |
659 | |
660 TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsInvalidation) { | |
661 // Store loads after an invalidation are counted as invalidated, even if | |
662 // the loads do not result in the invalidation being acknowledged. | |
663 StartInvalidator(); | |
664 StorePolicy(POLICY_OBJECT_A); | |
665 FireInvalidation(POLICY_OBJECT_A, 5, "test"); | |
666 StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | |
667 StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | |
668 StorePolicy(POLICY_OBJECT_A, 5, true /* policy_changed */); | |
669 | |
670 // Store loads after the invalidation is complete are not counted as | |
671 // invalidated. | |
672 StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | |
673 StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | |
674 StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | |
675 StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | |
676 StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | |
677 StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */); | |
678 StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */); | |
679 | |
680 EXPECT_EQ(3, GetCount(kMetricPolicyRefreshChanged)); | |
681 EXPECT_EQ(0, GetCount(kMetricPolicyRefreshChangedNoInvalidations)); | |
682 EXPECT_EQ(4, GetCount(kMetricPolicyRefreshUnchanged)); | |
683 EXPECT_EQ(2, GetCount(kMetricPolicyRefreshInvalidatedChanged)); | |
684 EXPECT_EQ(1, GetCount(kMetricPolicyRefreshInvalidatedUnchanged)); | |
685 } | |
686 | |
687 TEST_F(CloudPolicyInvalidatorTest, InvalidationMetrics) { | |
688 // Generate a mix of versioned and unknown-version invalidations. | |
689 StorePolicy(POLICY_OBJECT_A); | |
690 StartInvalidator(); | |
691 FireInvalidation(POLICY_OBJECT_B); | |
692 FireInvalidation(POLICY_OBJECT_A); | |
693 FireInvalidation(POLICY_OBJECT_B, 1, "test"); | |
694 FireInvalidation(POLICY_OBJECT_A, 1, "test"); | |
695 FireInvalidation(POLICY_OBJECT_A, 2, "test"); | |
696 FireInvalidation(POLICY_OBJECT_A); | |
697 FireInvalidation(POLICY_OBJECT_A); | |
698 FireInvalidation(POLICY_OBJECT_A, 3, "test"); | |
699 FireInvalidation(POLICY_OBJECT_A, 4, "test"); | |
700 | |
701 // Verify that received invalidations metrics are correct. | |
702 EXPECT_EQ(3, GetCount(kMetricPolicyInvalidationsNoPayload)); | |
703 EXPECT_EQ(4, GetCount(kMetricPolicyInvalidationsPayload)); | |
704 } | |
705 | |
706 class CloudPolicyInvalidationReplayerTest | |
707 : public testing::Test, | |
708 public CloudPolicyInvalidationHandler { | |
709 protected: | |
710 CloudPolicyInvalidationReplayerTest(); | |
711 | |
712 // Enable or disable the invalidation service for the replayer. | |
713 void EnableInvalidationService(); | |
714 void DisableInvalidationService(); | |
715 | |
716 // Fire an invalidation for the replayer. | |
717 void FireInvalidation(int64 version, const std::string& payload); | |
718 | |
719 // Fire an "incomplete" invalidation for the replayer. In this context, | |
720 // incomplete means that SetInvalidationInfo is called, but InvalidatePolicy | |
721 // is not called. | |
722 void FireIncompleteInvalidation(int64 version, const std::string& payload); | |
723 | |
724 // Replay, so that expectations can be verified. | |
725 void Replay(); | |
726 | |
727 // Returns whether SetInvalidationInfo was called and checks the parameters. | |
728 bool SetInvalidationInfoCalled(int64 version, const std::string& payload); | |
729 | |
730 // Returns whether InvalidatePolicy was called. | |
731 bool InvalidatePolicyCalled(); | |
732 | |
733 // Returns whether OnInvalidatorStateChanged was called. | |
734 bool OnInvalidatorStateChangedCalled(); | |
735 | |
736 // CloudPolicyInvalidationHandler: | |
737 virtual void SetInvalidationInfo( | |
738 int64 version, | |
739 const std::string& payload) OVERRIDE; | |
740 virtual void InvalidatePolicy() OVERRIDE; | |
741 virtual void OnInvalidatorStateChanged(bool invalidations_enabled) OVERRIDE; | |
742 | |
743 private: | |
744 // The replayer object to test. | |
745 CloudPolicyInvalidationReplayer replayer_; | |
746 | |
747 // State of CloudPolicyInvalidationHandler methods called during replay. | |
748 bool set_invalidation_info_called_; | |
749 int64 invalidation_version_; | |
750 std::string invalidation_payload_; | |
751 bool invalidate_policy_called_; | |
752 bool on_invalidator_state_changed_called_; | |
753 }; | |
754 | |
755 CloudPolicyInvalidationReplayerTest::CloudPolicyInvalidationReplayerTest() | |
756 : set_invalidation_info_called_(false), | |
757 invalidation_version_(0), | |
758 invalidate_policy_called_(false), | |
759 on_invalidator_state_changed_called_(false) {} | |
760 | |
761 void CloudPolicyInvalidationReplayerTest::EnableInvalidationService() { | |
762 replayer_.OnInvalidatorStateChanged(true); | |
763 } | |
764 | |
765 void CloudPolicyInvalidationReplayerTest::DisableInvalidationService() { | |
766 replayer_.OnInvalidatorStateChanged(false); | |
767 } | |
768 | |
769 void CloudPolicyInvalidationReplayerTest::FireInvalidation( | |
770 int64 version, | |
771 const std::string& payload) { | |
772 replayer_.SetInvalidationInfo(version, payload); | |
773 replayer_.InvalidatePolicy(); | |
774 } | |
775 | |
776 void CloudPolicyInvalidationReplayerTest::FireIncompleteInvalidation( | |
777 int64 version, | |
778 const std::string& payload) { | |
779 replayer_.SetInvalidationInfo(version, payload); | |
780 } | |
781 | |
782 void CloudPolicyInvalidationReplayerTest::Replay() { | |
783 replayer_.Replay(this); | |
784 } | |
785 | |
786 bool CloudPolicyInvalidationReplayerTest::SetInvalidationInfoCalled( | |
787 int64 version, const std::string& payload) { | |
788 EXPECT_EQ(version, invalidation_version_); | |
789 EXPECT_EQ(payload, invalidation_payload_); | |
790 return set_invalidation_info_called_; | |
791 } | |
792 | |
793 bool CloudPolicyInvalidationReplayerTest::InvalidatePolicyCalled() { | |
794 return invalidate_policy_called_; | |
795 } | |
796 | |
797 bool CloudPolicyInvalidationReplayerTest::OnInvalidatorStateChangedCalled() { | |
798 return on_invalidator_state_changed_called_; | |
799 } | |
800 | |
801 void CloudPolicyInvalidationReplayerTest::SetInvalidationInfo( | |
802 int64 version, | |
803 const std::string& payload) { | |
804 EXPECT_FALSE(set_invalidation_info_called_); | |
805 EXPECT_FALSE(invalidate_policy_called_); | |
806 set_invalidation_info_called_ = true; | |
807 invalidation_version_ = version; | |
808 invalidation_payload_ = payload; | |
809 } | |
810 | |
811 void CloudPolicyInvalidationReplayerTest::InvalidatePolicy() { | |
812 invalidate_policy_called_ = true; | |
813 } | |
814 | |
815 void CloudPolicyInvalidationReplayerTest::OnInvalidatorStateChanged( | |
816 bool invalidations_enabled) { | |
817 EXPECT_FALSE(on_invalidator_state_changed_called_); | |
818 EXPECT_FALSE(set_invalidation_info_called_); | |
819 EXPECT_FALSE(invalidate_policy_called_); | |
820 EXPECT_TRUE(invalidations_enabled); | |
821 on_invalidator_state_changed_called_ = true; | |
822 } | |
823 | |
824 TEST_F(CloudPolicyInvalidationReplayerTest, NoCalls) { | |
825 Replay(); | |
826 EXPECT_FALSE(SetInvalidationInfoCalled(0, std::string())); | |
827 EXPECT_FALSE(InvalidatePolicyCalled()); | |
828 EXPECT_FALSE(OnInvalidatorStateChangedCalled()); | |
829 } | |
830 | |
831 TEST_F(CloudPolicyInvalidationReplayerTest, InvalidationsDisabled) { | |
832 EnableInvalidationService(); | |
833 DisableInvalidationService(); | |
834 Replay(); | |
835 EXPECT_FALSE(SetInvalidationInfoCalled(0, std::string())); | |
836 EXPECT_FALSE(InvalidatePolicyCalled()); | |
837 EXPECT_FALSE(OnInvalidatorStateChangedCalled()); | |
838 } | |
839 | |
840 TEST_F(CloudPolicyInvalidationReplayerTest, InvalidationsEnabled) { | |
841 EnableInvalidationService(); | |
842 DisableInvalidationService(); | |
843 EnableInvalidationService(); | |
844 Replay(); | |
845 EXPECT_FALSE(SetInvalidationInfoCalled(0, std::string())); | |
846 EXPECT_FALSE(InvalidatePolicyCalled()); | |
847 EXPECT_TRUE(OnInvalidatorStateChangedCalled()); | |
848 } | |
849 | |
850 TEST_F(CloudPolicyInvalidationReplayerTest, Invalidation) { | |
851 EnableInvalidationService(); | |
852 FireInvalidation(1, "test"); | |
853 Replay(); | |
854 EXPECT_TRUE(SetInvalidationInfoCalled(1, "test")); | |
855 EXPECT_TRUE(InvalidatePolicyCalled()); | |
856 EXPECT_TRUE(OnInvalidatorStateChangedCalled()); | |
857 } | |
858 | |
859 TEST_F(CloudPolicyInvalidationReplayerTest, MultipleInvalidations) { | |
860 EnableInvalidationService(); | |
861 FireInvalidation(1, "test1"); | |
862 FireInvalidation(2, "test2"); | |
863 FireInvalidation(3, "test3"); | |
864 Replay(); | |
865 EXPECT_TRUE(SetInvalidationInfoCalled(3, "test3")); | |
866 EXPECT_TRUE(InvalidatePolicyCalled()); | |
867 EXPECT_TRUE(OnInvalidatorStateChangedCalled()); | |
868 } | |
869 | |
870 TEST_F(CloudPolicyInvalidationReplayerTest, IncompleteInvalidation) { | |
871 EnableInvalidationService(); | |
872 FireInvalidation(1, "test1"); | |
873 FireInvalidation(2, "test2"); | |
874 FireIncompleteInvalidation(3, "test3"); | |
875 Replay(); | |
876 EXPECT_TRUE(SetInvalidationInfoCalled(3, "test3")); | |
877 EXPECT_FALSE(InvalidatePolicyCalled()); | |
878 EXPECT_TRUE(OnInvalidatorStateChangedCalled()); | |
879 } | |
880 | |
881 TEST_F(CloudPolicyInvalidationReplayerTest, InvalidationThenServiceDisabled) { | |
882 EnableInvalidationService(); | |
883 FireInvalidation(1, "test"); | |
884 DisableInvalidationService(); | |
885 Replay(); | |
886 EXPECT_TRUE(SetInvalidationInfoCalled(1, "test")); | |
887 EXPECT_TRUE(InvalidatePolicyCalled()); | |
888 EXPECT_FALSE(OnInvalidatorStateChangedCalled()); | |
889 } | |
890 | |
891 } // namespace policy | |
OLD | NEW |