add unittests for metrics_reporter_omaha

Test: unittests pass on iot devices
Change-Id: I80f8bf83718ee3ac1b01058076513d1199d027c4
diff --git a/Android.mk b/Android.mk
index 8da8ede..d34898a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -947,6 +947,7 @@
     common_service_unittest.cc \
     fake_system_state.cc \
     image_properties_android_unittest.cc \
+    metrics_reporter_omaha_unittest.cc \
     metrics_utils_unittest.cc \
     omaha_request_action_unittest.cc \
     omaha_request_params_unittest.cc \
diff --git a/metrics_reporter_omaha.cc b/metrics_reporter_omaha.cc
index fcbe7e4..3aaf1c6 100644
--- a/metrics_reporter_omaha.cc
+++ b/metrics_reporter_omaha.cc
@@ -16,6 +16,7 @@
 
 #include "update_engine/metrics_reporter_omaha.h"
 
+#include <memory>
 #include <string>
 
 #include <base/logging.h>
@@ -32,97 +33,103 @@
 
 namespace chromeos_update_engine {
 
+namespace metrics {
+
 // UpdateEngine.Daily.* metrics.
-constexpr char kMetricDailyOSAgeDays[] = "UpdateEngine.Daily.OSAgeDays";
+const char kMetricDailyOSAgeDays[] = "UpdateEngine.Daily.OSAgeDays";
 
 // UpdateEngine.Check.* metrics.
-constexpr char kMetricCheckDownloadErrorCode[] =
+const char kMetricCheckDownloadErrorCode[] =
     "UpdateEngine.Check.DownloadErrorCode";
-constexpr char kMetricCheckReaction[] = "UpdateEngine.Check.Reaction";
-constexpr char kMetricCheckResult[] = "UpdateEngine.Check.Result";
-constexpr char kMetricCheckTimeSinceLastCheckMinutes[] =
+const char kMetricCheckReaction[] = "UpdateEngine.Check.Reaction";
+const char kMetricCheckResult[] = "UpdateEngine.Check.Result";
+const char kMetricCheckTimeSinceLastCheckMinutes[] =
     "UpdateEngine.Check.TimeSinceLastCheckMinutes";
-constexpr char kMetricCheckTimeSinceLastCheckUptimeMinutes[] =
+const char kMetricCheckTimeSinceLastCheckUptimeMinutes[] =
     "UpdateEngine.Check.TimeSinceLastCheckUptimeMinutes";
 
 // UpdateEngine.Attempt.* metrics.
-constexpr char kMetricAttemptNumber[] = "UpdateEngine.Attempt.Number";
-constexpr char kMetricAttemptPayloadType[] = "UpdateEngine.Attempt.PayloadType";
-constexpr char kMetricAttemptPayloadSizeMiB[] =
+const char kMetricAttemptNumber[] = "UpdateEngine.Attempt.Number";
+const char kMetricAttemptPayloadType[] = "UpdateEngine.Attempt.PayloadType";
+const char kMetricAttemptPayloadSizeMiB[] =
     "UpdateEngine.Attempt.PayloadSizeMiB";
-constexpr char kMetricAttemptConnectionType[] =
+const char kMetricAttemptConnectionType[] =
     "UpdateEngine.Attempt.ConnectionType";
-constexpr char kMetricAttemptDurationMinutes[] =
+const char kMetricAttemptDurationMinutes[] =
     "UpdateEngine.Attempt.DurationMinutes";
-constexpr char kMetricAttemptDurationUptimeMinutes[] =
+const char kMetricAttemptDurationUptimeMinutes[] =
     "UpdateEngine.Attempt.DurationUptimeMinutes";
-constexpr char kMetricAttemptTimeSinceLastAttemptMinutes[] =
+const char kMetricAttemptTimeSinceLastAttemptMinutes[] =
     "UpdateEngine.Attempt.TimeSinceLastAttemptMinutes";
-constexpr char kMetricAttemptTimeSinceLastAttemptUptimeMinutes[] =
+const char kMetricAttemptTimeSinceLastAttemptUptimeMinutes[] =
     "UpdateEngine.Attempt.TimeSinceLastAttemptUptimeMinutes";
-constexpr char kMetricAttemptPayloadBytesDownloadedMiB[] =
+const char kMetricAttemptPayloadBytesDownloadedMiB[] =
     "UpdateEngine.Attempt.PayloadBytesDownloadedMiB";
-constexpr char kMetricAttemptPayloadDownloadSpeedKBps[] =
+const char kMetricAttemptPayloadDownloadSpeedKBps[] =
     "UpdateEngine.Attempt.PayloadDownloadSpeedKBps";
-constexpr char kMetricAttemptDownloadSource[] =
+const char kMetricAttemptDownloadSource[] =
     "UpdateEngine.Attempt.DownloadSource";
-constexpr char kMetricAttemptResult[] = "UpdateEngine.Attempt.Result";
-constexpr char kMetricAttemptInternalErrorCode[] =
+const char kMetricAttemptResult[] = "UpdateEngine.Attempt.Result";
+const char kMetricAttemptInternalErrorCode[] =
     "UpdateEngine.Attempt.InternalErrorCode";
-constexpr char kMetricAttemptDownloadErrorCode[] =
+const char kMetricAttemptDownloadErrorCode[] =
     "UpdateEngine.Attempt.DownloadErrorCode";
 
 // UpdateEngine.SuccessfulUpdate.* metrics.
-constexpr char kMetricSuccessfulUpdateAttemptCount[] =
+const char kMetricSuccessfulUpdateAttemptCount[] =
     "UpdateEngine.SuccessfulUpdate.AttemptCount";
-constexpr char kMetricSuccessfulUpdateBytesDownloadedMiB[] =
+const char kMetricSuccessfulUpdateBytesDownloadedMiB[] =
     "UpdateEngine.SuccessfulUpdate.BytesDownloadedMiB";
-constexpr char kMetricSuccessfulUpdateDownloadOverheadPercentage[] =
+const char kMetricSuccessfulUpdateDownloadOverheadPercentage[] =
     "UpdateEngine.SuccessfulUpdate.DownloadOverheadPercentage";
-constexpr char kMetricSuccessfulUpdateDownloadSourcesUsed[] =
+const char kMetricSuccessfulUpdateDownloadSourcesUsed[] =
     "UpdateEngine.SuccessfulUpdate.DownloadSourcesUsed";
-constexpr char kMetricSuccessfulUpdatePayloadType[] =
+const char kMetricSuccessfulUpdatePayloadType[] =
     "UpdateEngine.SuccessfulUpdate.PayloadType";
-constexpr char kMetricSuccessfulUpdatePayloadSizeMiB[] =
+const char kMetricSuccessfulUpdatePayloadSizeMiB[] =
     "UpdateEngine.SuccessfulUpdate.PayloadSizeMiB";
-constexpr char kMetricSuccessfulUpdateRebootCount[] =
+const char kMetricSuccessfulUpdateRebootCount[] =
     "UpdateEngine.SuccessfulUpdate.RebootCount";
-constexpr char kMetricSuccessfulUpdateTotalDurationMinutes[] =
+const char kMetricSuccessfulUpdateTotalDurationMinutes[] =
     "UpdateEngine.SuccessfulUpdate.TotalDurationMinutes";
-constexpr char kMetricSuccessfulUpdateUpdatesAbandonedCount[] =
+const char kMetricSuccessfulUpdateUpdatesAbandonedCount[] =
     "UpdateEngine.SuccessfulUpdate.UpdatesAbandonedCount";
-constexpr char kMetricSuccessfulUpdateUrlSwitchCount[] =
+const char kMetricSuccessfulUpdateUrlSwitchCount[] =
     "UpdateEngine.SuccessfulUpdate.UrlSwitchCount";
 
 // UpdateEngine.Rollback.* metric.
-constexpr char kMetricRollbackResult[] = "UpdateEngine.Rollback.Result";
+const char kMetricRollbackResult[] = "UpdateEngine.Rollback.Result";
 
 // UpdateEngine.CertificateCheck.* metrics.
-constexpr char kMetricCertificateCheckUpdateCheck[] =
+const char kMetricCertificateCheckUpdateCheck[] =
     "UpdateEngine.CertificateCheck.UpdateCheck";
-constexpr char kMetricCertificateCheckDownload[] =
+const char kMetricCertificateCheckDownload[] =
     "UpdateEngine.CertificateCheck.Download";
 
 // UpdateEngine.* metrics.
-constexpr char kMetricFailedUpdateCount[] = "UpdateEngine.FailedUpdateCount";
-constexpr char kMetricInstallDateProvisioningSource[] =
+const char kMetricFailedUpdateCount[] = "UpdateEngine.FailedUpdateCount";
+const char kMetricInstallDateProvisioningSource[] =
     "UpdateEngine.InstallDateProvisioningSource";
-constexpr char kMetricTimeToRebootMinutes[] =
-    "UpdateEngine.TimeToRebootMinutes";
+const char kMetricTimeToRebootMinutes[] = "UpdateEngine.TimeToRebootMinutes";
+
+}  // namespace metrics
+
+MetricsReporterOmaha::MetricsReporterOmaha()
+    : metrics_lib_(new MetricsLibrary()) {}
 
 void MetricsReporterOmaha::Initialize() {
-  metrics_lib_.Init();
+  metrics_lib_->Init();
 }
 
 void MetricsReporterOmaha::ReportDailyMetrics(base::TimeDelta os_age) {
-  string metric = kMetricDailyOSAgeDays;
+  string metric = metrics::kMetricDailyOSAgeDays;
   LOG(INFO) << "Uploading " << utils::FormatTimeDelta(os_age) << " for metric "
             << metric;
-  metrics_lib_.SendToUMA(metric,
-                         static_cast<int>(os_age.InDays()),
-                         0,       // min: 0 days
-                         6 * 30,  // max: 6 months (approx)
-                         50);     // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          static_cast<int>(os_age.InDays()),
+                          0,       // min: 0 days
+                          6 * 30,  // max: 6 months (approx)
+                          50);     // num_buckets
 }
 
 void MetricsReporterOmaha::ReportUpdateCheckMetrics(
@@ -135,24 +142,24 @@
   int max_value;
 
   if (result != metrics::CheckResult::kUnset) {
-    metric = kMetricCheckResult;
+    metric = metrics::kMetricCheckResult;
     value = static_cast<int>(result);
     max_value = static_cast<int>(metrics::CheckResult::kNumConstants) - 1;
     LOG(INFO) << "Sending " << value << " for metric " << metric << " (enum)";
-    metrics_lib_.SendEnumToUMA(metric, value, max_value);
+    metrics_lib_->SendEnumToUMA(metric, value, max_value);
   }
   if (reaction != metrics::CheckReaction::kUnset) {
-    metric = kMetricCheckReaction;
+    metric = metrics::kMetricCheckReaction;
     value = static_cast<int>(reaction);
     max_value = static_cast<int>(metrics::CheckReaction::kNumConstants) - 1;
     LOG(INFO) << "Sending " << value << " for metric " << metric << " (enum)";
-    metrics_lib_.SendEnumToUMA(metric, value, max_value);
+    metrics_lib_->SendEnumToUMA(metric, value, max_value);
   }
   if (download_error_code != metrics::DownloadErrorCode::kUnset) {
-    metric = kMetricCheckDownloadErrorCode;
+    metric = metrics::kMetricCheckDownloadErrorCode;
     value = static_cast<int>(download_error_code);
     LOG(INFO) << "Sending " << value << " for metric " << metric << " (sparse)";
-    metrics_lib_.SendSparseToUMA(metric, value);
+    metrics_lib_->SendSparseToUMA(metric, value);
   }
 
   base::TimeDelta time_since_last;
@@ -160,39 +167,39 @@
           system_state,
           kPrefsMetricsCheckLastReportingTime,
           &time_since_last)) {
-    metric = kMetricCheckTimeSinceLastCheckMinutes;
+    metric = metrics::kMetricCheckTimeSinceLastCheckMinutes;
     LOG(INFO) << "Sending " << utils::FormatTimeDelta(time_since_last)
               << " for metric " << metric;
-    metrics_lib_.SendToUMA(metric,
-                           time_since_last.InMinutes(),
-                           0,             // min: 0 min
-                           30 * 24 * 60,  // max: 30 days
-                           50);           // num_buckets
+    metrics_lib_->SendToUMA(metric,
+                            time_since_last.InMinutes(),
+                            0,             // min: 0 min
+                            30 * 24 * 60,  // max: 30 days
+                            50);           // num_buckets
   }
 
   base::TimeDelta uptime_since_last;
   static int64_t uptime_since_last_storage = 0;
   if (metrics_utils::MonotonicDurationHelper(
           system_state, &uptime_since_last_storage, &uptime_since_last)) {
-    metric = kMetricCheckTimeSinceLastCheckUptimeMinutes;
+    metric = metrics::kMetricCheckTimeSinceLastCheckUptimeMinutes;
     LOG(INFO) << "Sending " << utils::FormatTimeDelta(uptime_since_last)
               << " for metric " << metric;
-    metrics_lib_.SendToUMA(metric,
-                           uptime_since_last.InMinutes(),
-                           0,             // min: 0 min
-                           30 * 24 * 60,  // max: 30 days
-                           50);           // num_buckets
+    metrics_lib_->SendToUMA(metric,
+                            uptime_since_last.InMinutes(),
+                            0,             // min: 0 min
+                            30 * 24 * 60,  // max: 30 days
+                            50);           // num_buckets
   }
 }
 
 void MetricsReporterOmaha::ReportAbnormallyTerminatedUpdateAttemptMetrics() {
-  string metric = kMetricAttemptResult;
+  string metric = metrics::kMetricAttemptResult;
   metrics::AttemptResult attempt_result =
       metrics::AttemptResult::kAbnormalTermination;
 
   LOG(INFO) << "Uploading " << static_cast<int>(attempt_result)
             << " for metric " << metric;
-  metrics_lib_.SendEnumToUMA(
+  metrics_lib_->SendEnumToUMA(
       metric,
       static_cast<int>(attempt_result),
       static_cast<int>(metrics::AttemptResult::kNumConstants));
@@ -212,94 +219,94 @@
     ErrorCode internal_error_code,
     metrics::DownloadErrorCode payload_download_error_code,
     metrics::ConnectionType connection_type) {
-  string metric = kMetricAttemptNumber;
+  string metric = metrics::kMetricAttemptNumber;
   LOG(INFO) << "Uploading " << attempt_number << " for metric " << metric;
-  metrics_lib_.SendToUMA(metric,
-                         attempt_number,
-                         0,    // min: 0 attempts
-                         49,   // max: 49 attempts
-                         50);  // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          attempt_number,
+                          0,    // min: 0 attempts
+                          49,   // max: 49 attempts
+                          50);  // num_buckets
 
-  metric = kMetricAttemptPayloadType;
+  metric = metrics::kMetricAttemptPayloadType;
   LOG(INFO) << "Uploading " << utils::ToString(payload_type) << " for metric "
             << metric;
-  metrics_lib_.SendEnumToUMA(metric, payload_type, kNumPayloadTypes);
+  metrics_lib_->SendEnumToUMA(metric, payload_type, kNumPayloadTypes);
 
-  metric = kMetricAttemptDurationMinutes;
+  metric = metrics::kMetricAttemptDurationMinutes;
   LOG(INFO) << "Uploading " << utils::FormatTimeDelta(duration)
             << " for metric " << metric;
-  metrics_lib_.SendToUMA(metric,
-                         duration.InMinutes(),
-                         0,             // min: 0 min
-                         10 * 24 * 60,  // max: 10 days
-                         50);           // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          duration.InMinutes(),
+                          0,             // min: 0 min
+                          10 * 24 * 60,  // max: 10 days
+                          50);           // num_buckets
 
