Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(791)

Unified Diff: chrome/browser/policy/cloud/cloud_policy_invalidator_unittest.cc

Issue 19733003: Implement cloud policy invalidations using the invalidation service framework. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/policy/cloud/cloud_policy_invalidator_unittest.cc
diff --git a/chrome/browser/policy/cloud/cloud_policy_invalidator_unittest.cc b/chrome/browser/policy/cloud/cloud_policy_invalidator_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3daa087262c72d1cca6285b0d79e5a7fa27059b3
--- /dev/null
+++ b/chrome/browser/policy/cloud/cloud_policy_invalidator_unittest.cc
@@ -0,0 +1,566 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_samples.h"
+#include "base/metrics/sample_map.h"
+#include "base/metrics/statistics_recorder.h"
+#include "base/test/test_simple_task_runner.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "chrome/browser/invalidation/fake_invalidation_service.h"
+#include "chrome/browser/policy/cloud/cloud_policy_core.h"
+#include "chrome/browser/policy/cloud/cloud_policy_invalidator.h"
+#include "chrome/browser/policy/cloud/cloud_policy_service.h"
+#include "chrome/browser/policy/cloud/enterprise_metrics.h"
+#include "chrome/browser/policy/cloud/mock_cloud_policy_client.h"
+#include "chrome/browser/policy/cloud/mock_cloud_policy_store.h"
+#include "chrome/browser/policy/policy_types.h"
+#include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
+#include "policy/policy_constants.h"
+#include "sync/notifier/invalidation_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+class CloudPolicyInvalidatorTest : public testing::Test {
+ protected:
+ // Policy objects which can be used in tests.
+ enum PolicyObject {
+ POLICY_OBJECT_NONE,
+ POLICY_OBJECT_A,
+ POLICY_OBJECT_B
+ };
+
+ CloudPolicyInvalidatorTest();
+
+ virtual void SetUp() OVERRIDE;
+
+ virtual void TearDown() OVERRIDE;
+
+ // Starts the invalidator which will be tested.
+ void StartInvalidator();
+
+ // Unregister the invalidator.
+ void UnregisterInvalidator();
+
+ // Simulates storing a new policy to the policy store.
+ // |object| determines which policy object the store will report the
+ // invalidator should register for. May be POLICY_OBJECT_NONE for no object.
+ // |invalidation_version| determines what invalidation the store will report.
+ // |policy_changed| determines whether the store will report that the
+ // policy changed.
+ // |timestamp| determines the response timestamp the store will report.
+ void StorePolicy(
+ PolicyObject object,
+ int64 invalidation_version,
+ bool policy_changed,
+ int64 timestamp);
+ void StorePolicy(
+ PolicyObject object,
+ int64 invalidation_version,
+ bool policy_changed) {
+ StorePolicy(object, invalidation_version, policy_changed, ++timestamp_);
+ }
+ void StorePolicy(PolicyObject object, int64 invalidation_version) {
+ StorePolicy(object, invalidation_version, false);
+ }
+ void StorePolicy(PolicyObject object) {
+ StorePolicy(object, 0);
+ }
+
+ // Causes the invalidation service to fire an invalidation. Returns an ack
+ // handle which be used to verify that the invalidation was acknowledged.
+ syncer::AckHandle FireInvalidation(
+ PolicyObject object,
+ int64 version,
+ const std::string& payload);
+
+ // Causes the invalidation service to fire an invalidation with unknown
+ // version. Returns an ack handle which be used to verify that the
+ // invalidation was acknowledged.
+ syncer::AckHandle FireInvalidation(PolicyObject object);
+
+ // Verifies expectations of the current invalidation info on the policy
+ // client object.
+ void ExpectClientInvalidationInfo(int64 version, const std::string& payload);
+
+ // Verifies expectation that the invalidate callback was not called.
+ void ExpectInvalidateNotCalled();
+
+ // Verifies expectation that the invalidate callback was called within an
+ // appropriate timeframe depending on whether the invalidation had unknown
+ // version.
+ void ExpectInvalidateCalled(bool unknown_version);
+ void ExpectInvalidateCalled() {
+ ExpectInvalidateCalled(true);
+ }
+
+ // Determines if the invalidation with the given ack handle has been
+ // acknowledged.
+ bool IsInvalidationAcknowledged(const syncer::AckHandle& ack_handle);
+
+ // Get the current count for the given metric.
+ base::HistogramBase::Count GetCount(MetricPolicyRefresh metric);
+ base::HistogramBase::Count GetCount(MetricPolicyInvalidations metric);
+
+ private:
+ // The invalidate callback used for testing.
+ void Invalidate();
+
+ // Returns the object id of the given policy object.
+ const invalidation::ObjectId& GetPolicyObjectId(PolicyObject object) const;
+
+ // Get histogram samples for the given histogram.
+ scoped_ptr<base::HistogramSamples> GetHistogramSamples(
+ const std::string& name) const;
+
+ // Objects the invalidator depends on.
+ invalidation::FakeInvalidationService invalidation_service_;
+ MockCloudPolicyClient client_;
+ MockCloudPolicyStore store_;
+ scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+
+ // The invalidator which will be tested.
+ scoped_ptr<CloudPolicyInvalidator> invalidator_;
+
+ // Object ids for the test policy objects.
+ invalidation::ObjectId object_id_a_;
+ invalidation::ObjectId object_id_b_;
+
+ // Increasing policy timestamp.
+ int64 timestamp_;
+
+ // Stores how many times the invalidate callback was called.
+ int invalidate_callback_count_;
+
+ // Stores starting histogram counts for kMetricPolicyRefresh.
+ scoped_ptr<base::HistogramSamples> refresh_samples_;
+
+ // Stores starting histogram counts for kMetricPolicyInvalidations.
+ scoped_ptr<base::HistogramSamples> invalidations_samples_;
+};
+
+CloudPolicyInvalidatorTest::CloudPolicyInvalidatorTest()
+ : task_runner_(new base::TestSimpleTaskRunner()),
+ object_id_a_(135, "asdf"),
+ object_id_b_(246, "zxcv"),
+ timestamp_(123456),
+ invalidate_callback_count_(0) {}
+
+void CloudPolicyInvalidatorTest::SetUp() {
+ base::StatisticsRecorder::Initialize();
+ refresh_samples_ = GetHistogramSamples(kMetricPolicyRefresh);
+ invalidations_samples_ = GetHistogramSamples(kMetricPolicyInvalidations);
+}
+
+void CloudPolicyInvalidatorTest::TearDown() {
+ EXPECT_FALSE(invalidation_service_.ReceivedInvalidAcknowledgement());
+}
+
+void CloudPolicyInvalidatorTest::StartInvalidator() {
+ invalidator_.reset(new CloudPolicyInvalidator(
+ &invalidation_service_,
+ &client_,
+ &store_,
+ task_runner_,
+ base::Bind(
+ &CloudPolicyInvalidatorTest::Invalidate,
+ base::Unretained(this))));
+}
+
+void CloudPolicyInvalidatorTest::UnregisterInvalidator() {
+ invalidator_->Unregister();
+}
+
+void CloudPolicyInvalidatorTest::StorePolicy(
+ PolicyObject object,
+ int64 invalidation_version,
+ bool policy_changed,
+ int64 timestamp) {
+ enterprise_management::PolicyData* data =
+ new enterprise_management::PolicyData();
+ if (object != POLICY_OBJECT_NONE) {
+ data->set_invalidation_source(GetPolicyObjectId(object).source());
+ data->set_invalidation_name(GetPolicyObjectId(object).name());
+ }
+ data->set_timestamp(timestamp);
+ store_.set_invalidation_version(invalidation_version);
+ store_.SetPolicyChanged(policy_changed);
+ store_.policy_.reset(data);
+ base::DictionaryValue policies;
+ policies.SetInteger(
+ key::kMaxInvalidationFetchDelay,
+ CloudPolicyInvalidator::kMaxFetchDelayMin);
+ store_.policy_map_.LoadFrom(
+ &policies,
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_MACHINE);
+ store_.NotifyStoreLoaded();
+}
+
+syncer::AckHandle CloudPolicyInvalidatorTest::FireInvalidation(
+ PolicyObject object,
+ int64 version,
+ const std::string& payload) {
+ return invalidation_service_.EmitInvalidationForTest(
+ GetPolicyObjectId(object),
+ version,
+ payload);
+}
+
+syncer::AckHandle CloudPolicyInvalidatorTest::FireInvalidation(
+ PolicyObject object) {
+ return invalidation_service_.EmitInvalidationForTest(
+ GetPolicyObjectId(object),
+ syncer::Invalidation::kUnknownVersion,
+ std::string());
+}
+
+void CloudPolicyInvalidatorTest::ExpectClientInvalidationInfo(
+ int64 version,
+ const std::string& payload) {
+ EXPECT_EQ(version, client_.invalidation_version_);
+ EXPECT_EQ(payload, client_.invalidation_payload_);
+}
+
+void CloudPolicyInvalidatorTest::ExpectInvalidateNotCalled() {
+ EXPECT_EQ(0, invalidate_callback_count_);
+ task_runner_->RunUntilIdle();
+ EXPECT_EQ(0, invalidate_callback_count_);
+}
+
+void CloudPolicyInvalidatorTest::ExpectInvalidateCalled(bool unknown_version) {
+ base::TimeDelta min_delay;
+ base::TimeDelta max_delay = base::TimeDelta::FromMilliseconds(
+ CloudPolicyInvalidator::kMaxFetchDelayMin);
+ if (unknown_version) {
+ base::TimeDelta additional_delay = base::TimeDelta::FromMinutes(
+ CloudPolicyInvalidator::kMissingPayloadDelay);
+ min_delay += additional_delay;
+ max_delay += additional_delay;
+ }
+
+ ASSERT_FALSE(task_runner_->GetPendingTasks().empty());
+ base::TimeDelta actual_delay = task_runner_->GetPendingTasks().back().delay;
+ EXPECT_GE(actual_delay, min_delay);
+ EXPECT_LE(actual_delay, max_delay);
+
+ EXPECT_EQ(0, invalidate_callback_count_);
+ task_runner_->RunUntilIdle();
+ EXPECT_EQ(1, invalidate_callback_count_);
+ invalidate_callback_count_ = 0;
+}
+
+bool CloudPolicyInvalidatorTest::IsInvalidationAcknowledged(
+ const syncer::AckHandle& ack_handle) {
+ return invalidation_service_.IsInvalidationAcknowledged(ack_handle);
+}
+
+base::HistogramBase::Count CloudPolicyInvalidatorTest::GetCount(
+ MetricPolicyRefresh metric) {
+ return GetHistogramSamples(kMetricPolicyRefresh)->GetCount(metric) -
+ refresh_samples_->GetCount(metric);
+}
+
+base::HistogramBase::Count CloudPolicyInvalidatorTest::GetCount(
+ MetricPolicyInvalidations metric) {
+ return GetHistogramSamples(kMetricPolicyInvalidations)->GetCount(metric) -
+ invalidations_samples_->GetCount(metric);
+}
+
+void CloudPolicyInvalidatorTest::Invalidate() {
+ ++invalidate_callback_count_;
+}
+
+const invalidation::ObjectId& CloudPolicyInvalidatorTest::GetPolicyObjectId(
+ PolicyObject object) const {
+ EXPECT_TRUE(object == POLICY_OBJECT_A || object == POLICY_OBJECT_B);
+ return object == POLICY_OBJECT_A ? object_id_a_ : object_id_b_;
+}
+
+scoped_ptr<base::HistogramSamples>
+ CloudPolicyInvalidatorTest::GetHistogramSamples(
+ const std::string& name) const {
+ base::HistogramBase* histogram =
+ base::StatisticsRecorder::FindHistogram(name);
+ if (!histogram)
+ return scoped_ptr<base::HistogramSamples>(new base::SampleMap());
+ return histogram->SnapshotSamples();
+}
+
+TEST_F(CloudPolicyInvalidatorTest, RegisterOnStoreLoaded) {
+ // No registration when store is not loaded.
+ StartInvalidator();
+ FireInvalidation(POLICY_OBJECT_A);
+ FireInvalidation(POLICY_OBJECT_B);
+ ExpectInvalidateNotCalled();
+
+ // No registration when store is loaded with no invalidation object id.
+ StorePolicy(POLICY_OBJECT_NONE);
+ FireInvalidation(POLICY_OBJECT_A);
+ FireInvalidation(POLICY_OBJECT_B);
+ ExpectInvalidateNotCalled();
+
+ // Check registration when store is loaded for object A.
+ StorePolicy(POLICY_OBJECT_A);
+ FireInvalidation(POLICY_OBJECT_A);
+ ExpectInvalidateCalled();
+ FireInvalidation(POLICY_OBJECT_B);
+ ExpectInvalidateNotCalled();
+}
+
+TEST_F(CloudPolicyInvalidatorTest, ChangeRegistration) {
+ // Register for object A.
+ StartInvalidator();
+ StorePolicy(POLICY_OBJECT_A);
+ FireInvalidation(POLICY_OBJECT_A);
+ ExpectInvalidateCalled();
+ FireInvalidation(POLICY_OBJECT_B);
+ ExpectInvalidateNotCalled();
+ syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A);
+
+ // Check re-registration for object B. Make sure the pending invalidation for
+ // object A is acknowledged without making the callback.
+ StorePolicy(POLICY_OBJECT_B);
+ EXPECT_TRUE(IsInvalidationAcknowledged(ack));
+ ExpectInvalidateNotCalled();
+
+ // Make sure future invalidations for object A are ignored and for object B
+ // are processed.
+ FireInvalidation(POLICY_OBJECT_A);
+ ExpectInvalidateNotCalled();
+ FireInvalidation(POLICY_OBJECT_B);
+ ExpectInvalidateCalled();
+}
+
+TEST_F(CloudPolicyInvalidatorTest, UnregisterOnStoreLoaded) {
+ // Register for object A.
+ StartInvalidator();
+ StorePolicy(POLICY_OBJECT_A);
+ FireInvalidation(POLICY_OBJECT_A);
+ ExpectInvalidateCalled();
+
+ // Check unregistration when store is loaded with no invalidation object id.
+ StorePolicy(POLICY_OBJECT_NONE);
+ FireInvalidation(POLICY_OBJECT_A);
+ FireInvalidation(POLICY_OBJECT_B);
+ ExpectInvalidateNotCalled();
+
+ // Check re-registration for object B.
+ StorePolicy(POLICY_OBJECT_B);
+ FireInvalidation(POLICY_OBJECT_B);
+ ExpectInvalidateCalled();
+}
+
+TEST_F(CloudPolicyInvalidatorTest, HandleInvalidation) {
+ // Register and fire invalidation
+ StorePolicy(POLICY_OBJECT_A);
+ StartInvalidator();
+ syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 12, "test_payload");
+
+ // Make sure client info is set as soon as the invalidation is received.
+ ExpectClientInvalidationInfo(12, "test_payload");
+ ExpectInvalidateCalled(false /* unknown_version */);
+
+ // Make sure invalidation is not acknowledged until the store is loaded.
+ EXPECT_FALSE(IsInvalidationAcknowledged(ack));
+ ExpectClientInvalidationInfo(12, "test_payload");
+ StorePolicy(POLICY_OBJECT_A, 12);
+ EXPECT_TRUE(IsInvalidationAcknowledged(ack));
+ ExpectClientInvalidationInfo(0, std::string());
+}
+
+TEST_F(CloudPolicyInvalidatorTest, HandleInvalidationWithUnknownVersion) {
+ // Register and fire invalidation with unknown version.
+ StorePolicy(POLICY_OBJECT_A);
+ StartInvalidator();
+ syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A);
+
+ // Make sure client info is not set until after the invalidation callback is
+ // made.
+ ExpectClientInvalidationInfo(0, std::string());
+ ExpectInvalidateCalled();
+ ExpectClientInvalidationInfo(-1, std::string());
+
+ // Make sure invalidation is not acknowledged until the store is loaded.
+ EXPECT_FALSE(IsInvalidationAcknowledged(ack));
+ StorePolicy(POLICY_OBJECT_A, -1);
+ EXPECT_TRUE(IsInvalidationAcknowledged(ack));
+ ExpectClientInvalidationInfo(0, std::string());
+}
+
+TEST_F(CloudPolicyInvalidatorTest, Unregister) {
+ StorePolicy(POLICY_OBJECT_A);
+ StartInvalidator();
+ syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A);
+
+ // Make sure invalidation is acknowledged when Unregister is called, even
+ // if the store hasn't been reloaded.
+ EXPECT_FALSE(IsInvalidationAcknowledged(ack));
+ UnregisterInvalidator();
+ EXPECT_TRUE(IsInvalidationAcknowledged(ack));
+
+ // Make sure that the invalidate callback is not made.
+ ExpectInvalidateNotCalled();
+}
+
+TEST_F(CloudPolicyInvalidatorTest, HandleMultipleInvalidations) {
+ // Generate multiple invalidations.
+ StorePolicy(POLICY_OBJECT_A);
+ StartInvalidator();
+ syncer::AckHandle ack1 = FireInvalidation(POLICY_OBJECT_A, 1, "test1");
+ ExpectClientInvalidationInfo(1, "test1");
+ syncer::AckHandle ack2 = FireInvalidation(POLICY_OBJECT_A, 2, "test2");
+ ExpectClientInvalidationInfo(2, "test2");
+ syncer::AckHandle ack3= FireInvalidation(POLICY_OBJECT_A, 3, "test3");
+ ExpectClientInvalidationInfo(3, "test3");
+
+ // Make sure the replaced invalidations are acknowledged.
+ EXPECT_TRUE(IsInvalidationAcknowledged(ack1));
+ EXPECT_TRUE(IsInvalidationAcknowledged(ack2));
+
+ // Make sure the invalidate callback is called once.
+ ExpectInvalidateCalled(false /* unknown_version */);
+
+ // Make sure that the last invalidation is only acknowledged after the store
+ // is loaded with the latest version.
+ StorePolicy(POLICY_OBJECT_A, 1);
+ EXPECT_FALSE(IsInvalidationAcknowledged(ack3));
+ StorePolicy(POLICY_OBJECT_A, 2);
+ EXPECT_FALSE(IsInvalidationAcknowledged(ack3));
+ StorePolicy(POLICY_OBJECT_A, 3);
+ EXPECT_TRUE(IsInvalidationAcknowledged(ack3));
+}
+
+TEST_F(CloudPolicyInvalidatorTest,
+ HandleMultipleInvalidationsWithUnknownVersion) {
+ // Validate that multiple invalidations with unknown version each generate
+ // unique invalidation version numbers.
+ StorePolicy(POLICY_OBJECT_A);
+ StartInvalidator();
+ syncer::AckHandle ack1 = FireInvalidation(POLICY_OBJECT_A);
+ ExpectClientInvalidationInfo(0, std::string());
+ ExpectInvalidateCalled();
+ ExpectClientInvalidationInfo(-1, std::string());
+ syncer::AckHandle ack2 = FireInvalidation(POLICY_OBJECT_A);
+ ExpectClientInvalidationInfo(0, std::string());
+ ExpectInvalidateCalled();
+ ExpectClientInvalidationInfo(-2, std::string());
+ syncer::AckHandle ack3 = FireInvalidation(POLICY_OBJECT_A);
+ ExpectClientInvalidationInfo(0, std::string());
+ ExpectInvalidateCalled();
+ ExpectClientInvalidationInfo(-3, std::string());
+
+ // Make sure the replaced invalidations are acknowledged.
+ EXPECT_TRUE(IsInvalidationAcknowledged(ack1));
+ EXPECT_TRUE(IsInvalidationAcknowledged(ack2));
+
+ // Make sure that the last invalidation is only acknowledged after the store
+ // is loaded with the last unknown version.
+ StorePolicy(POLICY_OBJECT_A, -1);
+ EXPECT_FALSE(IsInvalidationAcknowledged(ack3));
+ StorePolicy(POLICY_OBJECT_A, -2);
+ EXPECT_FALSE(IsInvalidationAcknowledged(ack3));
+ StorePolicy(POLICY_OBJECT_A, -3);
+ EXPECT_TRUE(IsInvalidationAcknowledged(ack3));
+}
+
+TEST_F(CloudPolicyInvalidatorTest, AcknowledgeBeforeInvalidateCallback) {
+ // Generate an invalidation.
+ StorePolicy(POLICY_OBJECT_A);
+ StartInvalidator();
+ syncer::AckHandle ack = FireInvalidation(POLICY_OBJECT_A, 3, "test");
+
+ // Ensure that the invalidate callback is not made and the invalidation is
+ // acknowledged if the store is loaded with the latest version before the
+ // callback is invoked.
+ StorePolicy(POLICY_OBJECT_A, 3);
+ EXPECT_TRUE(IsInvalidationAcknowledged(ack));
+ ExpectInvalidateNotCalled();
+}
+
+TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsUnregistered) {
+ // Store loads occurring before invalidation registration are not counted.
+ StartInvalidator();
+ StorePolicy(POLICY_OBJECT_NONE, 0, false /* policy_changed */);
+ StorePolicy(POLICY_OBJECT_NONE, 0, true /* policy_changed */);
+ EXPECT_EQ(0, GetCount(kMetricPolicyRefreshChanged));
+ EXPECT_EQ(0, GetCount(kMetricPolicyRefreshUnchanged));
+ EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedChanged));
+ EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedUnchanged));
+}
+
+TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsStoreSameTimestamp) {
+ // Store loads with the same timestamp as the load which causes registration
+ // are not counted.
+ StartInvalidator();
+ StorePolicy(
+ POLICY_OBJECT_A, 0, false /* policy_changed */, 12 /* timestamp */);
+ StorePolicy(
+ POLICY_OBJECT_A, 0, false /* policy_changed */, 12 /* timestamp */);
+ StorePolicy(
+ POLICY_OBJECT_A, 0, true /* policy_changed */, 12 /* timestamp */);
+
+ // The next load with a different timestamp counts.
+ StorePolicy(
+ POLICY_OBJECT_A, 0, true /* policy_changed */, 13 /* timestamp */);
+
+ EXPECT_EQ(1, GetCount(kMetricPolicyRefreshChanged));
+ EXPECT_EQ(0, GetCount(kMetricPolicyRefreshUnchanged));
+ EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedChanged));
+ EXPECT_EQ(0, GetCount(kMetricPolicyRefreshInvalidatedUnchanged));
+}
+
+TEST_F(CloudPolicyInvalidatorTest, RefreshMetricsInvalidation) {
+ // Store loads after an invalidation are counted as invalidated, even if
+ // the loads do not result in the invalidation being acknowledged.
+ StartInvalidator();
+ StorePolicy(POLICY_OBJECT_A);
+ FireInvalidation(POLICY_OBJECT_A, 5, "test");
+ StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
+ StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
+ StorePolicy(POLICY_OBJECT_A, 5, true /* policy_changed */);
+
+ // Store loads after the invalidation is complete are not counted as
+ // invalidated.
+ StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
+ StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
+ StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
+ StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
+ StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
+ StorePolicy(POLICY_OBJECT_A, 0, true /* policy_changed */);
+ StorePolicy(POLICY_OBJECT_A, 0, false /* policy_changed */);
+
+ EXPECT_EQ(3, GetCount(kMetricPolicyRefreshChanged));
+ EXPECT_EQ(4, GetCount(kMetricPolicyRefreshUnchanged));
+ EXPECT_EQ(2, GetCount(kMetricPolicyRefreshInvalidatedChanged));
+ EXPECT_EQ(1, GetCount(kMetricPolicyRefreshInvalidatedUnchanged));
+}
+
+TEST_F(CloudPolicyInvalidatorTest, InvalidationMetrics) {
+ // Generate a mix of versioned and unknown-version invalidations.
+ StorePolicy(POLICY_OBJECT_A);
+ StartInvalidator();
+ FireInvalidation(POLICY_OBJECT_B);
+ FireInvalidation(POLICY_OBJECT_A);
+ FireInvalidation(POLICY_OBJECT_B, 1, "test");
+ FireInvalidation(POLICY_OBJECT_A, 1, "test");
+ FireInvalidation(POLICY_OBJECT_A, 2, "test");
+ FireInvalidation(POLICY_OBJECT_A);
+ FireInvalidation(POLICY_OBJECT_A);
+ FireInvalidation(POLICY_OBJECT_A, 3, "test");
+ FireInvalidation(POLICY_OBJECT_A, 4, "test");
+
+ // Verify that received invalidations metrics are correct.
+ EXPECT_EQ(3, GetCount(kMetricPolicyInvalidationsNoPayload));
+ EXPECT_EQ(4, GetCount(kMetricPolicyInvalidationsPayload));
+}
+
+} // namespace policy

Powered by Google App Engine
This is Rietveld 408576698