Chromium Code Reviews| 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..3ff5ef20ecf5ff0c1f12ada40874b325fa1b03ff |
| --- /dev/null |
| +++ b/chrome/browser/policy/enterprise_metrics_browsertest.cc |
| @@ -0,0 +1,842 @@ |
| +// 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/logging.h" |
| +#include "base/message_loop.h" |
| +#include "base/metrics/histogram.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 "chrome/test/ui_test_utils.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/enterprise_enrollment_screen.h" |
| +#include "chrome/browser/chromeos/login/mock_signed_settings_helper.h" |
| +#include "chrome/browser/chromeos/login/signed_settings.h" |
| +#include "chrome/browser/chromeos/login/wizard_controller.h" |
| +#include "chrome/browser/chromeos/login/wizard_in_process_browser_test.h" |
| +#include "chrome/browser/policy/device_policy_cache.h" |
| +#include "chrome/browser/policy/enterprise_install_attributes.h" |
| +#include "chrome/common/net/gaia/gaia_constants.h" |
| +#include "content/common/test_url_fetcher_factory.h" |
| +#endif |
| + |
| +namespace policy { |
| + |
| +namespace em = enterprise_management; |
| + |
| +using testing::_; |
| +using testing::AnyNumber; |
| +using testing::DoAll; |
| +using testing::Return; |
| +using testing::SetArgumentPointee; |
| + |
| +#if defined(OS_CHROMEOS) |
| + |
| +namespace { |
| + |
| +class TestInstallAttributes { |
|
gfeher
2011/07/18 12:06:12
Please add 1-2 line comment explaining what does t
Joao da Silva
2011/07/19 09:34:17
Done.
|
| + 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); |
| +}; |
| + |
| +} // namespace |
| + |
| +#endif // OS_CHROMEOS |
| + |
| +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) { |
|
gfeher
2011/07/18 12:06:12
Nit: pass by constant reference.
Joao da Silva
2011/07/19 09:34:17
Done.
|
| + 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(); |
| + } |
| + } |
| + |
| + virtual void TearDown() OVERRIDE { |
| + RunAllPending(); |
| + EXPECT_TRUE(CheckSamples()); |
| + } |
| + |
| + const FilePath& temp_dir() { |
| + return temp_dir_.path(); |
| + } |
| + |
| + void RunAllPending() { |
| + loop_.RunAllPending(); |
| + } |
| + |
| + void ExpectSample(int sample) { |
|
gfeher
2011/07/18 12:06:12
Please add a comment, like "Adds a sample to the s
Joao da Silva
2011/07/19 09:34:17
Done.
|
| + 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; |
| + if (!expects_samples) { |
| + bool found = base::StatisticsRecorder::FindHistogram(metric_name_, |
| + &histogram); |
| + EXPECT_FALSE(found); |
| + return !found; |
| + } |
| + |
| + bool found = base::StatisticsRecorder::FindHistogram(metric_name_, |
| + &histogram); |
| + EXPECT_TRUE(found); |
| + if (!found) |
| + return false; |
| + EXPECT_TRUE(histogram != NULL); |
| + if (histogram == NULL) |
| + return false; |
| + |
| + base::Histogram::SampleSet samples; |
| + histogram->SnapshotSample(&samples); |
| + |
| + bool result = true; |
| + size_t sum = 0; |
| + for (size_t i = 0; i < expected_samples_.size(); ++i) { |
| + EXPECT_EQ(expected_samples_[i], samples.counts(i)) << "i is " << i; |
| + if (expected_samples_[i] != samples.counts(i)) |
| + result = false; |
| + sum += expected_samples_[i]; |
| + } |
| + EXPECT_EQ(sum, (size_t) samples.TotalCount()); |
| + if (sum != (size_t) samples.TotalCount()) |
| + result = false; |
| + return result; |
| + } |
| + |
| + private: |
| + base::StatisticsRecorder statistics_recorder_; |
| + MessageLoop loop_; |
| + BrowserThread ui_thread_; |
| + BrowserThread file_thread_; |
| + std::string metric_name_; |
|
gfeher
2011/07/18 12:06:12
Please add a comment for this.
Joao da Silva
2011/07/19 09:34:17
Done.
|
| + std::vector<int> expected_samples_; |
| + ScopedTempDir temp_dir_; |
| +}; |
| + |
| +TEST_F(EnterpriseMetricsTest, TokenFetch) { |
| + SetMetricName(kMetricToken); |
| + |
| + MockDeviceManagementService service; |
| + service.ScheduleInitialization(0); |
| + 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); |
| + ExpectSample(kMetricTokenFetchRequested); |
| + ExpectSample(kMetricTokenFetchRequestFailed); |
| + backend->ProcessRegisterRequest("token", "testid", request, &delegate); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // 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); |
|
gfeher
2011/07/18 12:06:12
I suggest you to use mock_device_management_backen
Joao da Silva
2011/07/19 09:34:17
As discussed, this test is actually exercising the
|
| + ExpectSample(kMetricTokenFetchRequested); |
| + ExpectSample(kMetricTokenFetchBadResponse); |
| + backend->ProcessRegisterRequest("token", "testid", request, &delegate); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // Test various error cases. |
| + 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 }, |
| + }; |
| + |
| + service.set_data(std::string()); |
| + |
| + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { |
| + service.set_response_code(cases[i].error_code); |
| + ExpectSample(kMetricTokenFetchRequested); |
| + ExpectSample(cases[i].sample); |
| + backend->ProcessRegisterRequest("token", "testid", request, &delegate); |
| + EXPECT_TRUE(CheckSamples()); |
| + } |
| + |
| + // Test successful token retrieval. |
| + service.set_response_code(200); |
| + ExpectSample(kMetricTokenFetchRequested); |
| + ExpectSample(kMetricTokenFetchResponseReceived); |
| + backend->ProcessRegisterRequest("token", "testid", request, &delegate); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // 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_auth_token", true); |
| + PolicyNotifier notifier; |
| + DeviceTokenFetcher fetcher(&service, &cache, data_store.get(), ¬ifier); |
| + |
| + 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(); |
| + |
| + ExpectSample(kMetricTokenFetchRequested); |
| + ExpectSample(kMetricTokenFetchResponseReceived); |
| + ExpectSample(kMetricTokenFetchOK); |
| + 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_auth_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_auth_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_auth_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_auth_token", false); |
| + cache.Load(); |
| + RunAllPending(); |
| + ExpectSample(kMetricTokenLoadSucceeded); |
| + EXPECT_TRUE(CheckSamples()); |
| +} |
| + |
| +TEST_F(EnterpriseMetricsTest, PolicyFetch) { |
|
gfeher
2011/07/18 12:06:12
I would prefer this test case to be broken up to s
Joao da Silva
2011/07/19 09:34:17
Done.
|
| + SetMetricName(kMetricPolicy); |
| + |
| + MockDeviceManagementService service; |
| + service.ScheduleInitialization(0); |
| + 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); |
| + ExpectSample(kMetricPolicyFetchRequested); |
| + ExpectSample(kMetricPolicyFetchRequestFailed); |
| + backend->ProcessPolicyRequest("token", "testid", request, &delegate); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // 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); |
| + ExpectSample(kMetricPolicyFetchRequested); |
| + ExpectSample(kMetricPolicyFetchBadResponse); |
| + backend->ProcessPolicyRequest("token", "testid", request, &delegate); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // Test various error cases. |
| + 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 }, |
| + }; |
| + |
| + service.set_data(std::string()); |
| + |
| + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { |
| + service.set_response_code(cases[i].error_code); |
| + ExpectSample(kMetricPolicyFetchRequested); |
| + ExpectSample(cases[i].sample); |
| + backend->ProcessPolicyRequest("token", "testid", request, &delegate); |
| + EXPECT_TRUE(CheckSamples()); |
| + } |
| + |
| + // Test successful policy retrieval. |
| + service.set_response_code(200); |
| + ExpectSample(kMetricPolicyFetchRequested); |
| + ExpectSample(kMetricPolicyFetchResponseReceived); |
| + backend->ProcessPolicyRequest("token", "testid", request, &delegate); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // Test fetching an invalid policy. |
| + UserPolicyCache cache(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); |
| + ExpectSample(kMetricPolicyFetchInvalidPolicy); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // 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); |
| + ExpectSample(kMetricPolicyFetchTimestampInFuture); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // 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); |
| + ExpectSample(kMetricPolicyFetchNotModified); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // Test fetch OK. |
| + 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 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(), |
| + ¬ifier); |
| + 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) |
| + |
| +TEST_F(EnterpriseMetricsTest, DevicePolicyStorage) { |
|
gfeher
2011/07/18 12:06:12
Could you also break this into smaller tests cases
Joao da Silva
2011/07/19 09:34:17
Done.
|
| + SetMetricName(kMetricPolicy); |
| + |
| + 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. |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // 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); |
| + ExpectSample(kMetricPolicyLoadFailed); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // 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); |
| + ExpectSample(kMetricPolicyLoadFailed); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // 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); |
| + ExpectSample(kMetricPolicyLoadSucceeded); |
| + // There is no policy data though. |
| + ExpectSample(kMetricPolicyFetchNotModified); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // Test storing the device policy. |
| + struct { |
| + chromeos::SignedSettings::ReturnCode return_code; |
| + int expected_retrieve; |
| + int expected_sample; |
| + int expected_sample2; |
| + } cases[] = { |
| + { chromeos::SignedSettings::SUCCESS, 1, |
| + kMetricPolicyStoreSucceeded, -1 }, |
| + { chromeos::SignedSettings::BAD_SIGNATURE, 0, |
| + kMetricPolicyStoreFailed, kMetricPolicyFetchBadSignature }, |
| + { 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); |
| + ExpectSample(cases[i].expected_sample); |
| + if (cases[i].expected_sample2 >= 0) |
| + ExpectSample(cases[i].expected_sample2); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // 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); |
| + ExpectSample(kMetricPolicyFetchNonEnterpriseDevice); |
| + EXPECT_TRUE(CheckSamples()); |
| + } |
| + |
| + // 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); |
| + ExpectSample(kMetricPolicyFetchUserMismatch); |
| + EXPECT_TRUE(CheckSamples()); |
| + } |
| + |
| + // 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); |
| + ExpectSample(kMetricPolicyFetchBadSignature); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // 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); |
| + ExpectSample(kMetricPolicyFetchOtherFailed); |
| + EXPECT_TRUE(CheckSamples()); |
| + |
| + // 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); |
| + ExpectSample(kMetricPolicyFetchInvalidPolicy); |
| + EXPECT_TRUE(CheckSamples()); |
| + } |
| +} |
| + |
| +#endif |
| + |
| +} // namespace policy |
| + |
| +#if defined(OS_CHROMEOS) |
| + |
| +namespace chromeos { |
| + |
| +namespace { |
| + |
| +void assert_handler(const std::string& str) { |
| + LOG(INFO) << "Previous failure was expected, ignoring."; |
| +} |
| + |
| +} // namespace |
| + |
| +class EnterpriseMetricsEnrollmentTest : public WizardInProcessBrowserTest { |
|
gfeher
2011/07/18 12:06:12
Please put this into its own file.
Joao da Silva
2011/07/19 09:34:17
Done.
|
| + protected: |
| + EnterpriseMetricsEnrollmentTest() |
| + : WizardInProcessBrowserTest( |
| + WizardController::kEnterpriseEnrollmentScreenName) {} |
| + |
| + virtual void SetUpOnMainThread() OVERRIDE { |
| + WizardInProcessBrowserTest::SetUpOnMainThread(); |
| + |
| + ASSERT_TRUE(controller() != NULL); |
| + |
| + // Use mock URLFetchers. |
| + URLFetcher::set_factory(&factory_); |
|
gfeher
2011/07/18 12:06:12
Are you using this anywhere?
Joao da Silva
2011/07/19 09:34:17
Yes, in the call to screen_->Authenticate(). It wi
|
| + |
| + screen_ = controller()->GetEnterpriseEnrollmentScreen(); |
| + |
| + ASSERT_TRUE(screen_ != NULL); |
| + ASSERT_EQ(controller()->current_screen(), screen_); |
| + } |
| + |
| + virtual void CleanUpOnMainThread() OVERRIDE { |
| + WizardInProcessBrowserTest::CleanUpOnMainThread(); |
| + |
| + // Check that no other counters were sampled. |
| + base::Histogram::SampleSet samples; |
| + GetSampleSet(&samples); |
| + EXPECT_EQ(1, samples.TotalCount()); |
| + } |
| + |
| + // This is used to let expected NOTREACHED paths go on instead of making |
| + // the test fail. It will also let CHECKs and DCHECKs pass, but that should be |
| + // tested elsewhere. |
| + void ExpectNOTREACHED() { |
| + logging::SetLogAssertHandler(assert_handler); |
|
gfeher
2011/07/18 12:06:12
Which is the particular NOTREACHED you are trying
Joao da Silva
2011/07/19 09:34:17
Some code paths within EnterpriseEnrollmentScreen
|
| + } |
| + |
| + void ExpectSample(int sample) { |
| + ASSERT_GE(sample, 0); |
| + ASSERT_LT(sample, policy::kMetricEnrollmentSize); |
| + |
| + base::Histogram::SampleSet samples; |
| + GetSampleSet(&samples); |
| + EXPECT_EQ(1, samples.counts(sample)); |
| + } |
| + |
| + EnterpriseEnrollmentScreen* screen_; |
| + |
| + private: |
| + void GetSampleSet(base::Histogram::SampleSet* set) { |
| + base::Histogram* histogram = NULL; |
| + EXPECT_TRUE(base::StatisticsRecorder::FindHistogram( |
| + policy::kMetricEnrollment, &histogram)); |
| + ASSERT_TRUE(histogram != NULL); |
| + histogram->SnapshotSample(set); |
| + } |
| + |
| + TestURLFetcherFactory factory_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(EnterpriseMetricsEnrollmentTest); |
| +}; |
| + |
| +IN_PROC_BROWSER_TEST_F(EnterpriseMetricsEnrollmentTest, EnrollmentStart) { |
| + std::string empty; |
| + screen_->Authenticate(empty, empty, empty, empty); |
| + ExpectSample(policy::kMetricEnrollmentStarted); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(EnterpriseMetricsEnrollmentTest, EnrollmentCancelled) { |
| + screen_->CancelEnrollment(); |
| + ExpectSample(policy::kMetricEnrollmentCancelled); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(EnterpriseMetricsEnrollmentTest, AuthTokenWrongService) { |
| + ExpectNOTREACHED(); |
| + screen_->OnIssueAuthTokenSuccess(std::string(), std::string()); |
| + ExpectSample(policy::kMetricEnrollmentOtherFailed); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(EnterpriseMetricsEnrollmentTest, |
| + AuthTokenCloudPolicyNotReady) { |
| + ExpectNOTREACHED(); |
| + screen_->OnIssueAuthTokenSuccess(GaiaConstants::kDeviceManagementService, |
| + std::string()); |
| + ExpectSample(policy::kMetricEnrollmentOtherFailed); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(EnterpriseMetricsEnrollmentTest, AuthTokenFailure) { |
| + ExpectNOTREACHED(); |
| + GoogleServiceAuthError error(GoogleServiceAuthError::SERVICE_UNAVAILABLE); |
| + screen_->OnIssueAuthTokenFailure(std::string(), error); |
| + ExpectSample(policy::kMetricEnrollmentOtherFailed); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(EnterpriseMetricsEnrollmentTest, OnPolicyBadToken) { |
| + screen_->OnPolicyStateChanged(policy::CloudPolicySubsystem::BAD_GAIA_TOKEN, |
| + policy::CloudPolicySubsystem::NO_DETAILS); |
| + ExpectSample(policy::kMetricEnrollmentPolicyFailed); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(EnterpriseMetricsEnrollmentTest, OnPolicyNetworkError) { |
| + screen_->OnPolicyStateChanged(policy::CloudPolicySubsystem::NETWORK_ERROR, |
| + policy::CloudPolicySubsystem::NO_DETAILS); |
| + ExpectSample(policy::kMetricEnrollmentPolicyFailed); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(EnterpriseMetricsEnrollmentTest, OnPolicyUnmanaged) { |
| + screen_->OnPolicyStateChanged(policy::CloudPolicySubsystem::UNMANAGED, |
| + policy::CloudPolicySubsystem::NO_DETAILS); |
| + ExpectSample(policy::kMetricEnrollmentNotSupported); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(EnterpriseMetricsEnrollmentTest, EnrollmentOK) { |
| + screen_->OnPolicyStateChanged(policy::CloudPolicySubsystem::SUCCESS, |
| + policy::CloudPolicySubsystem::NO_DETAILS); |
| + ExpectSample(policy::kMetricEnrollmentOK); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(EnterpriseMetricsEnrollmentTest, AuthErrorConnection) { |
| + GoogleServiceAuthError error(GoogleServiceAuthError::CONNECTION_FAILED); |
| + screen_->OnClientLoginFailure(error); |
| + ExpectSample(policy::kMetricEnrollmentNetworkFailed); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(EnterpriseMetricsEnrollmentTest, AuthErrorLoginFailed) { |
| + GoogleServiceAuthError error(GoogleServiceAuthError::TWO_FACTOR); |
| + screen_->OnClientLoginFailure(error); |
| + ExpectSample(policy::kMetricEnrollmentLoginFailed); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(EnterpriseMetricsEnrollmentTest, AccountDisabled) { |
| + GoogleServiceAuthError error(GoogleServiceAuthError::ACCOUNT_DISABLED); |
| + screen_->OnClientLoginFailure(error); |
| + ExpectSample(policy::kMetricEnrollmentNotSupported); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(EnterpriseMetricsEnrollmentTest, AuthErrorUnexpected) { |
| + GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED); |
| + screen_->OnClientLoginFailure(error); |
| + ExpectSample(policy::kMetricEnrollmentNetworkFailed); |
| +} |
| + |
| +} // namespace chromeos |
| + |
| +#endif // OS_CHROMEOS |