-  metric = kMetricAttemptDurationUptimeMinutes;
+  metric = metrics::kMetricAttemptDurationUptimeMinutes;
   LOG(INFO) << "Uploading " << utils::FormatTimeDelta(duration_uptime)
             << " for metric " << metric;
-  metrics_lib_.SendToUMA(metric,
-                         duration_uptime.InMinutes(),
-                         0,             // min: 0 min
-                         10 * 24 * 60,  // max: 10 days
-                         50);           // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          duration_uptime.InMinutes(),
+                          0,             // min: 0 min
+                          10 * 24 * 60,  // max: 10 days
+                          50);           // num_buckets
 
-  metric = kMetricAttemptPayloadSizeMiB;
+  metric = metrics::kMetricAttemptPayloadSizeMiB;
   int64_t payload_size_mib = payload_size / kNumBytesInOneMiB;
   LOG(INFO) << "Uploading " << payload_size_mib << " for metric " << metric;
-  metrics_lib_.SendToUMA(metric,
-                         payload_size_mib,
-                         0,     // min: 0 MiB
-                         1024,  // max: 1024 MiB = 1 GiB
-                         50);   // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          payload_size_mib,
+                          0,     // min: 0 MiB
+                          1024,  // max: 1024 MiB = 1 GiB
+                          50);   // num_buckets
 
