add unittests for metrics_reporter_omaha

Test: unittests pass on iot devices
Change-Id: I80f8bf83718ee3ac1b01058076513d1199d027c4
diff --git a/metrics_reporter_omaha_unittest.cc b/metrics_reporter_omaha_unittest.cc
new file mode 100644
index 0000000..7a4102e
--- /dev/null
+++ b/metrics_reporter_omaha_unittest.cc
@@ -0,0 +1,395 @@
+//
+// 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/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/common/fake_prefs.h"
+#include "update_engine/fake_system_state.h"
+
+using base::TimeDelta;
+using testing::AnyNumber;
+using testing::_;
+
+namespace chromeos_update_engine {
+class MetricsReporterOmahaTest : public ::testing::Test {
+ protected:
+  MetricsReporterOmahaTest() = default;
+
+  // Reset the metrics_lib_ to a mock library.
+  void SetUp() override {
+    mock_metrics_lib_ = new testing::NiceMock<MetricsLibraryMock>();
+    reporter_.metrics_lib_.reset(mock_metrics_lib_);
+  }
+
+  testing::NiceMock<MetricsLibraryMock>* mock_metrics_lib_;
+  MetricsReporterOmaha reporter_;
+};
+
+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) {
+  FakeSystemState fake_system_state;
+  FakeClock fake_clock;
+  FakePrefs fake_prefs;
+
+  // We need to execute the report twice to test the time since last report.
+  fake_system_state.set_clock(&fake_clock);
+  fake_system_state.set_prefs(&fake_prefs);
+  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);
+
+  EXPECT_CALL(
+      *mock_metrics_lib_,
+      SendToUMA(metrics::kMetricCheckTimeSinceLastCheckMinutes, 1, _, _, _))
+      .Times(1);
+  EXPECT_CALL(
+      *mock_metrics_lib_,
+      SendToUMA(
+          metrics::kMetricCheckTimeSinceLastCheckUptimeMinutes, 1, _, _, _))
+      .Times(1);
+
+  reporter_.ReportUpdateCheckMetrics(
+      &fake_system_state, 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));
+  reporter_.ReportUpdateCheckMetrics(
+      &fake_system_state, 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) {
+  FakeSystemState fake_system_state;
+  FakeClock fake_clock;
+  FakePrefs fake_prefs;
+
+  fake_system_state.set_clock(&fake_clock);
+  fake_system_state.set_prefs(&fake_prefs);
+  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;
+  int64_t payload_bytes_downloaded = 200 * kNumBytesInOneMiB;
+  int64_t payload_download_speed_bps = 100 * 1000;
+  DownloadSource download_source = kDownloadSourceHttpServer;
+  metrics::AttemptResult attempt_result =
+      metrics::AttemptResult::kInternalError;
+  ErrorCode internal_error_code = ErrorCode::kDownloadInvalidMetadataSignature;
+  metrics::DownloadErrorCode payload_download_error_code =
+      metrics::DownloadErrorCode::kDownloadError;
+  metrics::ConnectionType connection_type = metrics::ConnectionType::kCellular;
+
+  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 payload download metrics.
+  EXPECT_CALL(*mock_metrics_lib_,
+              SendToUMA(metrics::kMetricAttemptPayloadSizeMiB, 100, _, _, _))
+      .Times(2);
+  EXPECT_CALL(
+      *mock_metrics_lib_,
+      SendToUMA(metrics::kMetricAttemptPayloadBytesDownloadedMiB, 200, _, _, _))
+      .Times(2);
+  EXPECT_CALL(
+      *mock_metrics_lib_,
+      SendToUMA(metrics::kMetricAttemptPayloadDownloadSpeedKBps, 100, _, _, _))
+      .Times(2);
+  EXPECT_CALL(*mock_metrics_lib_,
+              SendEnumToUMA(metrics::kMetricAttemptDownloadSource,
+                            static_cast<int>(download_source),
+                            _))
+      .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_,
+              SendSparseToUMA(metrics::kMetricAttemptDownloadErrorCode,
+                              static_cast<int>(payload_download_error_code)))
+      .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);
+
+  EXPECT_CALL(*mock_metrics_lib_,
+              SendEnumToUMA(metrics::kMetricAttemptConnectionType,
+                            static_cast<int>(connection_type),
+                            _))
+      .Times(2);
+
+  reporter_.ReportUpdateAttemptMetrics(&fake_system_state,
+                                       attempt_number,
+                                       payload_type,
+                                       duration,
+                                       duration_uptime,
+                                       payload_size,
+                                       payload_bytes_downloaded,
+                                       payload_download_speed_bps,
+                                       download_source,
+                                       attempt_result,
+                                       internal_error_code,
+                                       payload_download_error_code,
+                                       connection_type);
+
+  // 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(&fake_system_state,
+                                       attempt_number,
+                                       payload_type,
+                                       duration,
+                                       duration_uptime,
+                                       payload_size,
+                                       payload_bytes_downloaded,
+                                       payload_download_speed_bps,
+                                       download_source,
+                                       attempt_result,
+                                       internal_error_code,
+                                       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);
+  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::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,
+                                          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, 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);
+}
+
+}  // namespace chromeos_update_engine