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

Unified Diff: chrome/browser/policy/enterprise_metrics_browsertest.cc

Issue 7345010: Tests for cloud policy UMA metrics. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reviewed, rebased Created 9 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/enterprise_metrics_browsertest.cc
diff --git a/chrome/browser/policy/enterprise_metrics_browsertest.cc b/chrome/browser/policy/enterprise_metrics_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a28e8b5b03fb67ed314d3833e8611ce733f2b073
--- /dev/null
+++ b/chrome/browser/policy/enterprise_metrics_browsertest.cc
@@ -0,0 +1,848 @@
+// Copyright (c) 2011 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/file_util.h"
+#include "base/message_loop.h"
+#include "base/metrics/histogram.h"
+#include "base/scoped_temp_dir.h"
+#include "base/time.h"
+#include "chrome/browser/policy/cloud_policy_controller.h"
+#include "chrome/browser/policy/cloud_policy_data_store.h"
+#include "chrome/browser/policy/device_management_backend.h"
+#include "chrome/browser/policy/device_management_backend_mock.h"
+#include "chrome/browser/policy/device_management_service.h"
+#include "chrome/browser/policy/device_token_fetcher.h"
+#include "chrome/browser/policy/enterprise_metrics.h"
+#include "chrome/browser/policy/mock_cloud_policy_data_store.h"
+#include "chrome/browser/policy/mock_device_management_service.h"
+#include "chrome/browser/policy/policy_notifier.h"
+#include "chrome/browser/policy/proto/device_management_backend.pb.h"
+#include "chrome/browser/policy/proto/device_management_local.pb.h"
+#include "chrome/browser/policy/user_policy_cache.h"
+#include "chrome/browser/policy/user_policy_token_cache.h"
+#include "content/browser/browser_thread.h"
+#include "net/url_request/url_request_status.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/cros/mock_cryptohome_library.h"
+#include "chrome/browser/chromeos/login/mock_signed_settings_helper.h"
+#include "chrome/browser/chromeos/login/signed_settings.h"
+#include "chrome/browser/policy/device_policy_cache.h"
+#include "chrome/browser/policy/enterprise_install_attributes.h"
+#endif
+
+namespace policy {
+
+namespace em = enterprise_management;
+
+using testing::_;
+using testing::AnyNumber;
+using testing::DoAll;
+using testing::Invoke;
+using testing::Mock;
+using testing::Return;
+using testing::SetArgPointee;
+
+namespace {
+
+// Helper with common code for tests that use the DeviceManagementBackendImpl.
+class DeviceManagementBackendTestHelper {
+ public:
+ explicit DeviceManagementBackendTestHelper(MessageLoop* loop) {
+ service_.ScheduleInitialization(0);
+ loop->RunAllPending();
+ backend_.reset(service_.CreateBackendNotMocked());
+ }
+
+ DeviceManagementService& service() {
+ return service_;
+ }
+
+ void ProcessRegisterRequest() {
+ em::DeviceRegisterRequest request;
+ DeviceRegisterResponseDelegateMock delegate;
+ EXPECT_CALL(delegate, OnError(_)).Times(AnyNumber());
+ EXPECT_CALL(delegate, HandleRegisterResponse(_)).Times(AnyNumber());
+ backend_->ProcessRegisterRequest("token", "testid", request, &delegate);
+ }
+
+ void ProcessPolicyRequest() {
+ em::DevicePolicyRequest request;
+ DevicePolicyResponseDelegateMock delegate;
+ EXPECT_CALL(delegate, OnError(_)).Times(AnyNumber());
+ EXPECT_CALL(delegate, HandlePolicyResponse(_)).Times(AnyNumber());
+ backend_->ProcessPolicyRequest("token", "testid", request, &delegate);
+ }
+
+ void UnmockCreateBackend() {
+ EXPECT_CALL(service_, CreateBackend())
+ .WillOnce(Invoke(&service_,
+ &MockDeviceManagementService::CreateBackendNotMocked));
+ }
+
+ void ExpectStartJob(net::URLRequestStatus::Status status, int response_code,
+ const std::string& data) {
+ net::ResponseCookies cookies;
+ net::URLRequestStatus url_request_status(status, 0);
+ EXPECT_CALL(service_, StartJob(_))
+ .WillOnce(MockDeviceManagementServiceRespondToJob(
+ url_request_status, response_code, cookies, data));
+ }
+
+ bool VerifyAndClearExpectations() {
+ return Mock::VerifyAndClearExpectations(&service_);
+ }
+
+ private:
+ MockDeviceManagementService service_;
+ scoped_ptr<DeviceManagementBackend> backend_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeviceManagementBackendTestHelper);
+};
+
+} // namespace
+
+// This derives from testing::Test and not from InProcessBrowserTest and is
+// linked with browser_tests. The reason is that these are just unit tests, but
+// due to the static initialization of the UMA counters they have to run each
+// in its own process to make sure the counters are not initialized before the
+// test runs, and that the StatisticsRecorder instance created for the test
+// doesn't interfere with counters in other tests.
+class EnterpriseMetricsTest : public testing::Test {
+ public:
+ EnterpriseMetricsTest()
+ : ui_thread_(BrowserThread::UI, &loop_),
+ file_thread_(BrowserThread::FILE, &loop_) {
+ EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
+ }
+
+ void SetMetricName(const std::string& metric_name) {
+ metric_name_ = metric_name;
+ if (metric_name == kMetricToken) {
+ expected_samples_.resize(kMetricTokenSize, 0);
+ } else if (metric_name == kMetricPolicy) {
+ expected_samples_.resize(kMetricPolicySize, 0);
+ } else {
+ NOTREACHED();
+ }
+ }
+
+ // Run pending tasks, and check that no unexpected samples were recorded.
+ virtual void TearDown() OVERRIDE {
+ RunAllPending();
+ EXPECT_TRUE(CheckSamples());
+ }
+
+ const FilePath& temp_dir() {
+ return temp_dir_.path();
+ }
+
+ MessageLoop* loop() {
+ return &loop_;
+ }
+
+ void RunAllPending() {
+ loop_.RunAllPending();
+ }
+
+ // Adds |sample| to the list of expected samples. Subsequent calls of
+ // CheckSamples() will expect this sample.
+ void ExpectSample(int sample) {
+ ASSERT_FALSE(metric_name_.empty());
+ ASSERT_GE(sample, 0);
+ ASSERT_LT(sample, (int) expected_samples_.size());
+ expected_samples_[sample]++;
+ }
+
+ // Checks the current recorded samples against the expected set. Returns
+ // true if they match.
+ bool CheckSamples() {
+ EXPECT_FALSE(metric_name_.empty());
+ if (metric_name_.empty())
+ return false;
+ bool expects_samples = false;
+ for (size_t i = 0; i < expected_samples_.size(); ++i) {
+ if (expected_samples_[i] > 0) {
+ expects_samples = true;
+ break;
+ }
+ }
+ // The histogram won't be available until the first sample is measured.
+ base::Histogram* histogram = NULL;
+ bool found = base::StatisticsRecorder::FindHistogram(metric_name_,
+ &histogram);
+ found = found && histogram != NULL;
+ EXPECT_EQ(expects_samples, found);
+ if (found != expects_samples)
+ return false;
+ if (histogram == NULL)
+ return true;
+
+ base::Histogram::SampleSet samples;
+ histogram->SnapshotSample(&samples);
+
+ bool result = true;
+ int sum = 0;
+ for (size_t i = 0; i < expected_samples_.size(); ++i) {
+ EXPECT_EQ(expected_samples_[i], samples.counts(i))
+ << "Mismatched sample index was " << i;
+ if (expected_samples_[i] != samples.counts(i))
+ result = false;
+ sum += expected_samples_[i];
+ }
+ EXPECT_EQ(sum, samples.TotalCount());
+ if (sum != samples.TotalCount())
+ result = false;
+ return result;
+ }
+
+ private:
+ // All the UMA counters are registed at a static global singleton, which is
+ // initialized on the constructor of base::StatisticsRecorder. This usually
+ // lives in BrowserMain, but doesn't exist in unit tests, so we create it
+ // here. The "staticness" of this class is also the reason to run each
+ // test in a separate process.
+ base::StatisticsRecorder statistics_recorder_;
+ MessageLoop loop_;
+ BrowserThread ui_thread_;
+ BrowserThread file_thread_;
+ // |metric_name_| is the UMA counter that is being tested. It must be set
+ // before any calls to ExpectSample or CheckSamples.
+ std::string metric_name_;
+ // List of expected samples.
+ std::vector<int> expected_samples_;
+ ScopedTempDir temp_dir_;
+
+ DISALLOW_COPY_AND_ASSIGN(EnterpriseMetricsTest);
+};
+
+TEST_F(EnterpriseMetricsTest, TokenFetchRequestFail) {
+ SetMetricName(kMetricToken);
+ DeviceManagementBackendTestHelper helper(loop());
+
+ helper.ExpectStartJob(net::URLRequestStatus::FAILED, -1, std::string());
+ ExpectSample(kMetricTokenFetchRequested);
+ ExpectSample(kMetricTokenFetchRequestFailed);
+ helper.ProcessRegisterRequest();
+ EXPECT_TRUE(helper.VerifyAndClearExpectations());
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, TokenFetchInvalidData) {
+ SetMetricName(kMetricToken);
+ DeviceManagementBackendTestHelper helper(loop());
+
+ helper.ExpectStartJob(net::URLRequestStatus::SUCCESS, 200, "\xff");
+ ExpectSample(kMetricTokenFetchRequested);
+ ExpectSample(kMetricTokenFetchBadResponse);
+ helper.ProcessRegisterRequest();
+ EXPECT_TRUE(helper.VerifyAndClearExpectations());
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, TokenFetchErrors) {
+ SetMetricName(kMetricToken);
+ DeviceManagementBackendTestHelper helper(loop());
+
+ struct {
+ int error_code;
+ MetricToken sample;
+ } cases[] = {
+ { 400, kMetricTokenFetchRequestFailed },
+ { 401, kMetricTokenFetchServerFailed },
+ { 403, kMetricTokenFetchManagementNotSupported },
+ { 404, kMetricTokenFetchServerFailed },
+ { 410, kMetricTokenFetchDeviceNotFound },
+ { 412, kMetricTokenFetchServerFailed },
+ { 500, kMetricTokenFetchServerFailed },
+ { 503, kMetricTokenFetchServerFailed },
+ { 902, kMetricTokenFetchServerFailed },
+ { 491, kMetricTokenFetchServerFailed },
+ { 901, kMetricTokenFetchDeviceNotFound },
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ helper.ExpectStartJob(net::URLRequestStatus::SUCCESS,
+ cases[i].error_code, std::string());
+ ExpectSample(kMetricTokenFetchRequested);
+ ExpectSample(cases[i].sample);
+ helper.ProcessRegisterRequest();
+ EXPECT_TRUE(helper.VerifyAndClearExpectations());
+ EXPECT_TRUE(CheckSamples());
+ }
+}
+
+TEST_F(EnterpriseMetricsTest, TokenFetchReceiveResponse) {
+ SetMetricName(kMetricToken);
+ DeviceManagementBackendTestHelper helper(loop());
+
+ helper.ExpectStartJob(net::URLRequestStatus::SUCCESS, 200, std::string());
+ ExpectSample(kMetricTokenFetchRequested);
+ ExpectSample(kMetricTokenFetchResponseReceived);
+ helper.ProcessRegisterRequest();
+ EXPECT_TRUE(helper.VerifyAndClearExpectations());
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, TokenFetchOK) {
+ SetMetricName(kMetricToken);
+ DeviceManagementBackendTestHelper helper(loop());
+
+ // Test token fetcher.
+ UserPolicyCache cache(temp_dir().AppendASCII("FetchTokenTest"));
+ scoped_ptr<CloudPolicyDataStore> data_store;
+ data_store.reset(CloudPolicyDataStore::CreateForUserPolicies());
+ data_store->SetupForTesting("", "fake_device_id", "fake_user_name",
+ "fake_gaia_token", true);
+ PolicyNotifier notifier;
+ DeviceTokenFetcher fetcher(&helper.service(), &cache, data_store.get(),
+ &notifier);
+
+ MockCloudPolicyDataStoreObserver observer;
+ data_store->AddObserver(&observer);
+ EXPECT_CALL(observer, OnDeviceTokenChanged()).Times(1);
+
+ std::string data;
+ em::DeviceManagementResponse response;
+ response.mutable_register_response()->set_device_management_token("token");
+ response.SerializeToString(&data);
+ helper.ExpectStartJob(net::URLRequestStatus::SUCCESS, 200, data);
+
+ // FetchToken() will reset the backend. Make sure it does the right thing.
+ helper.UnmockCreateBackend();
+
+ fetcher.FetchToken();
+
+ ExpectSample(kMetricTokenFetchRequested);
+ ExpectSample(kMetricTokenFetchResponseReceived);
+ ExpectSample(kMetricTokenFetchOK);
+ EXPECT_TRUE(helper.VerifyAndClearExpectations());
+ EXPECT_TRUE(CheckSamples());
+
+ // Cleanup.
+ data_store->RemoveObserver(&observer);
+}
+
+TEST_F(EnterpriseMetricsTest, TokenStorage) {
+ SetMetricName(kMetricToken);
+
+ FilePath path = temp_dir().AppendASCII("StoreTokenTest");
+
+ scoped_ptr<CloudPolicyDataStore> data_store;
+ data_store.reset(CloudPolicyDataStore::CreateForUserPolicies());
+ data_store->SetupForTesting("", "fake_device_id", "fake_user_name",
+ "fake_gaia_token", false);
+ UserPolicyTokenCache cache(data_store.get(), path);
+
+ // Try loading a non-existing file first.
+ cache.Load();
+ RunAllPending();
+ // No samples expected.
+ EXPECT_TRUE(CheckSamples());
+
+ // Try loading an invalid file.
+ std::string data("\xff");
+ int result = file_util::WriteFile(path, data.c_str(), data.size());
+ ASSERT_EQ((int) data.size(), result);
+
+ // Make the data store expect a load from cache again.
+ data_store->SetupForTesting("", "fake_device_id", "fake_user_name",
+ "fake_gaia_token", false);
+ cache.Load();
+ RunAllPending();
+ ExpectSample(kMetricTokenLoadFailed);
+ EXPECT_TRUE(CheckSamples());
+
+ // Test storing a valid cache.
+ data_store->SetupForTesting("token", "fake_device_id", "fake_user_name",
+ "fake_gaia_token", false);
+ cache.OnDeviceTokenChanged();
+ RunAllPending();
+ ExpectSample(kMetricTokenStoreSucceeded);
+ EXPECT_TRUE(CheckSamples());
+
+ // Test loading a valid cache.
+ // Make the data store expect a load from cache again.
+ data_store->SetupForTesting("", "fake_device_id", "fake_user_name",
+ "fake_gaia_token", false);
+ cache.Load();
+ RunAllPending();
+ ExpectSample(kMetricTokenLoadSucceeded);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, PolicyFetchRequestFails) {
+ SetMetricName(kMetricPolicy);
+ DeviceManagementBackendTestHelper helper(loop());
+
+ helper.ExpectStartJob(net::URLRequestStatus::FAILED, -1, std::string());
+ ExpectSample(kMetricPolicyFetchRequested);
+ ExpectSample(kMetricPolicyFetchRequestFailed);
+ helper.ProcessPolicyRequest();
+ EXPECT_TRUE(helper.VerifyAndClearExpectations());
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, PolicyFetchInvalidData) {
+ SetMetricName(kMetricPolicy);
+ DeviceManagementBackendTestHelper helper(loop());
+
+ helper.ExpectStartJob(net::URLRequestStatus::SUCCESS, 200, "\xff");
+ ExpectSample(kMetricPolicyFetchRequested);
+ ExpectSample(kMetricPolicyFetchBadResponse);
+ helper.ProcessPolicyRequest();
+ EXPECT_TRUE(helper.VerifyAndClearExpectations());
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, PolicyFetchErrors) {
+ SetMetricName(kMetricPolicy);
+ DeviceManagementBackendTestHelper helper(loop());
+
+ struct {
+ int error_code;
+ MetricPolicy sample;
+ } cases[] = {
+ { 400, kMetricPolicyFetchRequestFailed },
+ { 401, kMetricPolicyFetchInvalidToken },
+ { 403, kMetricPolicyFetchServerFailed },
+ { 404, kMetricPolicyFetchServerFailed },
+ { 410, kMetricPolicyFetchServerFailed },
+ { 412, kMetricPolicyFetchServerFailed },
+ { 500, kMetricPolicyFetchServerFailed },
+ { 503, kMetricPolicyFetchServerFailed },
+ { 902, kMetricPolicyFetchNotFound },
+ { 491, kMetricPolicyFetchServerFailed },
+ { 901, kMetricPolicyFetchServerFailed },
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ helper.ExpectStartJob(net::URLRequestStatus::SUCCESS, cases[i].error_code,
+ std::string());
+ ExpectSample(kMetricPolicyFetchRequested);
+ ExpectSample(cases[i].sample);
+ helper.ProcessPolicyRequest();
+ EXPECT_TRUE(helper.VerifyAndClearExpectations());
+ EXPECT_TRUE(CheckSamples());
+ }
+}
+
+TEST_F(EnterpriseMetricsTest, PolicyFetchReceiveResponse) {
+ SetMetricName(kMetricPolicy);
+ DeviceManagementBackendTestHelper helper(loop());
+
+ helper.ExpectStartJob(net::URLRequestStatus::SUCCESS, 200, std::string());
+ ExpectSample(kMetricPolicyFetchRequested);
+ ExpectSample(kMetricPolicyFetchResponseReceived);
+ helper.ProcessPolicyRequest();
+ EXPECT_TRUE(helper.VerifyAndClearExpectations());
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, PolicyFetchInvalidPolicy) {
+ SetMetricName(kMetricPolicy);
+
+ UserPolicyCache cache(temp_dir().AppendASCII("UserPolicyCacheTest"));
+ UserPolicyDiskCache::Delegate* cache_as_delegate =
+ implicit_cast<UserPolicyDiskCache::Delegate*>(&cache);
+
+ em::CachedCloudPolicyResponse response;
+ response.mutable_cloud_policy()->set_policy_data("\xff");
+ cache_as_delegate->OnDiskCacheLoaded(response);
+ ExpectSample(kMetricPolicyFetchInvalidPolicy);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, PolicyFetchTimestampInFuture) {
+ SetMetricName(kMetricPolicy);
+
+ UserPolicyCache cache(temp_dir().AppendASCII("UserPolicyCacheTest"));
+ UserPolicyDiskCache::Delegate* cache_as_delegate =
+ implicit_cast<UserPolicyDiskCache::Delegate*>(&cache);
+
+ std::string data;
+ em::PolicyData policy_data;
+ base::TimeDelta timestamp =
+ (base::Time::NowFromSystemTime() + base::TimeDelta::FromDays(1000)) -
+ base::Time::UnixEpoch();
+ policy_data.set_timestamp(timestamp.InMilliseconds());
+ policy_data.SerializeToString(&data);
+ em::CachedCloudPolicyResponse response;
+ response.mutable_cloud_policy()->set_policy_data(data);
+ cache_as_delegate->OnDiskCacheLoaded(response);
+ ExpectSample(kMetricPolicyFetchTimestampInFuture);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, PolicyFetchNotModified) {
+ SetMetricName(kMetricPolicy);
+
+ UserPolicyCache cache(temp_dir().AppendASCII("UserPolicyCacheTest"));
+ UserPolicyDiskCache::Delegate* cache_as_delegate =
+ implicit_cast<UserPolicyDiskCache::Delegate*>(&cache);
+
+ std::string data;
+ em::PolicyData policy_data;
+ policy_data.set_timestamp(0);
+ policy_data.SerializeToString(&data);
+ em::CachedCloudPolicyResponse response;
+ response.mutable_cloud_policy()->set_policy_data(data);
+ cache_as_delegate->OnDiskCacheLoaded(response);
+ ExpectSample(kMetricPolicyFetchNotModified);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, PolicyFetchOK) {
+ SetMetricName(kMetricPolicy);
+
+ UserPolicyCache cache(temp_dir().AppendASCII("UserPolicyCacheTest"));
+
+ std::string data;
+ em::PolicyData policy_data;
+ policy_data.set_timestamp(0);
+ policy_data.SerializeToString(&data);
+ em::CachedCloudPolicyResponse response;
+ cache.SetPolicy(response.cloud_policy());
+ ExpectSample(kMetricPolicyFetchOK);
+ ExpectSample(kMetricPolicyFetchNotModified);
+ EXPECT_TRUE(CheckSamples());
+ // This also triggers a store. Update the expected samples.
+ RunAllPending();
+ ExpectSample(kMetricPolicyStoreSucceeded);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, PolicyFetchBadResponse) {
+ SetMetricName(kMetricPolicy);
+
+ UserPolicyCache cache(temp_dir().AppendASCII("UserPolicyCacheTest"));
+ PolicyNotifier notifier;
+ scoped_ptr<CloudPolicyDataStore> data_store;
+ data_store.reset(CloudPolicyDataStore::CreateForUserPolicies());
+ data_store->SetupForTesting("", "fake_device_id", "fake_user_name",
+ "fake_gaia_token", true);
+ CloudPolicyController controller(NULL, &cache, NULL, data_store.get(),
+ &notifier);
+ em::DevicePolicyResponse device_policy_response;
+ controller.HandlePolicyResponse(device_policy_response);
+ ExpectSample(kMetricPolicyFetchBadResponse);
+ EXPECT_TRUE(CheckSamples());
+
+ // More bad responses.
+ em::PolicyFetchResponse* policy_fetch_response =
+ device_policy_response.add_response();
+ policy_fetch_response->set_error_code(
+ DeviceManagementBackend::kErrorServicePolicyNotFound);
+ controller.HandlePolicyResponse(device_policy_response);
+ ExpectSample(kMetricPolicyFetchBadResponse);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, PolicyStorage) {
+ SetMetricName(kMetricPolicy);
+
+ FilePath path = temp_dir().AppendASCII("UserPolicyDiskCacheTest");
+
+ scoped_refptr<UserPolicyDiskCache> cache(
+ new UserPolicyDiskCache(base::WeakPtr<UserPolicyDiskCache::Delegate>(),
+ path));
+
+ // Load empty cache.
+ cache->Load();
+ RunAllPending();
+ // No samples expected.
+ EXPECT_TRUE(CheckSamples());
+
+ // Load an invalid cache.
+ std::string data("\xff");
+ int result = file_util::WriteFile(path, data.c_str(), data.size());
+ ASSERT_EQ((int) data.size(), result);
+
+ cache->Load();
+ RunAllPending();
+ ExpectSample(kMetricPolicyLoadFailed);
+ EXPECT_TRUE(CheckSamples());
+
+ // Store a cache.
+ em::CachedCloudPolicyResponse response;
+ cache->Store(response);
+ RunAllPending();
+ ExpectSample(kMetricPolicyStoreSucceeded);
+ EXPECT_TRUE(CheckSamples());
+
+ // Load a good cache.
+ cache->Load();
+ RunAllPending();
+ ExpectSample(kMetricPolicyLoadSucceeded);
+ EXPECT_TRUE(CheckSamples());
+}
+
+#if defined(OS_CHROMEOS)
+
+namespace {
+
+// Wrapper around an instance of EnterpriseInstallAttributes that uses a
+// mock CryptohomeLibrary. The wrapped EnterpriseInstallAttributes instance
+// is expected to be used to load the attributes once.
+class TestInstallAttributes {
+ public:
+ // |user| is the user to be returned as the value of the "enterprise.user"
+ // attribute.
+ explicit TestInstallAttributes(const std::string& user)
+ : user_(user),
+ owned_("true"),
+ install_attributes_(&mock_cryptohome_library_) {}
+
+ void ExpectUsage() {
+ EXPECT_CALL(mock_cryptohome_library_, InstallAttributesIsReady())
+ .WillOnce(Return(true));
+ EXPECT_CALL(mock_cryptohome_library_, InstallAttributesIsInvalid())
+ .WillOnce(Return(false));
+ EXPECT_CALL(mock_cryptohome_library_, InstallAttributesIsFirstInstall())
+ .WillOnce(Return(false));
+ EXPECT_CALL(mock_cryptohome_library_,
+ InstallAttributesGet("enterprise.owned", _))
+ .WillOnce(DoAll(SetArgPointee<1>(owned_),
+ Return(true)));
+ EXPECT_CALL(mock_cryptohome_library_,
+ InstallAttributesGet("enterprise.user", _))
+ .WillOnce(DoAll(SetArgPointee<1>(user_),
+ Return(true)));
+ }
+
+ EnterpriseInstallAttributes* install_attributes() {
+ return &install_attributes_;
+ }
+
+ private:
+ std::string user_;
+ std::string owned_;
+ chromeos::MockCryptohomeLibrary mock_cryptohome_library_;
+ EnterpriseInstallAttributes install_attributes_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestInstallAttributes);
+};
+
+} // namespace
+
+// Helper for tests that use a DevicePolicyCache.
+class DevicePolicyCacheTestHelper {
+ public:
+ DevicePolicyCacheTestHelper()
+ : install_attributes_("user") {
+ Init();
+ }
+
+ explicit DevicePolicyCacheTestHelper(const std::string& user)
+ : install_attributes_(user) {
+ Init();
+ }
+
+ void CompleteRetrieve(chromeos::SignedSettings::ReturnCode code) {
+ device_policy_cache_->OnRetrievePolicyCompleted(code, response_);
+ }
+
+ void SetPolicy() {
+ device_policy_cache_->SetPolicy(response_);
+ }
+
+ void SetData(const std::string& data) {
+ response_.set_policy_data(data);
+ }
+
+ void SetGoodData() {
+ em::PolicyData policy_data;
+ policy_data.set_request_token("token");
+ policy_data.set_username("user");
+ policy_data.set_device_id("device_id");
+ std::string data;
+ policy_data.SerializeToString(&data);
+ response_.set_policy_data(data);
+ }
+
+ void ExpectInstallAttributes() {
+ install_attributes_.ExpectUsage();
+ }
+
+ void ExpectMockSignedSettings(chromeos::SignedSettings::ReturnCode code,
+ int expected_retrieves) {
+ install_attributes_.ExpectUsage();
+ EXPECT_CALL(mock_signed_settings_helper_, StartStorePolicyOp(_, _))
+ .WillOnce(MockSignedSettingsHelperStorePolicy(code));
+ EXPECT_CALL(mock_signed_settings_helper_, CancelCallback(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(mock_signed_settings_helper_,
+ StartRetrievePolicyOp(_)).Times(expected_retrieves);
+ }
+
+ const em::PolicyFetchResponse& response() {
+ return response_;
+ }
+
+ private:
+ void Init() {
+ data_store_.reset(CloudPolicyDataStore::CreateForUserPolicies());
+ device_policy_cache_.reset(new DevicePolicyCache(data_store_.get(),
+ install_attributes_.install_attributes(),
+ &mock_signed_settings_helper_));
+ data_store_->SetupForTesting("", "id", "user", "gaia_token", false);
+ EXPECT_CALL(mock_signed_settings_helper_, CancelCallback(_)).Times(1);
+ }
+
+ chromeos::MockSignedSettingsHelper mock_signed_settings_helper_;
+ scoped_ptr<CloudPolicyDataStore> data_store_;
+ scoped_ptr<DevicePolicyCache> device_policy_cache_;
+ em::PolicyFetchResponse response_;
+ TestInstallAttributes install_attributes_;
+
+ DISALLOW_COPY_AND_ASSIGN(DevicePolicyCacheTestHelper);
+};
+
+TEST_F(EnterpriseMetricsTest, DevicePolicyNotFound) {
+ SetMetricName(kMetricPolicy);
+ DevicePolicyCacheTestHelper helper;
+
+ helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND);
+ // No samples expected.
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, DevicePolicyBadData) {
+ SetMetricName(kMetricPolicy);
+ DevicePolicyCacheTestHelper helper;
+
+ helper.SetData("\xff");
+ helper.CompleteRetrieve(chromeos::SignedSettings::SUCCESS);
+ ExpectSample(kMetricPolicyLoadFailed);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, DevicePolicyMoreBadData) {
+ SetMetricName(kMetricPolicy);
+ DevicePolicyCacheTestHelper helper;
+
+ em::PolicyData policy_data;
+ policy_data.set_request_token("token");
+ std::string data;
+ policy_data.SerializeToString(&data);
+ helper.SetData(data);
+ helper.CompleteRetrieve(chromeos::SignedSettings::SUCCESS);
+ ExpectSample(kMetricPolicyLoadFailed);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, DevicePolicyLoad) {
+ SetMetricName(kMetricPolicy);
+ DevicePolicyCacheTestHelper helper;
+
+ helper.SetGoodData();
+ helper.CompleteRetrieve(chromeos::SignedSettings::SUCCESS);
+ ExpectSample(kMetricPolicyLoadSucceeded);
+ ExpectSample(kMetricPolicyFetchNotModified);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, DevicePolicyStoreSuccess) {
+ SetMetricName(kMetricPolicy);
+ DevicePolicyCacheTestHelper helper;
+ helper.ExpectMockSignedSettings(chromeos::SignedSettings::SUCCESS, 1);
+ helper.SetGoodData();
+ helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND);
+ helper.SetPolicy();
+ ExpectSample(kMetricPolicyStoreSucceeded);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, DevicePolicyStoreBadSignature) {
+ SetMetricName(kMetricPolicy);
+ DevicePolicyCacheTestHelper helper;
+ helper.ExpectMockSignedSettings(chromeos::SignedSettings::BAD_SIGNATURE, 0);
+ helper.SetGoodData();
+ helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND);
+ helper.SetPolicy();
+ ExpectSample(kMetricPolicyStoreFailed);
+ ExpectSample(kMetricPolicyFetchBadSignature);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, DevicePolicyStoreOperationFailed) {
+ SetMetricName(kMetricPolicy);
+ DevicePolicyCacheTestHelper helper;
+ helper.ExpectMockSignedSettings(chromeos::SignedSettings::OPERATION_FAILED,
+ 0);
+ helper.SetGoodData();
+ helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND);
+ helper.SetPolicy();
+ ExpectSample(kMetricPolicyStoreFailed);
+ ExpectSample(kMetricPolicyFetchOtherFailed);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, DevicePolicyNonEnterprise) {
+ SetMetricName(kMetricPolicy);
+ DevicePolicyCacheTestHelper helper;
+
+ scoped_ptr<CloudPolicyDataStore> data_store;
+ data_store.reset(CloudPolicyDataStore::CreateForUserPolicies());
+ EnterpriseInstallAttributes install_attributes(NULL);
+ DevicePolicyCache device_policy_cache(data_store.get(), &install_attributes);
+
+ data_store->SetupForTesting("", "id", "user", "gaia_token", false);
+ helper.SetGoodData();
+ device_policy_cache.OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::NOT_FOUND, helper.response());
+
+ device_policy_cache.SetPolicy(helper.response());
+ ExpectSample(kMetricPolicyFetchNonEnterpriseDevice);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, DevicePolicyUserMismatch) {
+ SetMetricName(kMetricPolicy);
+ DevicePolicyCacheTestHelper helper("bogus");
+ helper.ExpectInstallAttributes();
+ helper.SetGoodData();
+ helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND);
+ helper.SetPolicy();
+ ExpectSample(kMetricPolicyFetchUserMismatch);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, DevicePolicyBadSignature) {
+ SetMetricName(kMetricPolicy);
+ DevicePolicyCacheTestHelper helper;
+ helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND);
+ helper.CompleteRetrieve(chromeos::SignedSettings::BAD_SIGNATURE);
+ ExpectSample(kMetricPolicyFetchBadSignature);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, DevicePolicyOtherFailed) {
+ SetMetricName(kMetricPolicy);
+ DevicePolicyCacheTestHelper helper;
+ helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND);
+ helper.CompleteRetrieve(chromeos::SignedSettings::OPERATION_FAILED);
+ ExpectSample(kMetricPolicyFetchOtherFailed);
+ EXPECT_TRUE(CheckSamples());
+}
+
+TEST_F(EnterpriseMetricsTest, DevicePolicyFetchInvalid) {
+ SetMetricName(kMetricPolicy);
+ DevicePolicyCacheTestHelper helper;
+
+ helper.ExpectInstallAttributes();
+ helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND);
+ helper.SetData("\xff");
+ helper.SetPolicy();
+ ExpectSample(kMetricPolicyFetchInvalidPolicy);
+ EXPECT_TRUE(CheckSamples());
+}
+
+#endif
+
+} // namespace policy

Powered by Google App Engine
This is Rietveld 408576698