-  metric = kMetricAttemptPayloadBytesDownloadedMiB;
+  metric = metrics::kMetricAttemptPayloadBytesDownloadedMiB;
   int64_t payload_bytes_downloaded_mib =
       payload_bytes_downloaded / kNumBytesInOneMiB;
   LOG(INFO) << "Uploading " << payload_bytes_downloaded_mib << " for metric "
             << metric;
-  metrics_lib_.SendToUMA(metric,
-                         payload_bytes_downloaded_mib,
-                         0,     // min: 0 MiB
-                         1024,  // max: 1024 MiB = 1 GiB
-                         50);   // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          payload_bytes_downloaded_mib,
+                          0,     // min: 0 MiB
+                          1024,  // max: 1024 MiB = 1 GiB
+                          50);   // num_buckets
 
-  metric = kMetricAttemptPayloadDownloadSpeedKBps;
+  metric = metrics::kMetricAttemptPayloadDownloadSpeedKBps;
   int64_t payload_download_speed_kbps = payload_download_speed_bps / 1000;
   LOG(INFO) << "Uploading " << payload_download_speed_kbps << " for metric "
             << metric;
-  metrics_lib_.SendToUMA(metric,
-                         payload_download_speed_kbps,
-                         0,          // min: 0 kB/s
-                         10 * 1000,  // max: 10000 kB/s = 10 MB/s
-                         50);        // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          payload_download_speed_kbps,
+                          0,          // min: 0 kB/s
+                          10 * 1000,  // max: 10000 kB/s = 10 MB/s
+                          50);        // num_buckets
 
