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

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

Issue 7345010: Tests for cloud policy UMA metrics. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase 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_unittest.cc
diff --git a/chrome/browser/policy/enterprise_metrics_unittest.cc b/chrome/browser/policy/enterprise_metrics_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9c148ee1d0463be5aa661877596dbc2e3455a9be
--- /dev/null
+++ b/chrome/browser/policy/enterprise_metrics_unittest.cc
@@ -0,0 +1,835 @@
+// 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.
+
+// These tests run in a child process because they depend on the static
+// initialization of the UMA counters. Those depend on a singleton instance of
+// base::StatisticsRecorder, which isn't available for unit_tests. Creating
+// one just for a couple of tests could lead to problems with other tests that
+// also depend on the base::StatisticsRecorder; basically, each statically
+// initialized UMA counter will belong to the StatisticsRecorder that exists
+// on the first execution of the function that contains the counter. Since we
+// can't make sure we are the first invokers of that function, we spawn a
+// child process instead that will create the StatisticsRecorder on its entry
+// function.
gfeher 2011/07/15 12:21:34 I am going to contradict one of my comments in our
Joao da Silva 2011/07/18 08:45:10 As discussed offline, the out-of-process tests wer
+
+#include <vector>
+
+#include "base/file_util.h"
+#include "base/message_loop.h"
+#include "base/metrics/histogram.h"
+#include "base/scoped_temp_dir.h"
+#include "base/test/multiprocess_test.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/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_disk_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"
+#include "testing/multiprocess_func_list.h"
+
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/cros/mock_cryptohome_library.h"
+#include "chrome/browser/chromeos/login/signed_settings.h"
+#include "chrome/browser/chromeos/login/signed_settings_helper.h"
+#include "chrome/browser/policy/device_policy_cache.h"
+#include "chrome/browser/policy/enterprise_install_attributes.h"
+#endif
+
+namespace policy {
+
+namespace em = enterprise_management;
+
+class EnterpriseMetricsTest : public base::MultiProcessTest {
+ protected:
+ EnterpriseMetricsTest() {}
+
+ void TestSubProcess(const std::string& child_name);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(EnterpriseMetricsTest);
+};
+
+void EnterpriseMetricsTest::TestSubProcess(const std::string& child_name) {
+ base::ProcessHandle handle = SpawnChild(child_name, false);
+ ASSERT_TRUE(handle);
+ int exit_code = 0;
+ EXPECT_TRUE(base::WaitForExitCode(handle, &exit_code));
+ EXPECT_EQ(exit_code, 0);
+}
+
+TEST_F(EnterpriseMetricsTest, TokenFetch) {
+ TestSubProcess("enterprise_metrics_token_fetch");
+}
+
+TEST_F(EnterpriseMetricsTest, TokenStorage) {
+ TestSubProcess("enterprise_metrics_token_storage");
+}
+
+TEST_F(EnterpriseMetricsTest, PolicyFetch) {
+ TestSubProcess("enterprise_metrics_policy_fetch");
+}
+
+TEST_F(EnterpriseMetricsTest, UserPolicyStorage) {
+ TestSubProcess("enterprise_metrics_user_policy_storage");
+}
+
+#if defined(OS_CHROMEOS)
+
+TEST_F(EnterpriseMetricsTest, DevicePolicyStorage) {
+ TestSubProcess("enterprise_metrics_device_policy_storage");
+}
+
+#endif
+
+// Tests in child processes have to return a non-zero value to signal that they
+// failed. These macros are used to return the appropriate value.
+
+// MULTIPROCESS_TEST_MAIN defines a function that returns an int, while
+// ASSERT_* macros return void, so they can't be used. Use this macro after
+// an EXPECT_* call that can't fail instead.
+#define RETURN_IF_FAILED() \
+ do { \
+ if (testing::Test::HasFailure()) \
+ return 1; \
+ } while (0)
+
+#define RETURN_CHECK_FAILED() \
+ return testing::Test::HasFailure() ? 1 : 0
+
+namespace {
+
+using testing::_;
+using testing::AnyNumber;
+using testing::DoAll;
+using testing::Return;
+using testing::SetArgumentPointee;
+
+class MockDeviceManagementService : public DeviceManagementService {
gfeher 2011/07/15 12:21:34 Have you considered reusing the existing MockDevic
Joao da Silva 2011/07/18 08:45:10 They are indeed different, wdyt of the merged vers
+ public:
+ MockDeviceManagementService()
+ : DeviceManagementService(""),
+ response_code_(-1) {
+ }
+
+ virtual void StartJob(DeviceManagementJob* job) OVERRIDE {
+ job->HandleResponse(status_, response_code_, cookies_, data_);
+ }
+
+ void set_url_request_status(const net::URLRequestStatus& status) {
+ status_ = status;
+ }
+
+ void set_response_code(int response_code) {
+ response_code_ = response_code;
+ }
+
+ void set_cookies(const net::ResponseCookies& cookies) {
+ cookies_ = cookies;
+ }
+
+ void set_data(const std::string& data) {
+ data_ = data;
+ }
+
+ private:
+ DeviceManagementJob* job_;
+ net::URLRequestStatus status_;
+ int response_code_;
+ net::ResponseCookies cookies_;
+ std::string data_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockDeviceManagementService);
+};
+
+class MockTokenAvailableObserver
+ : public policy::CloudPolicyDataStore::Observer {
+ public:
+ MockTokenAvailableObserver() {}
+ virtual ~MockTokenAvailableObserver() {}
+
+ MOCK_METHOD0(OnDeviceTokenChanged, void());
+ MOCK_METHOD0(OnCredentialsChanged, void());
+ MOCK_METHOD0(OnDataStoreGoingAway, void());
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockTokenAvailableObserver);
+};
+
+#if defined(OS_CHROMEOS)
+
+class MockSignedSettingsHelper : public chromeos::SignedSettingsHelper {
+ public:
+ MockSignedSettingsHelper() {}
+ virtual ~MockSignedSettingsHelper() {}
+
+ MOCK_METHOD2(StartCheckWhitelistOp,
+ void(const std::string& email, Callback*));
+ MOCK_METHOD3(StartWhitelistOp,
+ void(const std::string&, bool, Callback*));
+ MOCK_METHOD3(StartStorePropertyOp,
+ void(const std::string&, const std::string&, Callback*));
+ MOCK_METHOD2(StartRetrieveProperty,
+ void(const std::string&, Callback*));
+ MOCK_METHOD2(StartStorePolicyOp,
+ void(const em::PolicyFetchResponse&, Callback*));
+ MOCK_METHOD1(StartRetrievePolicyOp, void(Callback* callback));
+ MOCK_METHOD1(CancelCallback, void(Callback*));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockSignedSettingsHelper);
+};
+
+ACTION_P(MockSignedSettingsHelperStorePolicy, status_code) {
+ arg1->OnStorePolicyCompleted(status_code);
+}
+
+class TestInstallAttributes {
+ public:
+ explicit TestInstallAttributes(const std::string& user)
+ : user_(user),
+ owned_("true"),
+ install_attributes_(&mock_cryptohome_library_) {
+ 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(SetArgumentPointee<1>(owned_),
+ Return(true)));
+ EXPECT_CALL(mock_cryptohome_library_,
+ InstallAttributesGet("enterprise.user", _))
+ .WillOnce(DoAll(SetArgumentPointee<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);
+};
+
+#endif
+
+// A helper class for out-of-process tests.
+class MetricsTest {
gfeher 2011/07/15 12:21:34 Maybe call it MetricsTestHelper?
Joao da Silva 2011/07/18 08:45:10 Obsolete.
+ public:
+ explicit MetricsTest(const std::string& metric_name)
+ : ui_thread_(BrowserThread::UI, &loop_),
+ file_thread_(BrowserThread::FILE, &loop_),
+ metric_name_(metric_name) {
+ EXPECT_TRUE(temp_user_data_dir_.CreateUniqueTempDir());
+
+ if (metric_name_ == kMetricToken) {
+ samples_.resize(kMetricTokenSize, 0);
+ } else if (metric_name_ == kMetricPolicy) {
+ samples_.resize(kMetricPolicySize, 0);
+ } else {
+ NOTREACHED();
+ }
+ }
+
+ const FilePath& temp_dir() {
+ return temp_user_data_dir_.path();
+ }
+
+ void RunAllPending() {
+ loop_.RunAllPending();
+ }
+
+ void Done() {
+ RunAllPending();
+ CheckSamples("Done");
+ }
+
+ void ExpectSample(int sample) {
+ ASSERT_GE(sample, 0);
+ ASSERT_LT(sample, (int) samples_.size());
+ samples_[sample]++;
+ }
+
+ void CheckSamples(const std::string& test_case) {
+ bool expects_samples = false;
+ for (size_t i = 0; i < samples_.size(); ++i) {
+ if (samples_[i] > 0) {
+ expects_samples = true;
+ break;
+ }
+ }
+
+ // The histogram won't be available until the first sample is measured.
+ base::Histogram* histogram = NULL;
+ if (!expects_samples) {
+ EXPECT_FALSE(base::StatisticsRecorder::FindHistogram(metric_name_,
+ &histogram));
+ return;
+ }
+
+ EXPECT_TRUE(base::StatisticsRecorder::FindHistogram(metric_name_,
+ &histogram));
+ ASSERT_TRUE(histogram != NULL);
+
+ base::Histogram::SampleSet samples;
+ histogram->SnapshotSample(&samples);
+
+ size_t sum = 0;
+ for (size_t i = 0; i < samples_.size(); ++i) {
+ EXPECT_EQ(samples_[i], samples.counts(i))
+ << "Mismatch for " << test_case << ", i is " << i;
+ sum += samples_[i];
+ }
+ EXPECT_EQ(sum, (size_t) samples.TotalCount());
+ }
+
+ private:
+ base::StatisticsRecorder statistics_recorder_;
+ MessageLoop loop_;
+ ScopedTempDir temp_user_data_dir_;
+ BrowserThread ui_thread_;
+ BrowserThread file_thread_;
+ std::string metric_name_;
+ std::vector<int> samples_;
gfeher 2011/07/15 12:21:34 Call this expected_samples_?
Joao da Silva 2011/07/18 08:45:10 Done.
+
+ DISALLOW_COPY_AND_ASSIGN(MetricsTest);
+};
+
+} // namespace
+
+MULTIPROCESS_TEST_MAIN(enterprise_metrics_token_fetch) {
+ MetricsTest test(kMetricToken);
+ RETURN_IF_FAILED();
+
+ MockDeviceManagementService service;
+ service.ScheduleInitialization(0);
+ test.RunAllPending();
+ scoped_ptr<DeviceManagementBackend> backend(service.CreateBackend());
+
+ em::DeviceRegisterRequest request;
+ DeviceRegisterResponseDelegateMock delegate;
+ EXPECT_CALL(delegate, OnError(_)).Times(AnyNumber());
+ EXPECT_CALL(delegate, HandleRegisterResponse(_)).Times(AnyNumber());
+ net::URLRequestStatus status;
+
+ // Test failed requests.
+ status.set_status(net::URLRequestStatus::FAILED);
+ service.set_url_request_status(status);
+ test.ExpectSample(kMetricTokenFetchRequested);
+ test.ExpectSample(kMetricTokenFetchRequestFailed);
+ backend->ProcessRegisterRequest("token", "testid", request, &delegate);
+ test.CheckSamples("FailedRequest");
+
+ // Test invalid data.
+ std::string data("\xff");
+ status.set_status(net::URLRequestStatus::SUCCESS);
+ service.set_url_request_status(status);
+ service.set_response_code(200);
+ service.set_data(data);
+ test.ExpectSample(kMetricTokenFetchRequested);
+ test.ExpectSample(kMetricTokenFetchBadResponse);
+ backend->ProcessRegisterRequest("token", "testid", request, &delegate);
+ test.CheckSamples("BadData");
+
+ // Test various error cases.
+ struct {
+ const char* test_case;
+ int error_code;
+ MetricToken sample;
+ } cases[] = {
+ { "400", 400, kMetricTokenFetchRequestFailed },
+ { "401", 401, kMetricTokenFetchServerFailed },
+ { "403", 403, kMetricTokenFetchManagementNotSupported },
+ { "404", 404, kMetricTokenFetchServerFailed },
+ { "410", 410, kMetricTokenFetchDeviceNotFound },
+ { "412", 412, kMetricTokenFetchServerFailed },
+ { "500", 500, kMetricTokenFetchServerFailed },
+ { "503", 503, kMetricTokenFetchServerFailed },
+ { "902", 902, kMetricTokenFetchServerFailed },
+ { "491", 491, kMetricTokenFetchServerFailed },
+ { "901", 901, kMetricTokenFetchDeviceNotFound },
+ };
+
+ service.set_data(std::string());
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ service.set_response_code(cases[i].error_code);
+ test.ExpectSample(kMetricTokenFetchRequested);
+ test.ExpectSample(cases[i].sample);
+ backend->ProcessRegisterRequest("token", "testid", request, &delegate);
+ test.CheckSamples(cases[i].test_case);
+ }
+
+ // Test successful token retrieval.
+ service.set_response_code(200);
+ test.ExpectSample(kMetricTokenFetchRequested);
+ test.ExpectSample(kMetricTokenFetchResponseReceived);
+ backend->ProcessRegisterRequest("token", "testid", request, &delegate);
+ test.CheckSamples("ResponseReceived");
+
+ // Test token fetcher.
+ UserPolicyCache cache(test.temp_dir().AppendASCII("FetchTokenTest"));
+ scoped_ptr<CloudPolicyDataStore> data_store;
+ data_store.reset(CloudPolicyDataStore::CreateForUserPolicies());
+ data_store->SetupForTesting("", "fake_device_id", "fake_user_name",
+ "fake_auth_token", true);
+ PolicyNotifier notifier;
+ DeviceTokenFetcher fetcher(&service, &cache, data_store.get(), &notifier);
+
+ MockTokenAvailableObserver observer;
+ data_store->AddObserver(&observer);
+ EXPECT_CALL(observer, OnDeviceTokenChanged()).Times(1);
+
+ em::DeviceManagementResponse response;
+ response.mutable_register_response()->set_device_management_token("token");
+ response.SerializeToString(&data);
+ service.set_data(data);
+
+ fetcher.FetchToken();
+
+ test.ExpectSample(kMetricTokenFetchRequested);
+ test.ExpectSample(kMetricTokenFetchResponseReceived);
+ test.ExpectSample(kMetricTokenFetchOK);
+ test.CheckSamples("FetchOK");
+
+ // Cleanup.
+ data_store->RemoveObserver(&observer);
+
+ test.Done();
+ RETURN_CHECK_FAILED();
+}
+
+MULTIPROCESS_TEST_MAIN(enterprise_metrics_token_storage) {
+ MetricsTest test(kMetricToken);
+ RETURN_IF_FAILED();
+
+ FilePath path = test.temp_dir().AppendASCII("StoreTokenTest");
+
+ scoped_ptr<CloudPolicyDataStore> data_store;
+ data_store.reset(CloudPolicyDataStore::CreateForUserPolicies());
+ data_store->SetupForTesting("", "fake_device_id", "fake_user_name",
+ "fake_auth_token", false);
+ UserPolicyTokenCache cache(data_store.get(), path);
+
+ // Try loading a non-existing file first.
+ cache.Load();
+ test.RunAllPending();
+ // No samples expected.
+ test.CheckSamples("LoadEmpty");
+
+ // Try loading an invalid file.
+ std::string data("\xff");
+ int result = file_util::WriteFile(path, data.c_str(), data.size());
+ EXPECT_EQ((int) data.size(), result);
+ RETURN_IF_FAILED();
+
+ // Make the data store expect a load from cache again.
+ data_store->SetupForTesting("", "fake_device_id", "fake_user_name",
+ "fake_auth_token", false);
+ cache.Load();
+ test.RunAllPending();
+ test.ExpectSample(kMetricTokenLoadFailed);
+ test.CheckSamples("LoadFailed");
+
+ // Test storing a valid cache.
+ data_store->SetupForTesting("token", "fake_device_id", "fake_user_name",
+ "fake_auth_token", false);
+ cache.OnDeviceTokenChanged();
+ test.RunAllPending();
+ test.ExpectSample(kMetricTokenStoreSucceeded);
+ test.CheckSamples("StoreSucceeded");
+
+ // 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_auth_token", false);
+ cache.Load();
+ test.RunAllPending();
+ test.ExpectSample(kMetricTokenLoadSucceeded);
+ test.CheckSamples("LoadSucceeded");
+
+ test.Done();
+ RETURN_CHECK_FAILED();
+}
+
+MULTIPROCESS_TEST_MAIN(enterprise_metrics_policy_fetch) {
+ MetricsTest test(kMetricPolicy);
+ RETURN_IF_FAILED();
+
+ MockDeviceManagementService service;
+ service.ScheduleInitialization(0);
+ test.RunAllPending();
+ scoped_ptr<DeviceManagementBackend> backend(service.CreateBackend());
+
+ em::DevicePolicyRequest request;
+ DevicePolicyResponseDelegateMock delegate;
+ EXPECT_CALL(delegate, OnError(_)).Times(AnyNumber());
+ EXPECT_CALL(delegate, HandlePolicyResponse(_)).Times(AnyNumber());
+ net::URLRequestStatus status;
+
+ // Test failed requests.
+ status.set_status(net::URLRequestStatus::FAILED);
+ service.set_url_request_status(status);
+ test.ExpectSample(kMetricPolicyFetchRequested);
+ test.ExpectSample(kMetricPolicyFetchRequestFailed);
+ backend->ProcessPolicyRequest("token", "testid", request, &delegate);
+ test.CheckSamples("FailedRequest");
+
+ // Test invalid data.
+ std::string data("\xff");
+ status.set_status(net::URLRequestStatus::SUCCESS);
+ service.set_url_request_status(status);
+ service.set_response_code(200);
+ service.set_data(data);
+ test.ExpectSample(kMetricPolicyFetchRequested);
+ test.ExpectSample(kMetricPolicyFetchBadResponse);
+ backend->ProcessPolicyRequest("token", "testid", request, &delegate);
+ test.CheckSamples("BadData");
+
+ // Test various error cases.
+ struct {
+ const char* test_case;
+ int error_code;
+ MetricPolicy sample;
+ } cases[] = {
+ { "400", 400, kMetricPolicyFetchRequestFailed },
+ { "401", 401, kMetricPolicyFetchInvalidToken },
+ { "403", 403, kMetricPolicyFetchServerFailed },
+ { "404", 404, kMetricPolicyFetchServerFailed },
+ { "410", 410, kMetricPolicyFetchServerFailed },
+ { "412", 412, kMetricPolicyFetchServerFailed },
+ { "500", 500, kMetricPolicyFetchServerFailed },
+ { "503", 503, kMetricPolicyFetchServerFailed },
+ { "902", 902, kMetricPolicyFetchNotFound },
+ { "491", 491, kMetricPolicyFetchServerFailed },
+ { "901", 901, kMetricPolicyFetchServerFailed },
+ };
+
+ service.set_data(std::string());
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ service.set_response_code(cases[i].error_code);
+ test.ExpectSample(kMetricPolicyFetchRequested);
+ test.ExpectSample(cases[i].sample);
+ backend->ProcessPolicyRequest("token", "testid", request, &delegate);
+ test.CheckSamples(cases[i].test_case);
+ }
+
+ // Test successful policy retrieval.
+ service.set_response_code(200);
+ test.ExpectSample(kMetricPolicyFetchRequested);
+ test.ExpectSample(kMetricPolicyFetchResponseReceived);
+ backend->ProcessPolicyRequest("token", "testid", request, &delegate);
+ test.CheckSamples("ResponseReceived");
+
+ // Test fetching an invalid policy.
+ UserPolicyCache cache(test.temp_dir().AppendASCII("UserPolicyCacheTest"));
+ // This is to bypass the private method override in UserPolicyCache:
+ UserPolicyDiskCache::Delegate* cache_as_delegate =
+ implicit_cast<UserPolicyDiskCache::Delegate*>(&cache);
+
+ em::CachedCloudPolicyResponse response;
+ response.mutable_cloud_policy()->set_policy_data(data);
+ cache_as_delegate->OnDiskCacheLoaded(response);
+ test.ExpectSample(kMetricPolicyFetchInvalidPolicy);
+ test.CheckSamples("InvalidPolicy");
+
+ // Test timestamp in future.
+ 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);
+ response.mutable_cloud_policy()->set_policy_data(data);
+ cache_as_delegate->OnDiskCacheLoaded(response);
+ test.ExpectSample(kMetricPolicyFetchTimestampInFuture);
+ test.CheckSamples("TimestampInFuture");
+
+ // Test policy not modified.
+ policy_data.set_timestamp(0);
+ policy_data.SerializeToString(&data);
+ response.mutable_cloud_policy()->set_policy_data(data);
+ cache_as_delegate->OnDiskCacheLoaded(response);
+ test.ExpectSample(kMetricPolicyFetchNotModified);
+ test.CheckSamples("NotModified");
+
+ // Test fetch OK.
+ cache.SetPolicy(response.cloud_policy());
+ test.ExpectSample(kMetricPolicyFetchOK);
+ test.ExpectSample(kMetricPolicyFetchNotModified);
+ test.CheckSamples("FetchOK");
+ // This also triggers a store. Update the expected samples.
+ test.RunAllPending();
+ test.ExpectSample(kMetricPolicyStoreSucceeded);
+ test.CheckSamples("FetchOKAndStore");
+
+ // Test bad responses.
+ PolicyNotifier notifier;
+ scoped_ptr<CloudPolicyDataStore> data_store;
+ data_store.reset(CloudPolicyDataStore::CreateForUserPolicies());
+ data_store->SetupForTesting("", "fake_device_id", "fake_user_name",
+ "fake_auth_token", true);
+ CloudPolicyController controller(NULL, &cache, NULL, data_store.get(),
+ &notifier);
+ em::DevicePolicyResponse device_policy_response;
+ controller.HandlePolicyResponse(device_policy_response);
+ test.ExpectSample(kMetricPolicyFetchBadResponse);
+ test.CheckSamples("BadResponse");
+
+ // 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);
+ test.ExpectSample(kMetricPolicyFetchBadResponse);
+ test.CheckSamples("BadResponse2");
+
+ test.Done();
+ RETURN_CHECK_FAILED();
+}
+
+MULTIPROCESS_TEST_MAIN(enterprise_metrics_user_policy_storage) {
+ MetricsTest test(kMetricPolicy);
+ RETURN_IF_FAILED();
+
+ FilePath path = test.temp_dir().AppendASCII("UserPolicyDiskCacheTest");
+
+ scoped_refptr<UserPolicyDiskCache> cache(
+ new UserPolicyDiskCache(base::WeakPtr<UserPolicyDiskCache::Delegate>(),
+ path));
+
+ // Load empty cache.
+ cache->Load();
+ test.RunAllPending();
+ // No samples expected.
+ test.CheckSamples("NoCache");
+
+ // Load an invalid cache.
+ std::string data("\xff");
+ int result = file_util::WriteFile(path, data.c_str(), data.size());
+ EXPECT_EQ((int) data.size(), result);
+ RETURN_IF_FAILED();
+
+ cache->Load();
+ test.RunAllPending();
+ test.ExpectSample(kMetricPolicyLoadFailed);
+ test.CheckSamples("InvalidCache");
+
+ // Store a cache.
+ em::CachedCloudPolicyResponse response;
+ cache->Store(response);
+ test.RunAllPending();
+ test.ExpectSample(kMetricPolicyStoreSucceeded);
+ test.CheckSamples("StoreCache");
+
+ // Load a good cache.
+ cache->Load();
+ test.RunAllPending();
+ test.ExpectSample(kMetricPolicyLoadSucceeded);
+ test.CheckSamples("LoadCache");
+
+ test.Done();
+ RETURN_CHECK_FAILED();
+}
+
+#if defined(OS_CHROMEOS)
+
+MULTIPROCESS_TEST_MAIN(enterprise_metrics_device_policy_storage) {
+ MetricsTest test(kMetricPolicy);
+ RETURN_IF_FAILED();
+
+ scoped_ptr<CloudPolicyDataStore> data_store;
+ data_store.reset(CloudPolicyDataStore::CreateForUserPolicies());
+ // The DevicePolicyCache is reset to a new object to have
+ // |starting_up_| set to true again, and test the loading path.
+ scoped_ptr<DevicePolicyCache> device_policy_cache;
+ em::PolicyFetchResponse response;
+
+ // Test non-existing policy.
+ device_policy_cache.reset(new DevicePolicyCache(data_store.get(), NULL));
+ data_store->SetupForTesting("", "id", "user", "token", false);
+ device_policy_cache->OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::NOT_FOUND, response);
+ // No samples expected.
+ test.CheckSamples("NoPolicy");
+
+ // Test bad policy data.
+ response.set_policy_data(std::string("\xff"));
+ device_policy_cache.reset(new DevicePolicyCache(data_store.get(), NULL));
+ data_store->SetupForTesting("", "id", "user", "token", false);
+ device_policy_cache->OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::SUCCESS, response);
+ test.ExpectSample(kMetricPolicyLoadFailed);
+ test.CheckSamples("BadPolicyData");
+
+ // Test more bad policy data.
+ em::PolicyData policy_data;
+ policy_data.set_request_token("token");
+ std::string policy_data_string;
+ policy_data.SerializeToString(&policy_data_string);
+ response.set_policy_data(policy_data_string);
+ device_policy_cache.reset(new DevicePolicyCache(data_store.get(), NULL));
+ data_store->SetupForTesting("", "id", "user", "token", false);
+ device_policy_cache->OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::SUCCESS, response);
+ test.ExpectSample(kMetricPolicyLoadFailed);
+ test.CheckSamples("BadPolicyData2");
+
+ // Test good policy data.
+ policy_data.set_username("user");
+ policy_data.set_device_id("device_id");
+ policy_data.SerializeToString(&policy_data_string);
+ response.set_policy_data(policy_data_string);
+ device_policy_cache.reset(new DevicePolicyCache(data_store.get(), NULL));
+ data_store->SetupForTesting("", "id", "user", "token", false);
+ device_policy_cache->OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::SUCCESS, response);
+ test.ExpectSample(kMetricPolicyLoadSucceeded);
+ // There is no policy data though.
+ test.ExpectSample(kMetricPolicyFetchNotModified);
+ test.CheckSamples("LoadSucceeded");
+
+ // Test storing the device policy.
+ struct {
+ const char* case_name;
+ chromeos::SignedSettings::ReturnCode return_code;
+ int expected_retrieve;
+ int expected_sample;
+ int expected_sample2;
+ } cases[] = {
+ { "StoreSuceeded", chromeos::SignedSettings::SUCCESS, 1,
+ kMetricPolicyStoreSucceeded, -1 },
+ { "StoreBadSignature", chromeos::SignedSettings::BAD_SIGNATURE, 0,
+ kMetricPolicyStoreFailed, kMetricPolicyFetchBadSignature },
+ { "StoreOtherFailed", chromeos::SignedSettings::OPERATION_FAILED, 0,
+ kMetricPolicyStoreFailed, kMetricPolicyFetchOtherFailed },
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ TestInstallAttributes install_attributes("user");
+ MockSignedSettingsHelper mock_signed_settings_helper;
+
+ device_policy_cache.reset(
+ new DevicePolicyCache(data_store.get(),
+ install_attributes.install_attributes(), &mock_signed_settings_helper));
+
+ EXPECT_CALL(mock_signed_settings_helper, StartStorePolicyOp(_, _)).WillOnce(
+ MockSignedSettingsHelperStorePolicy(cases[i].return_code));
+ EXPECT_CALL(mock_signed_settings_helper, CancelCallback(_)).Times(2);
+ EXPECT_CALL(mock_signed_settings_helper,
+ StartRetrievePolicyOp(_)).Times(cases[i].expected_retrieve);
+
+ // Make the cache have |starting_up_| set to false.
+ data_store->SetupForTesting("", "id", "user", "token", false);
+ device_policy_cache->OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::NOT_FOUND, response);
+ // Now trigger the store.
+ device_policy_cache->SetPolicy(response);
+ test.ExpectSample(cases[i].expected_sample);
+ if (cases[i].expected_sample2 >= 0)
+ test.ExpectSample(cases[i].expected_sample2);
+ test.CheckSamples(cases[i].case_name);
+
+ // Cleanup while the MockSignedSettingsHelper is alive.
+ device_policy_cache.reset();
+ }
+
+ // Test setting policy on non-enterprise device.
+ {
+ EnterpriseInstallAttributes install_attributes(NULL);
+ device_policy_cache.reset(new DevicePolicyCache(data_store.get(),
+ &install_attributes));
+ // Make the cache have |starting_up_| set to false.
+ data_store->SetupForTesting("", "id", "user", "token", false);
+ device_policy_cache->OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::NOT_FOUND, response);
+ // Now trigger the error.
+ device_policy_cache->SetPolicy(response);
+ test.ExpectSample(kMetricPolicyFetchNonEnterpriseDevice);
+ test.CheckSamples("NonEnterprise");
+ }
+
+ // Test user-mismatch between device and policy.
+ {
+ TestInstallAttributes install_attributes("bogus");
+ device_policy_cache.reset(new DevicePolicyCache(data_store.get(),
+ install_attributes.install_attributes()));
+ // Make the cache have |starting_up_| set to false.
+ data_store->SetupForTesting("", "id", "user", "token", false);
+ device_policy_cache->OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::NOT_FOUND, response);
+ // Now trigger the store.
+ device_policy_cache->SetPolicy(response);
+ test.ExpectSample(kMetricPolicyFetchUserMismatch);
+ test.CheckSamples("UserMismatch");
+ }
+
+ // Test bad signature.
+ device_policy_cache.reset(new DevicePolicyCache(data_store.get(), NULL));
+ // Make the cache have |starting_up_| set to false.
+ data_store->SetupForTesting("", "id", "user", "token", false);
+ device_policy_cache->OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::NOT_FOUND, response);
+ // Now trigger the store.
+ device_policy_cache->OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::BAD_SIGNATURE, response);
+ test.ExpectSample(kMetricPolicyFetchBadSignature);
+ test.CheckSamples("BadSignature");
+
+ // Test other failures.
+ device_policy_cache.reset(new DevicePolicyCache(data_store.get(), NULL));
+ // Make the cache have |starting_up_| set to false.
+ data_store->SetupForTesting("", "id", "user", "token", false);
+ device_policy_cache->OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::NOT_FOUND, response);
+ // Now trigger the store.
+ device_policy_cache->OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::OPERATION_FAILED, response);
+ test.ExpectSample(kMetricPolicyFetchOtherFailed);
+ test.CheckSamples("BadSignature");
+
+ // Test fetching invalid policy.
+ {
+ TestInstallAttributes install_attributes("user");
+ device_policy_cache.reset(new DevicePolicyCache(data_store.get(),
+ install_attributes.install_attributes()));
+ // Make the cache have |starting_up_| set to false.
+ data_store->SetupForTesting("", "id", "user", "token", false);
+ device_policy_cache->OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::NOT_FOUND, response);
+ // Now trigger the store.
+ response.set_policy_data(std::string("\xff"));
+ device_policy_cache->SetPolicy(response);
+ test.ExpectSample(kMetricPolicyFetchInvalidPolicy);
+ test.CheckSamples("UserMismatch");
+ }
+
+ test.Done();
+ RETURN_CHECK_FAILED();
+}
+
+#endif
+
+} // namespace policy
« no previous file with comments | « chrome/browser/policy/enterprise_metrics_browsertest.cc ('k') | chrome/browser/policy/user_policy_token_cache.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698