| // |
| // Copyright (C) 2017 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| |
| #include "update_engine/cros/metrics_reporter_omaha.h" |
| |
| #include <memory> |
| #include <string> |
| |
| #include <base/time/time.h> |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| #include <metrics/metrics_library_mock.h> |
| |
| #include "update_engine/common/fake_clock.h" |
| #include "update_engine/cros/fake_system_state.h" |
| |
| using base::TimeDelta; |
| using testing::_; |
| using testing::AnyNumber; |
| using testing::Return; |
| |
| namespace chromeos_update_engine { |
| class MetricsReporterOmahaTest : public ::testing::Test { |
| protected: |
| MetricsReporterOmahaTest() = default; |
| |
| // Reset the metrics_lib_ to a mock library. |
| void SetUp() override { |
| FakeSystemState::CreateInstance(); |
| fake_clock_ = FakeSystemState::Get()->fake_clock(); |
| mock_metrics_lib_ = new testing::NiceMock<MetricsLibraryMock>(); |
| reporter_.metrics_lib_.reset(mock_metrics_lib_); |
| } |
| |
| testing::NiceMock<MetricsLibraryMock>* mock_metrics_lib_; |
| MetricsReporterOmaha reporter_; |
| |
| FakeClock* fake_clock_; |
| }; |
| |
| TEST_F(MetricsReporterOmahaTest, ReportDailyMetrics) { |
| TimeDelta age = TimeDelta::FromDays(10); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendToUMA(metrics::kMetricDailyOSAgeDays, _, _, _, _)) |
| .Times(1); |
| |
| reporter_.ReportDailyMetrics(age); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportUpdateCheckMetrics) { |
| // We need to execute the report twice to test the time since last report. |
| fake_clock_->SetWallclockTime(base::Time::FromInternalValue(1000000)); |
| fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(1000000)); |
| |
| metrics::CheckResult result = metrics::CheckResult::kUpdateAvailable; |
| metrics::CheckReaction reaction = metrics::CheckReaction::kIgnored; |
| metrics::DownloadErrorCode error_code = |
| metrics::DownloadErrorCode::kHttpStatus200; |
| |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendEnumToUMA(metrics::kMetricCheckResult, static_cast<int>(result), _)) |
| .Times(2); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendEnumToUMA( |
| metrics::kMetricCheckReaction, static_cast<int>(reaction), _)) |
| .Times(2); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricCheckDownloadErrorCode, |
| static_cast<int>(error_code))) |
| .Times(2); |
| |
| // Not pinned nor rollback |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricCheckTargetVersion, _)) |
| .Times(0); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricCheckRollbackTargetVersion, _)) |
| .Times(0); |
| |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA(metrics::kMetricCheckTimeSinceLastCheckMinutes, 1, _, _, _)) |
| .Times(1); |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA( |
| metrics::kMetricCheckTimeSinceLastCheckUptimeMinutes, 1, _, _, _)) |
| .Times(1); |
| |
| reporter_.ReportUpdateCheckMetrics(result, reaction, error_code); |
| |
| // Advance the clock by 1 minute and report the same metrics again. |
| fake_clock_->SetWallclockTime(base::Time::FromInternalValue(61000000)); |
| fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(61000000)); |
| // Allow rollback |
| reporter_.ReportUpdateCheckMetrics(result, reaction, error_code); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportUpdateCheckMetricsPinned) { |
| OmahaRequestParams params; |
| params.set_target_version_prefix("10575."); |
| params.set_rollback_allowed(false); |
| FakeSystemState::Get()->set_request_params(¶ms); |
| |
| metrics::CheckResult result = metrics::CheckResult::kUpdateAvailable; |
| metrics::CheckReaction reaction = metrics::CheckReaction::kIgnored; |
| metrics::DownloadErrorCode error_code = |
| metrics::DownloadErrorCode::kHttpStatus200; |
| |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricCheckDownloadErrorCode, _)); |
| // Target version set, but not a rollback. |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricCheckTargetVersion, 10575)) |
| .Times(1); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricCheckRollbackTargetVersion, _)) |
| .Times(0); |
| |
| reporter_.ReportUpdateCheckMetrics(result, reaction, error_code); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportUpdateCheckMetricsRollback) { |
| OmahaRequestParams params; |
| params.set_target_version_prefix("10575."); |
| params.set_rollback_allowed(true); |
| FakeSystemState::Get()->set_request_params(¶ms); |
| |
| metrics::CheckResult result = metrics::CheckResult::kUpdateAvailable; |
| metrics::CheckReaction reaction = metrics::CheckReaction::kIgnored; |
| metrics::DownloadErrorCode error_code = |
| metrics::DownloadErrorCode::kHttpStatus200; |
| |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricCheckDownloadErrorCode, _)); |
| // Rollback. |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricCheckTargetVersion, 10575)) |
| .Times(1); |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricCheckRollbackTargetVersion, 10575)) |
| .Times(1); |
| |
| reporter_.ReportUpdateCheckMetrics(result, reaction, error_code); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, |
| ReportAbnormallyTerminatedUpdateAttemptMetrics) { |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendEnumToUMA(metrics::kMetricAttemptResult, |
| static_cast<int>( |
| metrics::AttemptResult::kAbnormalTermination), |
| _)) |
| .Times(1); |
| |
| reporter_.ReportAbnormallyTerminatedUpdateAttemptMetrics(); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportUpdateAttemptMetrics) { |
| fake_clock_->SetWallclockTime(base::Time::FromInternalValue(1000000)); |
| fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(1000000)); |
| |
| int attempt_number = 1; |
| PayloadType payload_type = kPayloadTypeFull; |
| TimeDelta duration = TimeDelta::FromMinutes(1000); |
| TimeDelta duration_uptime = TimeDelta::FromMinutes(1000); |
| |
| int64_t payload_size = 100 * kNumBytesInOneMiB; |
| |
| metrics::AttemptResult attempt_result = |
| metrics::AttemptResult::kInternalError; |
| ErrorCode internal_error_code = ErrorCode::kDownloadInvalidMetadataSignature; |
| |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendToUMA(metrics::kMetricAttemptNumber, attempt_number, _, _, _)) |
| .Times(2); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendEnumToUMA(metrics::kMetricAttemptPayloadType, |
| static_cast<int>(payload_type), |
| _)) |
| .Times(2); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendToUMA(metrics::kMetricAttemptDurationMinutes, |
| duration.InMinutes(), |
| _, |
| _, |
| _)) |
| .Times(2); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendToUMA(metrics::kMetricAttemptDurationUptimeMinutes, |
| duration_uptime.InMinutes(), |
| _, |
| _, |
| _)) |
| .Times(2); |
| |
| // Check the report of attempt result. |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendEnumToUMA( |
| metrics::kMetricAttemptResult, static_cast<int>(attempt_result), _)) |
| .Times(2); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendEnumToUMA(metrics::kMetricAttemptInternalErrorCode, |
| static_cast<int>(internal_error_code), |
| _)) |
| .Times(2); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendToUMA(metrics::kMetricAttemptPayloadSizeMiB, 100, _, _, _)) |
| .Times(2); |
| |
| // Check the duration between two reports. |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA(metrics::kMetricAttemptTimeSinceLastAttemptMinutes, 1, _, _, _)) |
| .Times(1); |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA( |
| metrics::kMetricAttemptTimeSinceLastAttemptUptimeMinutes, 1, _, _, _)) |
| .Times(1); |
| |
| reporter_.ReportUpdateAttemptMetrics(attempt_number, |
| payload_type, |
| duration, |
| duration_uptime, |
| payload_size, |
| attempt_result, |
| internal_error_code); |
| |
| // Advance the clock by 1 minute and report the same metrics again. |
| fake_clock_->SetWallclockTime(base::Time::FromInternalValue(61000000)); |
| fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(61000000)); |
| reporter_.ReportUpdateAttemptMetrics(attempt_number, |
| payload_type, |
| duration, |
| duration_uptime, |
| payload_size, |
| attempt_result, |
| internal_error_code); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportUpdateAttemptDownloadMetrics) { |
| int64_t payload_bytes_downloaded = 200 * kNumBytesInOneMiB; |
| int64_t payload_download_speed_bps = 100 * 1000; |
| DownloadSource download_source = kDownloadSourceHttpServer; |
| metrics::DownloadErrorCode payload_download_error_code = |
| metrics::DownloadErrorCode::kDownloadError; |
| metrics::ConnectionType connection_type = metrics::ConnectionType::kCellular; |
| |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA(metrics::kMetricAttemptPayloadBytesDownloadedMiB, 200, _, _, _)) |
| .Times(1); |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA(metrics::kMetricAttemptPayloadDownloadSpeedKBps, 100, _, _, _)) |
| .Times(1); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendEnumToUMA(metrics::kMetricAttemptDownloadSource, |
| static_cast<int>(download_source), |
| _)) |
| .Times(1); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricAttemptDownloadErrorCode, |
| static_cast<int>(payload_download_error_code))) |
| .Times(1); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendEnumToUMA(metrics::kMetricAttemptConnectionType, |
| static_cast<int>(connection_type), |
| _)) |
| .Times(1); |
| |
| reporter_.ReportUpdateAttemptDownloadMetrics(payload_bytes_downloaded, |
| payload_download_speed_bps, |
| download_source, |
| payload_download_error_code, |
| connection_type); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportSuccessfulUpdateMetrics) { |
| int attempt_count = 3; |
| int updates_abandoned_count = 2; |
| PayloadType payload_type = kPayloadTypeDelta; |
| int64_t payload_size = 200 * kNumBytesInOneMiB; |
| int64_t num_bytes_downloaded[kNumDownloadSources] = {}; |
| // 200MiB payload downloaded from HttpsServer. |
| num_bytes_downloaded[0] = 200 * kNumBytesInOneMiB; |
| int download_overhead_percentage = 20; |
| TimeDelta total_duration = TimeDelta::FromMinutes(30); |
| TimeDelta total_duration_uptime = TimeDelta::FromMinutes(20); |
| int reboot_count = 2; |
| int url_switch_count = 2; |
| |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA(metrics::kMetricSuccessfulUpdatePayloadSizeMiB, 200, _, _, _)) |
| .Times(1); |
| |
| // Check the report to both BytesDownloadedMiBHttpsServer and |
| // BytesDownloadedMiB |
| std::string DownloadedMiBMetric = |
| metrics::kMetricSuccessfulUpdateBytesDownloadedMiB; |
| DownloadedMiBMetric += "HttpsServer"; |
| EXPECT_CALL(*mock_metrics_lib_, SendToUMA(DownloadedMiBMetric, 200, _, _, _)) |
| .Times(1); |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA( |
| metrics::kMetricSuccessfulUpdateBytesDownloadedMiB, 200, _, _, _)) |
| .Times(1); |
| |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA( |
| metrics::kMetricSuccessfulUpdateDownloadSourcesUsed, 1, _, _, _)) |
| .Times(1); |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA(metrics::kMetricSuccessfulUpdateDownloadOverheadPercentage, |
| 20, |
| _, |
| _, |
| _)); |
| |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendToUMA(metrics::kMetricSuccessfulUpdateUrlSwitchCount, |
| url_switch_count, |
| _, |
| _, |
| _)) |
| .Times(1); |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA( |
| metrics::kMetricSuccessfulUpdateTotalDurationMinutes, 30, _, _, _)) |
| .Times(1); |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA(metrics::kMetricSuccessfulUpdateTotalDurationUptimeMinutes, |
| 20, |
| _, |
| _, |
| _)) |
| .Times(1); |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA( |
| metrics::kMetricSuccessfulUpdateRebootCount, reboot_count, _, _, _)) |
| .Times(1); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendEnumToUMA( |
| metrics::kMetricSuccessfulUpdatePayloadType, payload_type, _)) |
| .Times(1); |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA( |
| metrics::kMetricSuccessfulUpdateAttemptCount, attempt_count, _, _, _)) |
| .Times(1); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendToUMA(metrics::kMetricSuccessfulUpdateUpdatesAbandonedCount, |
| updates_abandoned_count, |
| _, |
| _, |
| _)) |
| .Times(1); |
| |
| reporter_.ReportSuccessfulUpdateMetrics(attempt_count, |
| updates_abandoned_count, |
| payload_type, |
| payload_size, |
| num_bytes_downloaded, |
| download_overhead_percentage, |
| total_duration, |
| total_duration_uptime, |
| reboot_count, |
| url_switch_count); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportRollbackMetrics) { |
| metrics::RollbackResult result = metrics::RollbackResult::kSuccess; |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendEnumToUMA( |
| metrics::kMetricRollbackResult, static_cast<int>(result), _)) |
| .Times(1); |
| |
| reporter_.ReportRollbackMetrics(result); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportEnterpriseRollbackMetrics) { |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricEnterpriseRollbackSuccess, 10575)) |
| .Times(1); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricEnterpriseRollbackFailure, 10323)) |
| .Times(1); |
| |
| reporter_.ReportEnterpriseRollbackMetrics(/*success=*/true, "10575.39.2"); |
| reporter_.ReportEnterpriseRollbackMetrics(/*success=*/false, "10323.67.7"); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportCertificateCheckMetrics) { |
| ServerToCheck server_to_check = ServerToCheck::kUpdate; |
| CertificateCheckResult result = CertificateCheckResult::kValid; |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendEnumToUMA(metrics::kMetricCertificateCheckUpdateCheck, |
| static_cast<int>(result), |
| _)) |
| .Times(1); |
| |
| reporter_.ReportCertificateCheckMetrics(server_to_check, result); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportFailedUpdateCount) { |
| int target_attempt = 3; |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA(metrics::kMetricFailedUpdateCount, target_attempt, _, _, _)) |
| .Times(1); |
| |
| reporter_.ReportFailedUpdateCount(target_attempt); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportTimeToReboot) { |
| int time_to_reboot_minutes = 1000; |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA( |
| metrics::kMetricTimeToRebootMinutes, time_to_reboot_minutes, _, _, _)) |
| .Times(1); |
| |
| reporter_.ReportTimeToReboot(time_to_reboot_minutes); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportInstallDateProvisioningSource) { |
| int source = 2; |
| int max = 5; |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendEnumToUMA(metrics::kMetricInstallDateProvisioningSource, source, max)) |
| .Times(1); |
| |
| reporter_.ReportInstallDateProvisioningSource(source, max); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportKeyVersionMetrics) { |
| int kernel_min_version = 0x00040002; |
| int kernel_max_rollforward_version = 0xfffffffe; |
| bool kernel_max_rollforward_success = true; |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricKernelMinVersion, kernel_min_version)) |
| .Times(1); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendSparseToUMA(metrics::kMetricKernelMaxRollforwardVersion, |
| kernel_max_rollforward_version)) |
| .Times(1); |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendBoolToUMA(metrics::kMetricKernelMaxRollforwardSetSuccess, |
| kernel_max_rollforward_success)) |
| .Times(1); |
| |
| reporter_.ReportKeyVersionMetrics(kernel_min_version, |
| kernel_max_rollforward_version, |
| kernel_max_rollforward_success); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, ReportEnterpriseUpdateSeenToDownloadDays) { |
| constexpr int kDaysToUpdate = 10; |
| constexpr int kMinBucket = 1; |
| constexpr int kMaxBucket = 6 * 30; // approximately 6 months |
| constexpr int kNumBuckets = 50; |
| |
| EXPECT_CALL(*mock_metrics_lib_, |
| SendToUMA(metrics::kMetricSuccessfulUpdateDurationFromSeenDays, |
| kDaysToUpdate, |
| kMinBucket, |
| kMaxBucket, |
| kNumBuckets)) |
| .Times(1); |
| |
| reporter_.ReportEnterpriseUpdateSeenToDownloadDays( |
| false /* has_time_restriction_policy */, kDaysToUpdate); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, |
| ReportEnterpriseTimeRestrictedUpdateSeenToDownloadTime) { |
| const int kDaysToUpdate = 15; |
| constexpr int kMinBucket = 1; |
| constexpr int kMaxBucket = 6 * 30; // approximately 6 months |
| constexpr int kNumBuckets = 50; |
| |
| EXPECT_CALL( |
| *mock_metrics_lib_, |
| SendToUMA( |
| metrics::kMetricSuccessfulUpdateDurationFromSeenTimeRestrictedDays, |
| kDaysToUpdate, |
| kMinBucket, |
| kMaxBucket, |
| kNumBuckets)) |
| .Times(1); |
| |
| reporter_.ReportEnterpriseUpdateSeenToDownloadDays( |
| true /* has_time_restriction_policy */, kDaysToUpdate); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, WallclockDurationHelper) { |
| base::TimeDelta duration; |
| const std::string state_variable_key = "test-prefs"; |
| |
| // Initialize wallclock to 1 sec. |
| fake_clock_->SetWallclockTime(base::Time::FromInternalValue(1000000)); |
| |
| // First time called so no previous measurement available. |
| EXPECT_FALSE( |
| reporter_.WallclockDurationHelper(state_variable_key, &duration)); |
| |
| // Next time, we should get zero since the clock didn't advance. |
| EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 0); |
| |
| // We can also call it as many times as we want with it being |
| // considered a failure. |
| EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 0); |
| EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 0); |
| |
| // Advance the clock one second, then we should get 1 sec on the |
| // next call and 0 sec on the subsequent call. |
| fake_clock_->SetWallclockTime(base::Time::FromInternalValue(2000000)); |
| EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 1); |
| EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 0); |
| |
| // Advance clock two seconds and we should get 2 sec and then 0 sec. |
| fake_clock_->SetWallclockTime(base::Time::FromInternalValue(4000000)); |
| EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 2); |
| EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 0); |
| |
| // There's a possibility that the wallclock can go backwards (NTP |
| // adjustments, for example) so check that we properly handle this |
| // case. |
| fake_clock_->SetWallclockTime(base::Time::FromInternalValue(3000000)); |
| EXPECT_FALSE( |
| reporter_.WallclockDurationHelper(state_variable_key, &duration)); |
| fake_clock_->SetWallclockTime(base::Time::FromInternalValue(4000000)); |
| EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 1); |
| } |
| |
| TEST_F(MetricsReporterOmahaTest, MonotonicDurationHelper) { |
| int64_t storage = 0; |
| base::TimeDelta duration; |
| |
| // Initialize monotonic clock to 1 sec. |
| fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(1000000)); |
| |
| // First time called so no previous measurement available. |
| EXPECT_FALSE(reporter_.MonotonicDurationHelper(&storage, &duration)); |
| |
| // Next time, we should get zero since the clock didn't advance. |
| EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 0); |
| |
| // We can also call it as many times as we want with it being |
| // considered a failure. |
| EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 0); |
| EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 0); |
| |
| // Advance the clock one second, then we should get 1 sec on the |
| // next call and 0 sec on the subsequent call. |
| fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(2000000)); |
| EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 1); |
| EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 0); |
| |
| // Advance clock two seconds and we should get 2 sec and then 0 sec. |
| fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(4000000)); |
| EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 2); |
| EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration)); |
| EXPECT_EQ(duration.InSeconds(), 0); |
| } |
| |
| } // namespace chromeos_update_engine |