-  metric = kMetricAttemptDownloadSource;
+  metric = metrics::kMetricAttemptDownloadSource;
   LOG(INFO) << "Uploading " << download_source << " for metric " << metric;
-  metrics_lib_.SendEnumToUMA(metric, download_source, kNumDownloadSources);
+  metrics_lib_->SendEnumToUMA(metric, download_source, kNumDownloadSources);
 
-  metric = kMetricAttemptResult;
+  metric = metrics::kMetricAttemptResult;
   LOG(INFO) << "Uploading " << static_cast<int>(attempt_result)
             << " for metric " << metric;
-  metrics_lib_.SendEnumToUMA(
+  metrics_lib_->SendEnumToUMA(
       metric,
       static_cast<int>(attempt_result),
       static_cast<int>(metrics::AttemptResult::kNumConstants));
 
   if (internal_error_code != ErrorCode::kSuccess) {
-    metric = kMetricAttemptInternalErrorCode;
+    metric = metrics::kMetricAttemptInternalErrorCode;
     LOG(INFO) << "Uploading " << internal_error_code << " for metric "
               << metric;
-    metrics_lib_.SendEnumToUMA(metric,
-                               static_cast<int>(internal_error_code),
-                               static_cast<int>(ErrorCode::kUmaReportedMax));
+    metrics_lib_->SendEnumToUMA(metric,
+                                static_cast<int>(internal_error_code),
+                                static_cast<int>(ErrorCode::kUmaReportedMax));
   }
 
   if (payload_download_error_code != metrics::DownloadErrorCode::kUnset) {
-    metric = kMetricAttemptDownloadErrorCode;
+    metric = metrics::kMetricAttemptDownloadErrorCode;
     LOG(INFO) << "Uploading " << static_cast<int>(payload_download_error_code)
               << " for metric " << metric << " (sparse)";
-    metrics_lib_.SendSparseToUMA(metric,
-                                 static_cast<int>(payload_download_error_code));
+    metrics_lib_->SendSparseToUMA(
+        metric, static_cast<int>(payload_download_error_code));
   }
 
   base::TimeDelta time_since_last;
@@ -307,34 +314,34 @@
           system_state,
           kPrefsMetricsAttemptLastReportingTime,
           &time_since_last)) {
-    metric = kMetricAttemptTimeSinceLastAttemptMinutes;
+    metric = metrics::kMetricAttemptTimeSinceLastAttemptMinutes;
     LOG(INFO) << "Sending " << utils::FormatTimeDelta(time_since_last)
               << " for metric " << metric;
-    metrics_lib_.SendToUMA(metric,
-                           time_since_last.InMinutes(),
-                           0,             // min: 0 min
-                           30 * 24 * 60,  // max: 30 days
-                           50);           // num_buckets
+    metrics_lib_->SendToUMA(metric,
+                            time_since_last.InMinutes(),
+                            0,             // min: 0 min
+                            30 * 24 * 60,  // max: 30 days
+                            50);           // num_buckets
   }
 
   static int64_t uptime_since_last_storage = 0;
   base::TimeDelta uptime_since_last;
   if (metrics_utils::MonotonicDurationHelper(
           system_state, &uptime_since_last_storage, &uptime_since_last)) {
-    metric = kMetricAttemptTimeSinceLastAttemptUptimeMinutes;
+    metric = metrics::kMetricAttemptTimeSinceLastAttemptUptimeMinutes;
     LOG(INFO) << "Sending " << utils::FormatTimeDelta(uptime_since_last)
               << " for metric " << metric;
-    metrics_lib_.SendToUMA(metric,
-                           uptime_since_last.InMinutes(),
-                           0,             // min: 0 min
-                           30 * 24 * 60,  // max: 30 days
-                           50);           // num_buckets
+    metrics_lib_->SendToUMA(metric,
+                            uptime_since_last.InMinutes(),
+                            0,             // min: 0 min
+                            30 * 24 * 60,  // max: 30 days
+                            50);           // num_buckets
   }
 
