| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/basictypes.h" |
| 6 #include "base/file_util.h" |
| 7 #include "base/message_loop.h" |
| 8 #include "base/metrics/histogram.h" |
| 9 #include "base/scoped_temp_dir.h" |
| 10 #include "base/time.h" |
| 11 #include "chrome/browser/policy/cloud_policy_controller.h" |
| 12 #include "chrome/browser/policy/cloud_policy_data_store.h" |
| 13 #include "chrome/browser/policy/device_management_backend.h" |
| 14 #include "chrome/browser/policy/device_management_backend_mock.h" |
| 15 #include "chrome/browser/policy/device_management_service.h" |
| 16 #include "chrome/browser/policy/device_token_fetcher.h" |
| 17 #include "chrome/browser/policy/enterprise_metrics.h" |
| 18 #include "chrome/browser/policy/mock_cloud_policy_data_store.h" |
| 19 #include "chrome/browser/policy/mock_device_management_service.h" |
| 20 #include "chrome/browser/policy/policy_notifier.h" |
| 21 #include "chrome/browser/policy/proto/device_management_backend.pb.h" |
| 22 #include "chrome/browser/policy/proto/device_management_local.pb.h" |
| 23 #include "chrome/browser/policy/user_policy_cache.h" |
| 24 #include "chrome/browser/policy/user_policy_token_cache.h" |
| 25 #include "content/browser/browser_thread.h" |
| 26 #include "net/url_request/url_request_status.h" |
| 27 #include "testing/gmock/include/gmock/gmock.h" |
| 28 #include "testing/gtest/include/gtest/gtest.h" |
| 29 |
| 30 #if defined(OS_CHROMEOS) |
| 31 #include "chrome/browser/chromeos/cros/mock_cryptohome_library.h" |
| 32 #include "chrome/browser/chromeos/login/mock_signed_settings_helper.h" |
| 33 #include "chrome/browser/chromeos/login/signed_settings.h" |
| 34 #include "chrome/browser/policy/device_policy_cache.h" |
| 35 #include "chrome/browser/policy/enterprise_install_attributes.h" |
| 36 #endif |
| 37 |
| 38 namespace policy { |
| 39 |
| 40 namespace em = enterprise_management; |
| 41 |
| 42 using testing::_; |
| 43 using testing::AnyNumber; |
| 44 using testing::DoAll; |
| 45 using testing::Invoke; |
| 46 using testing::Mock; |
| 47 using testing::Return; |
| 48 using testing::SetArgPointee; |
| 49 |
| 50 namespace { |
| 51 |
| 52 // Helper with common code for tests that use the DeviceManagementBackendImpl. |
| 53 class DeviceManagementBackendTestHelper { |
| 54 public: |
| 55 explicit DeviceManagementBackendTestHelper(MessageLoop* loop) { |
| 56 service_.ScheduleInitialization(0); |
| 57 loop->RunAllPending(); |
| 58 backend_.reset(service_.CreateBackendNotMocked()); |
| 59 } |
| 60 |
| 61 DeviceManagementService& service() { |
| 62 return service_; |
| 63 } |
| 64 |
| 65 void ProcessRegisterRequest() { |
| 66 em::DeviceRegisterRequest request; |
| 67 DeviceRegisterResponseDelegateMock delegate; |
| 68 EXPECT_CALL(delegate, OnError(_)).Times(AnyNumber()); |
| 69 EXPECT_CALL(delegate, HandleRegisterResponse(_)).Times(AnyNumber()); |
| 70 backend_->ProcessRegisterRequest("token", "testid", request, &delegate); |
| 71 } |
| 72 |
| 73 void ProcessPolicyRequest() { |
| 74 em::DevicePolicyRequest request; |
| 75 DevicePolicyResponseDelegateMock delegate; |
| 76 EXPECT_CALL(delegate, OnError(_)).Times(AnyNumber()); |
| 77 EXPECT_CALL(delegate, HandlePolicyResponse(_)).Times(AnyNumber()); |
| 78 backend_->ProcessPolicyRequest("token", "testid", request, &delegate); |
| 79 } |
| 80 |
| 81 void UnmockCreateBackend() { |
| 82 EXPECT_CALL(service_, CreateBackend()) |
| 83 .WillOnce(Invoke(&service_, |
| 84 &MockDeviceManagementService::CreateBackendNotMocked)); |
| 85 } |
| 86 |
| 87 void ExpectStartJob(net::URLRequestStatus::Status status, int response_code, |
| 88 const std::string& data) { |
| 89 net::ResponseCookies cookies; |
| 90 net::URLRequestStatus url_request_status(status, 0); |
| 91 EXPECT_CALL(service_, StartJob(_)) |
| 92 .WillOnce(MockDeviceManagementServiceRespondToJob( |
| 93 url_request_status, response_code, cookies, data)); |
| 94 } |
| 95 |
| 96 bool VerifyAndClearExpectations() { |
| 97 return Mock::VerifyAndClearExpectations(&service_); |
| 98 } |
| 99 |
| 100 private: |
| 101 MockDeviceManagementService service_; |
| 102 scoped_ptr<DeviceManagementBackend> backend_; |
| 103 |
| 104 DISALLOW_COPY_AND_ASSIGN(DeviceManagementBackendTestHelper); |
| 105 }; |
| 106 |
| 107 } // namespace |
| 108 |
| 109 // This derives from testing::Test and not from InProcessBrowserTest and is |
| 110 // linked with browser_tests. The reason is that these are just unit tests, but |
| 111 // due to the static initialization of the UMA counters they have to run each |
| 112 // in its own process to make sure the counters are not initialized before the |
| 113 // test runs, and that the StatisticsRecorder instance created for the test |
| 114 // doesn't interfere with counters in other tests. |
| 115 class EnterpriseMetricsTest : public testing::Test { |
| 116 public: |
| 117 EnterpriseMetricsTest() |
| 118 : ui_thread_(BrowserThread::UI, &loop_), |
| 119 file_thread_(BrowserThread::FILE, &loop_) { |
| 120 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 121 } |
| 122 |
| 123 void SetMetricName(const std::string& metric_name) { |
| 124 metric_name_ = metric_name; |
| 125 if (metric_name == kMetricToken) { |
| 126 expected_samples_.resize(kMetricTokenSize, 0); |
| 127 } else if (metric_name == kMetricPolicy) { |
| 128 expected_samples_.resize(kMetricPolicySize, 0); |
| 129 } else { |
| 130 NOTREACHED(); |
| 131 } |
| 132 } |
| 133 |
| 134 // Run pending tasks, and check that no unexpected samples were recorded. |
| 135 virtual void TearDown() OVERRIDE { |
| 136 RunAllPending(); |
| 137 EXPECT_TRUE(CheckSamples()); |
| 138 } |
| 139 |
| 140 const FilePath& temp_dir() { |
| 141 return temp_dir_.path(); |
| 142 } |
| 143 |
| 144 MessageLoop* loop() { |
| 145 return &loop_; |
| 146 } |
| 147 |
| 148 void RunAllPending() { |
| 149 loop_.RunAllPending(); |
| 150 } |
| 151 |
| 152 // Adds |sample| to the list of expected samples. Subsequent calls of |
| 153 // CheckSamples() will expect this sample. |
| 154 void ExpectSample(int sample) { |
| 155 ASSERT_FALSE(metric_name_.empty()); |
| 156 ASSERT_GE(sample, 0); |
| 157 ASSERT_LT(sample, (int) expected_samples_.size()); |
| 158 expected_samples_[sample]++; |
| 159 } |
| 160 |
| 161 // Checks the current recorded samples against the expected set. Returns |
| 162 // true if they match. |
| 163 bool CheckSamples() { |
| 164 EXPECT_FALSE(metric_name_.empty()); |
| 165 if (metric_name_.empty()) |
| 166 return false; |
| 167 bool expects_samples = false; |
| 168 for (size_t i = 0; i < expected_samples_.size(); ++i) { |
| 169 if (expected_samples_[i] > 0) { |
| 170 expects_samples = true; |
| 171 break; |
| 172 } |
| 173 } |
| 174 // The histogram won't be available until the first sample is measured. |
| 175 base::Histogram* histogram = NULL; |
| 176 bool found = base::StatisticsRecorder::FindHistogram(metric_name_, |
| 177 &histogram); |
| 178 found = found && histogram != NULL; |
| 179 EXPECT_EQ(expects_samples, found); |
| 180 if (found != expects_samples) |
| 181 return false; |
| 182 if (histogram == NULL) |
| 183 return true; |
| 184 |
| 185 base::Histogram::SampleSet samples; |
| 186 histogram->SnapshotSample(&samples); |
| 187 |
| 188 bool result = true; |
| 189 int sum = 0; |
| 190 for (size_t i = 0; i < expected_samples_.size(); ++i) { |
| 191 EXPECT_EQ(expected_samples_[i], samples.counts(i)) |
| 192 << "Mismatched sample index was " << i; |
| 193 if (expected_samples_[i] != samples.counts(i)) |
| 194 result = false; |
| 195 sum += expected_samples_[i]; |
| 196 } |
| 197 EXPECT_EQ(sum, samples.TotalCount()); |
| 198 if (sum != samples.TotalCount()) |
| 199 result = false; |
| 200 return result; |
| 201 } |
| 202 |
| 203 private: |
| 204 // All the UMA counters are registed at a static global singleton, which is |
| 205 // initialized on the constructor of base::StatisticsRecorder. This usually |
| 206 // lives in BrowserMain, but doesn't exist in unit tests, so we create it |
| 207 // here. The "staticness" of this class is also the reason to run each |
| 208 // test in a separate process. |
| 209 base::StatisticsRecorder statistics_recorder_; |
| 210 MessageLoop loop_; |
| 211 BrowserThread ui_thread_; |
| 212 BrowserThread file_thread_; |
| 213 // |metric_name_| is the UMA counter that is being tested. It must be set |
| 214 // before any calls to ExpectSample or CheckSamples. |
| 215 std::string metric_name_; |
| 216 // List of expected samples. |
| 217 std::vector<int> expected_samples_; |
| 218 ScopedTempDir temp_dir_; |
| 219 |
| 220 DISALLOW_COPY_AND_ASSIGN(EnterpriseMetricsTest); |
| 221 }; |
| 222 |
| 223 TEST_F(EnterpriseMetricsTest, TokenFetchRequestFail) { |
| 224 SetMetricName(kMetricToken); |
| 225 DeviceManagementBackendTestHelper helper(loop()); |
| 226 |
| 227 helper.ExpectStartJob(net::URLRequestStatus::FAILED, -1, std::string()); |
| 228 ExpectSample(kMetricTokenFetchRequested); |
| 229 ExpectSample(kMetricTokenFetchRequestFailed); |
| 230 helper.ProcessRegisterRequest(); |
| 231 EXPECT_TRUE(helper.VerifyAndClearExpectations()); |
| 232 EXPECT_TRUE(CheckSamples()); |
| 233 } |
| 234 |
| 235 TEST_F(EnterpriseMetricsTest, TokenFetchInvalidData) { |
| 236 SetMetricName(kMetricToken); |
| 237 DeviceManagementBackendTestHelper helper(loop()); |
| 238 |
| 239 helper.ExpectStartJob(net::URLRequestStatus::SUCCESS, 200, "\xff"); |
| 240 ExpectSample(kMetricTokenFetchRequested); |
| 241 ExpectSample(kMetricTokenFetchBadResponse); |
| 242 helper.ProcessRegisterRequest(); |
| 243 EXPECT_TRUE(helper.VerifyAndClearExpectations()); |
| 244 EXPECT_TRUE(CheckSamples()); |
| 245 } |
| 246 |
| 247 TEST_F(EnterpriseMetricsTest, TokenFetchErrors) { |
| 248 SetMetricName(kMetricToken); |
| 249 DeviceManagementBackendTestHelper helper(loop()); |
| 250 |
| 251 struct { |
| 252 int error_code; |
| 253 MetricToken sample; |
| 254 } cases[] = { |
| 255 { 400, kMetricTokenFetchRequestFailed }, |
| 256 { 401, kMetricTokenFetchServerFailed }, |
| 257 { 403, kMetricTokenFetchManagementNotSupported }, |
| 258 { 404, kMetricTokenFetchServerFailed }, |
| 259 { 410, kMetricTokenFetchDeviceNotFound }, |
| 260 { 412, kMetricTokenFetchServerFailed }, |
| 261 { 500, kMetricTokenFetchServerFailed }, |
| 262 { 503, kMetricTokenFetchServerFailed }, |
| 263 { 902, kMetricTokenFetchServerFailed }, |
| 264 { 491, kMetricTokenFetchServerFailed }, |
| 265 { 901, kMetricTokenFetchDeviceNotFound }, |
| 266 }; |
| 267 |
| 268 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { |
| 269 helper.ExpectStartJob(net::URLRequestStatus::SUCCESS, |
| 270 cases[i].error_code, std::string()); |
| 271 ExpectSample(kMetricTokenFetchRequested); |
| 272 ExpectSample(cases[i].sample); |
| 273 helper.ProcessRegisterRequest(); |
| 274 EXPECT_TRUE(helper.VerifyAndClearExpectations()); |
| 275 EXPECT_TRUE(CheckSamples()); |
| 276 } |
| 277 } |
| 278 |
| 279 TEST_F(EnterpriseMetricsTest, TokenFetchReceiveResponse) { |
| 280 SetMetricName(kMetricToken); |
| 281 DeviceManagementBackendTestHelper helper(loop()); |
| 282 |
| 283 helper.ExpectStartJob(net::URLRequestStatus::SUCCESS, 200, std::string()); |
| 284 ExpectSample(kMetricTokenFetchRequested); |
| 285 ExpectSample(kMetricTokenFetchResponseReceived); |
| 286 helper.ProcessRegisterRequest(); |
| 287 EXPECT_TRUE(helper.VerifyAndClearExpectations()); |
| 288 EXPECT_TRUE(CheckSamples()); |
| 289 } |
| 290 |
| 291 TEST_F(EnterpriseMetricsTest, TokenFetchOK) { |
| 292 SetMetricName(kMetricToken); |
| 293 DeviceManagementBackendTestHelper helper(loop()); |
| 294 |
| 295 // Test token fetcher. |
| 296 UserPolicyCache cache(temp_dir().AppendASCII("FetchTokenTest")); |
| 297 scoped_ptr<CloudPolicyDataStore> data_store; |
| 298 data_store.reset(CloudPolicyDataStore::CreateForUserPolicies()); |
| 299 data_store->SetupForTesting("", "fake_device_id", "fake_user_name", |
| 300 "fake_gaia_token", true); |
| 301 PolicyNotifier notifier; |
| 302 DeviceTokenFetcher fetcher(&helper.service(), &cache, data_store.get(), |
| 303 ¬ifier); |
| 304 |
| 305 MockCloudPolicyDataStoreObserver observer; |
| 306 data_store->AddObserver(&observer); |
| 307 EXPECT_CALL(observer, OnDeviceTokenChanged()).Times(1); |
| 308 |
| 309 std::string data; |
| 310 em::DeviceManagementResponse response; |
| 311 response.mutable_register_response()->set_device_management_token("token"); |
| 312 response.SerializeToString(&data); |
| 313 helper.ExpectStartJob(net::URLRequestStatus::SUCCESS, 200, data); |
| 314 |
| 315 // FetchToken() will reset the backend. Make sure it does the right thing. |
| 316 helper.UnmockCreateBackend(); |
| 317 |
| 318 fetcher.FetchToken(); |
| 319 |
| 320 ExpectSample(kMetricTokenFetchRequested); |
| 321 ExpectSample(kMetricTokenFetchResponseReceived); |
| 322 ExpectSample(kMetricTokenFetchOK); |
| 323 EXPECT_TRUE(helper.VerifyAndClearExpectations()); |
| 324 EXPECT_TRUE(CheckSamples()); |
| 325 |
| 326 // Cleanup. |
| 327 data_store->RemoveObserver(&observer); |
| 328 } |
| 329 |
| 330 TEST_F(EnterpriseMetricsTest, TokenStorage) { |
| 331 SetMetricName(kMetricToken); |
| 332 |
| 333 FilePath path = temp_dir().AppendASCII("StoreTokenTest"); |
| 334 |
| 335 scoped_ptr<CloudPolicyDataStore> data_store; |
| 336 data_store.reset(CloudPolicyDataStore::CreateForUserPolicies()); |
| 337 data_store->SetupForTesting("", "fake_device_id", "fake_user_name", |
| 338 "fake_gaia_token", false); |
| 339 UserPolicyTokenCache cache(data_store.get(), path); |
| 340 |
| 341 // Try loading a non-existing file first. |
| 342 cache.Load(); |
| 343 RunAllPending(); |
| 344 // No samples expected. |
| 345 EXPECT_TRUE(CheckSamples()); |
| 346 |
| 347 // Try loading an invalid file. |
| 348 std::string data("\xff"); |
| 349 int result = file_util::WriteFile(path, data.c_str(), data.size()); |
| 350 ASSERT_EQ((int) data.size(), result); |
| 351 |
| 352 // Make the data store expect a load from cache again. |
| 353 data_store->SetupForTesting("", "fake_device_id", "fake_user_name", |
| 354 "fake_gaia_token", false); |
| 355 cache.Load(); |
| 356 RunAllPending(); |
| 357 ExpectSample(kMetricTokenLoadFailed); |
| 358 EXPECT_TRUE(CheckSamples()); |
| 359 |
| 360 // Test storing a valid cache. |
| 361 data_store->SetupForTesting("token", "fake_device_id", "fake_user_name", |
| 362 "fake_gaia_token", false); |
| 363 cache.OnDeviceTokenChanged(); |
| 364 RunAllPending(); |
| 365 ExpectSample(kMetricTokenStoreSucceeded); |
| 366 EXPECT_TRUE(CheckSamples()); |
| 367 |
| 368 // Test loading a valid cache. |
| 369 // Make the data store expect a load from cache again. |
| 370 data_store->SetupForTesting("", "fake_device_id", "fake_user_name", |
| 371 "fake_gaia_token", false); |
| 372 cache.Load(); |
| 373 RunAllPending(); |
| 374 ExpectSample(kMetricTokenLoadSucceeded); |
| 375 EXPECT_TRUE(CheckSamples()); |
| 376 } |
| 377 |
| 378 TEST_F(EnterpriseMetricsTest, PolicyFetchRequestFails) { |
| 379 SetMetricName(kMetricPolicy); |
| 380 DeviceManagementBackendTestHelper helper(loop()); |
| 381 |
| 382 helper.ExpectStartJob(net::URLRequestStatus::FAILED, -1, std::string()); |
| 383 ExpectSample(kMetricPolicyFetchRequested); |
| 384 ExpectSample(kMetricPolicyFetchRequestFailed); |
| 385 helper.ProcessPolicyRequest(); |
| 386 EXPECT_TRUE(helper.VerifyAndClearExpectations()); |
| 387 EXPECT_TRUE(CheckSamples()); |
| 388 } |
| 389 |
| 390 TEST_F(EnterpriseMetricsTest, PolicyFetchInvalidData) { |
| 391 SetMetricName(kMetricPolicy); |
| 392 DeviceManagementBackendTestHelper helper(loop()); |
| 393 |
| 394 helper.ExpectStartJob(net::URLRequestStatus::SUCCESS, 200, "\xff"); |
| 395 ExpectSample(kMetricPolicyFetchRequested); |
| 396 ExpectSample(kMetricPolicyFetchBadResponse); |
| 397 helper.ProcessPolicyRequest(); |
| 398 EXPECT_TRUE(helper.VerifyAndClearExpectations()); |
| 399 EXPECT_TRUE(CheckSamples()); |
| 400 } |
| 401 |
| 402 TEST_F(EnterpriseMetricsTest, PolicyFetchErrors) { |
| 403 SetMetricName(kMetricPolicy); |
| 404 DeviceManagementBackendTestHelper helper(loop()); |
| 405 |
| 406 struct { |
| 407 int error_code; |
| 408 MetricPolicy sample; |
| 409 } cases[] = { |
| 410 { 400, kMetricPolicyFetchRequestFailed }, |
| 411 { 401, kMetricPolicyFetchInvalidToken }, |
| 412 { 403, kMetricPolicyFetchServerFailed }, |
| 413 { 404, kMetricPolicyFetchServerFailed }, |
| 414 { 410, kMetricPolicyFetchServerFailed }, |
| 415 { 412, kMetricPolicyFetchServerFailed }, |
| 416 { 500, kMetricPolicyFetchServerFailed }, |
| 417 { 503, kMetricPolicyFetchServerFailed }, |
| 418 { 902, kMetricPolicyFetchNotFound }, |
| 419 { 491, kMetricPolicyFetchServerFailed }, |
| 420 { 901, kMetricPolicyFetchServerFailed }, |
| 421 }; |
| 422 |
| 423 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { |
| 424 helper.ExpectStartJob(net::URLRequestStatus::SUCCESS, cases[i].error_code, |
| 425 std::string()); |
| 426 ExpectSample(kMetricPolicyFetchRequested); |
| 427 ExpectSample(cases[i].sample); |
| 428 helper.ProcessPolicyRequest(); |
| 429 EXPECT_TRUE(helper.VerifyAndClearExpectations()); |
| 430 EXPECT_TRUE(CheckSamples()); |
| 431 } |
| 432 } |
| 433 |
| 434 TEST_F(EnterpriseMetricsTest, PolicyFetchReceiveResponse) { |
| 435 SetMetricName(kMetricPolicy); |
| 436 DeviceManagementBackendTestHelper helper(loop()); |
| 437 |
| 438 helper.ExpectStartJob(net::URLRequestStatus::SUCCESS, 200, std::string()); |
| 439 ExpectSample(kMetricPolicyFetchRequested); |
| 440 ExpectSample(kMetricPolicyFetchResponseReceived); |
| 441 helper.ProcessPolicyRequest(); |
| 442 EXPECT_TRUE(helper.VerifyAndClearExpectations()); |
| 443 EXPECT_TRUE(CheckSamples()); |
| 444 } |
| 445 |
| 446 TEST_F(EnterpriseMetricsTest, PolicyFetchInvalidPolicy) { |
| 447 SetMetricName(kMetricPolicy); |
| 448 |
| 449 UserPolicyCache cache(temp_dir().AppendASCII("UserPolicyCacheTest")); |
| 450 UserPolicyDiskCache::Delegate* cache_as_delegate = |
| 451 implicit_cast<UserPolicyDiskCache::Delegate*>(&cache); |
| 452 |
| 453 em::CachedCloudPolicyResponse response; |
| 454 response.mutable_cloud_policy()->set_policy_data("\xff"); |
| 455 cache_as_delegate->OnDiskCacheLoaded(response); |
| 456 ExpectSample(kMetricPolicyFetchInvalidPolicy); |
| 457 EXPECT_TRUE(CheckSamples()); |
| 458 } |
| 459 |
| 460 TEST_F(EnterpriseMetricsTest, PolicyFetchTimestampInFuture) { |
| 461 SetMetricName(kMetricPolicy); |
| 462 |
| 463 UserPolicyCache cache(temp_dir().AppendASCII("UserPolicyCacheTest")); |
| 464 UserPolicyDiskCache::Delegate* cache_as_delegate = |
| 465 implicit_cast<UserPolicyDiskCache::Delegate*>(&cache); |
| 466 |
| 467 std::string data; |
| 468 em::PolicyData policy_data; |
| 469 base::TimeDelta timestamp = |
| 470 (base::Time::NowFromSystemTime() + base::TimeDelta::FromDays(1000)) - |
| 471 base::Time::UnixEpoch(); |
| 472 policy_data.set_timestamp(timestamp.InMilliseconds()); |
| 473 policy_data.SerializeToString(&data); |
| 474 em::CachedCloudPolicyResponse response; |
| 475 response.mutable_cloud_policy()->set_policy_data(data); |
| 476 cache_as_delegate->OnDiskCacheLoaded(response); |
| 477 ExpectSample(kMetricPolicyFetchTimestampInFuture); |
| 478 EXPECT_TRUE(CheckSamples()); |
| 479 } |
| 480 |
| 481 TEST_F(EnterpriseMetricsTest, PolicyFetchNotModified) { |
| 482 SetMetricName(kMetricPolicy); |
| 483 |
| 484 UserPolicyCache cache(temp_dir().AppendASCII("UserPolicyCacheTest")); |
| 485 UserPolicyDiskCache::Delegate* cache_as_delegate = |
| 486 implicit_cast<UserPolicyDiskCache::Delegate*>(&cache); |
| 487 |
| 488 std::string data; |
| 489 em::PolicyData policy_data; |
| 490 policy_data.set_timestamp(0); |
| 491 policy_data.SerializeToString(&data); |
| 492 em::CachedCloudPolicyResponse response; |
| 493 response.mutable_cloud_policy()->set_policy_data(data); |
| 494 cache_as_delegate->OnDiskCacheLoaded(response); |
| 495 ExpectSample(kMetricPolicyFetchNotModified); |
| 496 EXPECT_TRUE(CheckSamples()); |
| 497 } |
| 498 |
| 499 TEST_F(EnterpriseMetricsTest, PolicyFetchOK) { |
| 500 SetMetricName(kMetricPolicy); |
| 501 |
| 502 UserPolicyCache cache(temp_dir().AppendASCII("UserPolicyCacheTest")); |
| 503 |
| 504 std::string data; |
| 505 em::PolicyData policy_data; |
| 506 policy_data.set_timestamp(0); |
| 507 policy_data.SerializeToString(&data); |
| 508 em::CachedCloudPolicyResponse response; |
| 509 cache.SetPolicy(response.cloud_policy()); |
| 510 ExpectSample(kMetricPolicyFetchOK); |
| 511 ExpectSample(kMetricPolicyFetchNotModified); |
| 512 EXPECT_TRUE(CheckSamples()); |
| 513 // This also triggers a store. Update the expected samples. |
| 514 RunAllPending(); |
| 515 ExpectSample(kMetricPolicyStoreSucceeded); |
| 516 EXPECT_TRUE(CheckSamples()); |
| 517 } |
| 518 |
| 519 TEST_F(EnterpriseMetricsTest, PolicyFetchBadResponse) { |
| 520 SetMetricName(kMetricPolicy); |
| 521 |
| 522 UserPolicyCache cache(temp_dir().AppendASCII("UserPolicyCacheTest")); |
| 523 PolicyNotifier notifier; |
| 524 scoped_ptr<CloudPolicyDataStore> data_store; |
| 525 data_store.reset(CloudPolicyDataStore::CreateForUserPolicies()); |
| 526 data_store->SetupForTesting("", "fake_device_id", "fake_user_name", |
| 527 "fake_gaia_token", true); |
| 528 CloudPolicyController controller(NULL, &cache, NULL, data_store.get(), |
| 529 ¬ifier); |
| 530 em::DevicePolicyResponse device_policy_response; |
| 531 controller.HandlePolicyResponse(device_policy_response); |
| 532 ExpectSample(kMetricPolicyFetchBadResponse); |
| 533 EXPECT_TRUE(CheckSamples()); |
| 534 |
| 535 // More bad responses. |
| 536 em::PolicyFetchResponse* policy_fetch_response = |
| 537 device_policy_response.add_response(); |
| 538 policy_fetch_response->set_error_code( |
| 539 DeviceManagementBackend::kErrorServicePolicyNotFound); |
| 540 controller.HandlePolicyResponse(device_policy_response); |
| 541 ExpectSample(kMetricPolicyFetchBadResponse); |
| 542 EXPECT_TRUE(CheckSamples()); |
| 543 } |
| 544 |
| 545 TEST_F(EnterpriseMetricsTest, PolicyStorage) { |
| 546 SetMetricName(kMetricPolicy); |
| 547 |
| 548 FilePath path = temp_dir().AppendASCII("UserPolicyDiskCacheTest"); |
| 549 |
| 550 scoped_refptr<UserPolicyDiskCache> cache( |
| 551 new UserPolicyDiskCache(base::WeakPtr<UserPolicyDiskCache::Delegate>(), |
| 552 path)); |
| 553 |
| 554 // Load empty cache. |
| 555 cache->Load(); |
| 556 RunAllPending(); |
| 557 // No samples expected. |
| 558 EXPECT_TRUE(CheckSamples()); |
| 559 |
| 560 // Load an invalid cache. |
| 561 std::string data("\xff"); |
| 562 int result = file_util::WriteFile(path, data.c_str(), data.size()); |
| 563 ASSERT_EQ((int) data.size(), result); |
| 564 |
| 565 cache->Load(); |
| 566 RunAllPending(); |
| 567 ExpectSample(kMetricPolicyLoadFailed); |
| 568 EXPECT_TRUE(CheckSamples()); |
| 569 |
| 570 // Store a cache. |
| 571 em::CachedCloudPolicyResponse response; |
| 572 cache->Store(response); |
| 573 RunAllPending(); |
| 574 ExpectSample(kMetricPolicyStoreSucceeded); |
| 575 EXPECT_TRUE(CheckSamples()); |
| 576 |
| 577 // Load a good cache. |
| 578 cache->Load(); |
| 579 RunAllPending(); |
| 580 ExpectSample(kMetricPolicyLoadSucceeded); |
| 581 EXPECT_TRUE(CheckSamples()); |
| 582 } |
| 583 |
| 584 #if defined(OS_CHROMEOS) |
| 585 |
| 586 namespace { |
| 587 |
| 588 // Wrapper around an instance of EnterpriseInstallAttributes that uses a |
| 589 // mock CryptohomeLibrary. The wrapped EnterpriseInstallAttributes instance |
| 590 // is expected to be used to load the attributes once. |
| 591 class TestInstallAttributes { |
| 592 public: |
| 593 // |user| is the user to be returned as the value of the "enterprise.user" |
| 594 // attribute. |
| 595 explicit TestInstallAttributes(const std::string& user) |
| 596 : user_(user), |
| 597 owned_("true"), |
| 598 install_attributes_(&mock_cryptohome_library_) {} |
| 599 |
| 600 void ExpectUsage() { |
| 601 EXPECT_CALL(mock_cryptohome_library_, InstallAttributesIsReady()) |
| 602 .WillOnce(Return(true)); |
| 603 EXPECT_CALL(mock_cryptohome_library_, InstallAttributesIsInvalid()) |
| 604 .WillOnce(Return(false)); |
| 605 EXPECT_CALL(mock_cryptohome_library_, InstallAttributesIsFirstInstall()) |
| 606 .WillOnce(Return(false)); |
| 607 EXPECT_CALL(mock_cryptohome_library_, |
| 608 InstallAttributesGet("enterprise.owned", _)) |
| 609 .WillOnce(DoAll(SetArgPointee<1>(owned_), |
| 610 Return(true))); |
| 611 EXPECT_CALL(mock_cryptohome_library_, |
| 612 InstallAttributesGet("enterprise.user", _)) |
| 613 .WillOnce(DoAll(SetArgPointee<1>(user_), |
| 614 Return(true))); |
| 615 } |
| 616 |
| 617 EnterpriseInstallAttributes* install_attributes() { |
| 618 return &install_attributes_; |
| 619 } |
| 620 |
| 621 private: |
| 622 std::string user_; |
| 623 std::string owned_; |
| 624 chromeos::MockCryptohomeLibrary mock_cryptohome_library_; |
| 625 EnterpriseInstallAttributes install_attributes_; |
| 626 |
| 627 DISALLOW_COPY_AND_ASSIGN(TestInstallAttributes); |
| 628 }; |
| 629 |
| 630 } // namespace |
| 631 |
| 632 // Helper for tests that use a DevicePolicyCache. |
| 633 class DevicePolicyCacheTestHelper { |
| 634 public: |
| 635 DevicePolicyCacheTestHelper() |
| 636 : install_attributes_("user") { |
| 637 Init(); |
| 638 } |
| 639 |
| 640 explicit DevicePolicyCacheTestHelper(const std::string& user) |
| 641 : install_attributes_(user) { |
| 642 Init(); |
| 643 } |
| 644 |
| 645 void CompleteRetrieve(chromeos::SignedSettings::ReturnCode code) { |
| 646 device_policy_cache_->OnRetrievePolicyCompleted(code, response_); |
| 647 } |
| 648 |
| 649 void SetPolicy() { |
| 650 device_policy_cache_->SetPolicy(response_); |
| 651 } |
| 652 |
| 653 void SetData(const std::string& data) { |
| 654 response_.set_policy_data(data); |
| 655 } |
| 656 |
| 657 void SetGoodData() { |
| 658 em::PolicyData policy_data; |
| 659 policy_data.set_request_token("token"); |
| 660 policy_data.set_username("user"); |
| 661 policy_data.set_device_id("device_id"); |
| 662 std::string data; |
| 663 policy_data.SerializeToString(&data); |
| 664 response_.set_policy_data(data); |
| 665 } |
| 666 |
| 667 void ExpectInstallAttributes() { |
| 668 install_attributes_.ExpectUsage(); |
| 669 } |
| 670 |
| 671 void ExpectMockSignedSettings(chromeos::SignedSettings::ReturnCode code, |
| 672 int expected_retrieves) { |
| 673 install_attributes_.ExpectUsage(); |
| 674 EXPECT_CALL(mock_signed_settings_helper_, StartStorePolicyOp(_, _)) |
| 675 .WillOnce(MockSignedSettingsHelperStorePolicy(code)); |
| 676 EXPECT_CALL(mock_signed_settings_helper_, CancelCallback(_)) |
| 677 .Times(1) |
| 678 .RetiresOnSaturation(); |
| 679 EXPECT_CALL(mock_signed_settings_helper_, |
| 680 StartRetrievePolicyOp(_)).Times(expected_retrieves); |
| 681 } |
| 682 |
| 683 const em::PolicyFetchResponse& response() { |
| 684 return response_; |
| 685 } |
| 686 |
| 687 private: |
| 688 void Init() { |
| 689 data_store_.reset(CloudPolicyDataStore::CreateForUserPolicies()); |
| 690 device_policy_cache_.reset(new DevicePolicyCache(data_store_.get(), |
| 691 install_attributes_.install_attributes(), |
| 692 &mock_signed_settings_helper_)); |
| 693 data_store_->SetupForTesting("", "id", "user", "gaia_token", false); |
| 694 EXPECT_CALL(mock_signed_settings_helper_, CancelCallback(_)).Times(1); |
| 695 } |
| 696 |
| 697 chromeos::MockSignedSettingsHelper mock_signed_settings_helper_; |
| 698 scoped_ptr<CloudPolicyDataStore> data_store_; |
| 699 scoped_ptr<DevicePolicyCache> device_policy_cache_; |
| 700 em::PolicyFetchResponse response_; |
| 701 TestInstallAttributes install_attributes_; |
| 702 |
| 703 DISALLOW_COPY_AND_ASSIGN(DevicePolicyCacheTestHelper); |
| 704 }; |
| 705 |
| 706 TEST_F(EnterpriseMetricsTest, DevicePolicyNotFound) { |
| 707 SetMetricName(kMetricPolicy); |
| 708 DevicePolicyCacheTestHelper helper; |
| 709 |
| 710 helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND); |
| 711 // No samples expected. |
| 712 EXPECT_TRUE(CheckSamples()); |
| 713 } |
| 714 |
| 715 TEST_F(EnterpriseMetricsTest, DevicePolicyBadData) { |
| 716 SetMetricName(kMetricPolicy); |
| 717 DevicePolicyCacheTestHelper helper; |
| 718 |
| 719 helper.SetData("\xff"); |
| 720 helper.CompleteRetrieve(chromeos::SignedSettings::SUCCESS); |
| 721 ExpectSample(kMetricPolicyLoadFailed); |
| 722 EXPECT_TRUE(CheckSamples()); |
| 723 } |
| 724 |
| 725 TEST_F(EnterpriseMetricsTest, DevicePolicyMoreBadData) { |
| 726 SetMetricName(kMetricPolicy); |
| 727 DevicePolicyCacheTestHelper helper; |
| 728 |
| 729 em::PolicyData policy_data; |
| 730 policy_data.set_request_token("token"); |
| 731 std::string data; |
| 732 policy_data.SerializeToString(&data); |
| 733 helper.SetData(data); |
| 734 helper.CompleteRetrieve(chromeos::SignedSettings::SUCCESS); |
| 735 ExpectSample(kMetricPolicyLoadFailed); |
| 736 EXPECT_TRUE(CheckSamples()); |
| 737 } |
| 738 |
| 739 TEST_F(EnterpriseMetricsTest, DevicePolicyLoad) { |
| 740 SetMetricName(kMetricPolicy); |
| 741 DevicePolicyCacheTestHelper helper; |
| 742 |
| 743 helper.SetGoodData(); |
| 744 helper.CompleteRetrieve(chromeos::SignedSettings::SUCCESS); |
| 745 ExpectSample(kMetricPolicyLoadSucceeded); |
| 746 ExpectSample(kMetricPolicyFetchNotModified); |
| 747 EXPECT_TRUE(CheckSamples()); |
| 748 } |
| 749 |
| 750 TEST_F(EnterpriseMetricsTest, DevicePolicyStoreSuccess) { |
| 751 SetMetricName(kMetricPolicy); |
| 752 DevicePolicyCacheTestHelper helper; |
| 753 helper.ExpectMockSignedSettings(chromeos::SignedSettings::SUCCESS, 1); |
| 754 helper.SetGoodData(); |
| 755 helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND); |
| 756 helper.SetPolicy(); |
| 757 ExpectSample(kMetricPolicyStoreSucceeded); |
| 758 EXPECT_TRUE(CheckSamples()); |
| 759 } |
| 760 |
| 761 TEST_F(EnterpriseMetricsTest, DevicePolicyStoreBadSignature) { |
| 762 SetMetricName(kMetricPolicy); |
| 763 DevicePolicyCacheTestHelper helper; |
| 764 helper.ExpectMockSignedSettings(chromeos::SignedSettings::BAD_SIGNATURE, 0); |
| 765 helper.SetGoodData(); |
| 766 helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND); |
| 767 helper.SetPolicy(); |
| 768 ExpectSample(kMetricPolicyStoreFailed); |
| 769 ExpectSample(kMetricPolicyFetchBadSignature); |
| 770 EXPECT_TRUE(CheckSamples()); |
| 771 } |
| 772 |
| 773 TEST_F(EnterpriseMetricsTest, DevicePolicyStoreOperationFailed) { |
| 774 SetMetricName(kMetricPolicy); |
| 775 DevicePolicyCacheTestHelper helper; |
| 776 helper.ExpectMockSignedSettings(chromeos::SignedSettings::OPERATION_FAILED, |
| 777 0); |
| 778 helper.SetGoodData(); |
| 779 helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND); |
| 780 helper.SetPolicy(); |
| 781 ExpectSample(kMetricPolicyStoreFailed); |
| 782 ExpectSample(kMetricPolicyFetchOtherFailed); |
| 783 EXPECT_TRUE(CheckSamples()); |
| 784 } |
| 785 |
| 786 TEST_F(EnterpriseMetricsTest, DevicePolicyNonEnterprise) { |
| 787 SetMetricName(kMetricPolicy); |
| 788 DevicePolicyCacheTestHelper helper; |
| 789 |
| 790 scoped_ptr<CloudPolicyDataStore> data_store; |
| 791 data_store.reset(CloudPolicyDataStore::CreateForUserPolicies()); |
| 792 EnterpriseInstallAttributes install_attributes(NULL); |
| 793 DevicePolicyCache device_policy_cache(data_store.get(), &install_attributes); |
| 794 |
| 795 data_store->SetupForTesting("", "id", "user", "gaia_token", false); |
| 796 helper.SetGoodData(); |
| 797 device_policy_cache.OnRetrievePolicyCompleted( |
| 798 chromeos::SignedSettings::NOT_FOUND, helper.response()); |
| 799 |
| 800 device_policy_cache.SetPolicy(helper.response()); |
| 801 ExpectSample(kMetricPolicyFetchNonEnterpriseDevice); |
| 802 EXPECT_TRUE(CheckSamples()); |
| 803 } |
| 804 |
| 805 TEST_F(EnterpriseMetricsTest, DevicePolicyUserMismatch) { |
| 806 SetMetricName(kMetricPolicy); |
| 807 DevicePolicyCacheTestHelper helper("bogus"); |
| 808 helper.ExpectInstallAttributes(); |
| 809 helper.SetGoodData(); |
| 810 helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND); |
| 811 helper.SetPolicy(); |
| 812 ExpectSample(kMetricPolicyFetchUserMismatch); |
| 813 EXPECT_TRUE(CheckSamples()); |
| 814 } |
| 815 |
| 816 TEST_F(EnterpriseMetricsTest, DevicePolicyBadSignature) { |
| 817 SetMetricName(kMetricPolicy); |
| 818 DevicePolicyCacheTestHelper helper; |
| 819 helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND); |
| 820 helper.CompleteRetrieve(chromeos::SignedSettings::BAD_SIGNATURE); |
| 821 ExpectSample(kMetricPolicyFetchBadSignature); |
| 822 EXPECT_TRUE(CheckSamples()); |
| 823 } |
| 824 |
| 825 TEST_F(EnterpriseMetricsTest, DevicePolicyOtherFailed) { |
| 826 SetMetricName(kMetricPolicy); |
| 827 DevicePolicyCacheTestHelper helper; |
| 828 helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND); |
| 829 helper.CompleteRetrieve(chromeos::SignedSettings::OPERATION_FAILED); |
| 830 ExpectSample(kMetricPolicyFetchOtherFailed); |
| 831 EXPECT_TRUE(CheckSamples()); |
| 832 } |
| 833 |
| 834 TEST_F(EnterpriseMetricsTest, DevicePolicyFetchInvalid) { |
| 835 SetMetricName(kMetricPolicy); |
| 836 DevicePolicyCacheTestHelper helper; |
| 837 |
| 838 helper.ExpectInstallAttributes(); |
| 839 helper.CompleteRetrieve(chromeos::SignedSettings::NOT_FOUND); |
| 840 helper.SetData("\xff"); |
| 841 helper.SetPolicy(); |
| 842 ExpectSample(kMetricPolicyFetchInvalidPolicy); |
| 843 EXPECT_TRUE(CheckSamples()); |
| 844 } |
| 845 |
| 846 #endif |
| 847 |
| 848 } // namespace policy |
| OLD | NEW |