-  metric = kMetricAttemptConnectionType;
+  metric = metrics::kMetricAttemptConnectionType;
   LOG(INFO) << "Uploading " << static_cast<int>(connection_type)
             << " for metric " << metric;
-  metrics_lib_.SendEnumToUMA(
+  metrics_lib_->SendEnumToUMA(
       metric,
       static_cast<int>(connection_type),
       static_cast<int>(metrics::ConnectionType::kNumConstants));
@@ -350,14 +357,14 @@
     base::TimeDelta total_duration,
     int reboot_count,
     int url_switch_count) {
-  string metric = kMetricSuccessfulUpdatePayloadSizeMiB;
+  string metric = metrics::kMetricSuccessfulUpdatePayloadSizeMiB;
   int64_t mbs = payload_size / kNumBytesInOneMiB;
   LOG(INFO) << "Uploading " << mbs << " (MiBs) for metric " << metric;
-  metrics_lib_.SendToUMA(metric,
-                         mbs,
-                         0,     // min: 0 MiB
-                         1024,  // max: 1024 MiB = 1 GiB
-                         50);   // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          mbs,
+                          0,     // min: 0 MiB
+                          1024,  // max: 1024 MiB = 1 GiB
+                          50);   // num_buckets
 
   int64_t total_bytes = 0;
   int download_sources_used = 0;
@@ -370,7 +377,7 @@
     // update. Otherwise we're going to end up with a lot of zero-byte
     // events in the histogram.
 
-    metric = kMetricSuccessfulUpdateBytesDownloadedMiB;
+    metric = metrics::kMetricSuccessfulUpdateBytesDownloadedMiB;
     if (i < kNumDownloadSources) {
       metric += utils::ToString(source);
       mbs = num_bytes_downloaded[i] / kNumBytesInOneMiB;
@@ -383,88 +390,88 @@
 
     if (mbs > 0) {
       LOG(INFO) << "Uploading " << mbs << " (MiBs) for metric " << metric;
-      metrics_lib_.SendToUMA(metric,
-                             mbs,
-                             0,     // min: 0 MiB
-                             1024,  // max: 1024 MiB = 1 GiB
-                             50);   // num_buckets
+      metrics_lib_->SendToUMA(metric,
+                              mbs,
+                              0,     // min: 0 MiB
+                              1024,  // max: 1024 MiB = 1 GiB
+                              50);   // num_buckets
     }
   }
 
-  metric = kMetricSuccessfulUpdateDownloadSourcesUsed;
+  metric = metrics::kMetricSuccessfulUpdateDownloadSourcesUsed;
   LOG(INFO) << "Uploading 0x" << std::hex << download_sources_used
             << " (bit flags) for metric " << metric;
-  metrics_lib_.SendToUMA(metric,
-                         download_sources_used,
-                         0,                               // min
-                         (1 << kNumDownloadSources) - 1,  // max
-                         1 << kNumDownloadSources);       // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          download_sources_used,
+                          0,                               // min
+                          (1 << kNumDownloadSources) - 1,  // max
+                          1 << kNumDownloadSources);       // num_buckets
 
-  metric = kMetricSuccessfulUpdateDownloadOverheadPercentage;
+  metric = metrics::kMetricSuccessfulUpdateDownloadOverheadPercentage;
   LOG(INFO) << "Uploading " << download_overhead_percentage << "% for metric "
             << metric;
-  metrics_lib_.SendToUMA(metric,
-                         download_overhead_percentage,
-                         0,     // min: 0% overhead
-                         1000,  // max: 1000% overhead
-                         50);   // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          download_overhead_percentage,
+                          0,     // min: 0% overhead
+                          1000,  // max: 1000% overhead
+                          50);   // num_buckets
 
-  metric = kMetricSuccessfulUpdateUrlSwitchCount;
+  metric = metrics::kMetricSuccessfulUpdateUrlSwitchCount;
   LOG(INFO) << "Uploading " << url_switch_count << " (count) for metric "
             << metric;
-  metrics_lib_.SendToUMA(metric,
-                         url_switch_count,
-                         0,    // min: 0 URL switches
-                         49,   // max: 49 URL switches
-                         50);  // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          url_switch_count,
+                          0,    // min: 0 URL switches
+                          49,   // max: 49 URL switches
+                          50);  // num_buckets
 
-  metric = kMetricSuccessfulUpdateTotalDurationMinutes;
+  metric = metrics::kMetricSuccessfulUpdateTotalDurationMinutes;
   LOG(INFO) << "Uploading " << utils::FormatTimeDelta(total_duration)
             << " for metric " << metric;
-  metrics_lib_.SendToUMA(metric,
-                         static_cast<int>(total_duration.InMinutes()),
-                         0,              // min: 0 min
-                         365 * 24 * 60,  // max: 365 days ~= 1 year
-                         50);            // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          static_cast<int>(total_duration.InMinutes()),
+                          0,              // min: 0 min
+                          365 * 24 * 60,  // max: 365 days ~= 1 year
+                          50);            // num_buckets
 
-  metric = kMetricSuccessfulUpdateRebootCount;
+  metric = metrics::kMetricSuccessfulUpdateRebootCount;
   LOG(INFO) << "Uploading reboot count of " << reboot_count << " for metric "
             << metric;
-  metrics_lib_.SendToUMA(metric,
-                         reboot_count,
-                         0,    // min: 0 reboots
-                         49,   // max: 49 reboots
-                         50);  // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          reboot_count,
+                          0,    // min: 0 reboots
+                          49,   // max: 49 reboots
+                          50);  // num_buckets
 
-  metric = kMetricSuccessfulUpdatePayloadType;
-  metrics_lib_.SendEnumToUMA(metric, payload_type, kNumPayloadTypes);
+  metric = metrics::kMetricSuccessfulUpdatePayloadType;
+  metrics_lib_->SendEnumToUMA(metric, payload_type, kNumPayloadTypes);
   LOG(INFO) << "Uploading " << utils::ToString(payload_type) << " for metric "
             << metric;
 
-  metric = kMetricSuccessfulUpdateAttemptCount;
-  metrics_lib_.SendToUMA(metric,
-                         attempt_count,
-                         1,    // min: 1 attempt
-                         50,   // max: 50 attempts
-                         50);  // num_buckets
+  metric = metrics::kMetricSuccessfulUpdateAttemptCount;
+  metrics_lib_->SendToUMA(metric,
+                          attempt_count,
+                          1,    // min: 1 attempt
+                          50,   // max: 50 attempts
+                          50);  // num_buckets
   LOG(INFO) << "Uploading " << attempt_count << " for metric " << metric;
 
-  metric = kMetricSuccessfulUpdateUpdatesAbandonedCount;
+  metric = metrics::kMetricSuccessfulUpdateUpdatesAbandonedCount;
   LOG(INFO) << "Uploading " << updates_abandoned_count << " (count) for metric "
             << metric;
-  metrics_lib_.SendToUMA(metric,
-                         updates_abandoned_count,
-                         0,    // min: 0 counts
-                         49,   // max: 49 counts
-                         50);  // num_buckets
+  metrics_lib_->SendToUMA(metric,
+                          updates_abandoned_count,
+                          0,    // min: 0 counts
+                          49,   // max: 49 counts
+                          50);  // num_buckets
 }
 
 void MetricsReporterOmaha::ReportRollbackMetrics(
     metrics::RollbackResult result) {
-  string metric = kMetricRollbackResult;
+  string metric = metrics::kMetricRollbackResult;
   int value = static_cast<int>(result);
   LOG(INFO) << "Sending " << value << " for metric " << metric << " (enum)";
-  metrics_lib_.SendEnumToUMA(
+  metrics_lib_->SendEnumToUMA(
       metric, value, static_cast<int>(metrics::RollbackResult::kNumConstants));
 }
 
@@ -473,41 +480,41 @@
   string metric;
   switch (server_to_check) {
     case ServerToCheck::kUpdate:
-      metric = kMetricCertificateCheckUpdateCheck;
+      metric = metrics::kMetricCertificateCheckUpdateCheck;
       break;
     case ServerToCheck::kDownload:
-      metric = kMetricCertificateCheckDownload;
+      metric = metrics::kMetricCertificateCheckDownload;
       break;
     case ServerToCheck::kNone:
       return;
   }
   LOG(INFO) << "Uploading " << static_cast<int>(result) << " for metric "
             << metric;
-  metrics_lib_.SendEnumToUMA(
+  metrics_lib_->SendEnumToUMA(
       metric,
       static_cast<int>(result),
       static_cast<int>(CertificateCheckResult::kNumConstants));
 }
 
 void MetricsReporterOmaha::ReportFailedUpdateCount(int target_attempt) {
-  string metric = kMetricFailedUpdateCount;
-  metrics_lib_.SendToUMA(metric,
-                         target_attempt,
-                         1,   // min value
-                         50,  // max value
-                         kNumDefaultUmaBuckets);
+  string metric = metrics::kMetricFailedUpdateCount;
+  metrics_lib_->SendToUMA(metric,
+                          target_attempt,
+                          1,   // min value
+                          50,  // max value
+                          kNumDefaultUmaBuckets);
 
   LOG(INFO) << "Uploading " << target_attempt << " (count) for metric "
             << metric;
 }
 
 void MetricsReporterOmaha::ReportTimeToReboot(int time_to_reboot_minutes) {
-  string metric = kMetricTimeToRebootMinutes;
-  metrics_lib_.SendToUMA(metric,
-                         time_to_reboot_minutes,
-                         0,             // min: 0 minute
-                         30 * 24 * 60,  // max: 1 month (approx)
-                         kNumDefaultUmaBuckets);
+  string metric = metrics::kMetricTimeToRebootMinutes;
+  metrics_lib_->SendToUMA(metric,
+                          time_to_reboot_minutes,
+                          0,             // min: 0 minute
+                          30 * 24 * 60,  // max: 1 month (approx)
+                          kNumDefaultUmaBuckets);
 
   LOG(INFO) << "Uploading " << time_to_reboot_minutes << " for metric "
             << metric;
@@ -515,9 +522,9 @@
 
 void MetricsReporterOmaha::ReportInstallDateProvisioningSource(int source,
                                                                int max) {
-  metrics_lib_.SendEnumToUMA(kMetricInstallDateProvisioningSource,
-                             source,  // Sample.
-                             max);
+  metrics_lib_->SendEnumToUMA(metrics::kMetricInstallDateProvisioningSource,
+                              source,  // Sample.
+                              max);
 }
 
 }  // namespace chromeos_update_engine
diff --git a/metrics_reporter_omaha.h b/metrics_reporter_omaha.h
index e974a26..b209b13 100644
--- a/metrics_reporter_omaha.h
+++ b/metrics_reporter_omaha.h
@@ -17,6 +17,8 @@
 #ifndef UPDATE_ENGINE_METRICS_REPORTER_OMAHA_H_
 #define UPDATE_ENGINE_METRICS_REPORTER_OMAHA_H_
 
+#include <memory>
+
 #include <base/time/time.h>
 #include <metrics/metrics_library.h>
 
@@ -31,9 +33,63 @@
 
 class SystemState;
 
+namespace metrics {
+
+// UpdateEngine.Daily.* metrics.
+extern const char kMetricDailyOSAgeDays[];
+
+// UpdateEngine.Check.* metrics.
+extern const char kMetricCheckDownloadErrorCode[];
+extern const char kMetricCheckReaction[];
+extern const char kMetricCheckResult[];
+extern const char kMetricCheckTimeSinceLastCheckMinutes[];
+extern const char kMetricCheckTimeSinceLastCheckUptimeMinutes[];
+
+// UpdateEngine.Attempt.* metrics.
+extern const char kMetricAttemptNumber[];
+extern const char kMetricAttemptPayloadType[];
+extern const char kMetricAttemptPayloadSizeMiB[];
+extern const char kMetricAttemptConnectionType[];
+extern const char kMetricAttemptDurationMinutes[];
+extern const char kMetricAttemptDurationUptimeMinutes[];
+extern const char kMetricAttemptTimeSinceLastAttemptMinutes[];
+extern const char kMetricAttemptTimeSinceLastAttemptUptimeMinutes[];
+extern const char kMetricAttemptPayloadBytesDownloadedMiB[];
+extern const char kMetricAttemptPayloadDownloadSpeedKBps[];
+extern const char kMetricAttemptDownloadSource[];
+extern const char kMetricAttemptResult[];
+extern const char kMetricAttemptInternalErrorCode[];
+extern const char kMetricAttemptDownloadErrorCode[];
+
+// UpdateEngine.SuccessfulUpdate.* metrics.
+extern const char kMetricSuccessfulUpdateAttemptCount[];
+extern const char kMetricSuccessfulUpdateBytesDownloadedMiB[];
+extern const char kMetricSuccessfulUpdateDownloadOverheadPercentage[];
+extern const char kMetricSuccessfulUpdateDownloadSourcesUsed[];
+extern const char kMetricSuccessfulUpdatePayloadType[];
+extern const char kMetricSuccessfulUpdatePayloadSizeMiB[];
+extern const char kMetricSuccessfulUpdateRebootCount[];
+extern const char kMetricSuccessfulUpdateTotalDurationMinutes[];
+extern const char kMetricSuccessfulUpdateUpdatesAbandonedCount[];
+extern const char kMetricSuccessfulUpdateUrlSwitchCount[];
+
+// UpdateEngine.Rollback.* metric.
+extern const char kMetricRollbackResult[];
+
+// UpdateEngine.CertificateCheck.* metrics.
+extern const char kMetricCertificateCheckUpdateCheck[];
+extern const char kMetricCertificateCheckDownload[];
+
+// UpdateEngine.* metrics.
+extern const char kMetricFailedUpdateCount[];
+extern const char kMetricInstallDateProvisioningSource[];
+extern const char kMetricTimeToRebootMinutes[];
+
+}  // namespace metrics
+
 class MetricsReporterOmaha : public MetricsReporterInterface {
  public:
-  MetricsReporterOmaha() = default;
+  MetricsReporterOmaha();
 
   ~MetricsReporterOmaha() override = default;
 
@@ -87,7 +143,9 @@
   void ReportInstallDateProvisioningSource(int source, int max) override;
 
  private:
-  MetricsLibrary metrics_lib_;
+  friend class MetricsReporterOmahaTest;
+
+  std::unique_ptr<MetricsLibraryInterface> metrics_lib_;
 
   DISALLOW_COPY_AND_ASSIGN(MetricsReporterOmaha);
 };  // class metrics
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
diff --git a/update_engine.gyp b/update_engine.gyp
index 32c6553..ba4cfff 100644
--- a/update_engine.gyp
+++ b/update_engine.gyp
@@ -523,6 +523,7 @@
             'fake_system_state.cc',
             'hardware_chromeos_unittest.cc',
             'image_properties_chromeos_unittest.cc',
+            'metrics_reporter_omaha_unittest.cc',
             'metrics_utils_unittest.cc',
             'omaha_request_action_unittest.cc',
             'omaha_request_params_unittest.cc',