Add DownloadSourcesUsed and DownloadOverheadPercentage metrics.

DownloadSourcesUsed: This metric will tell us the various combinations of
the protocols and servers that were used in completing the download for
each successful update attempt.

DownloadOverheadPercentage: This metric will indicate how efficient our
download mechanisms are by calculating the overhead we incurred as a percentage
of the number of bytes that were actually needed to do the update
successfully.

BUG=chromium:225953
TEST=Unit Tests added, chrome://histograms shows new metrics correctly.

Change-Id: Ic1e9547a9a27e1aad53f7e30c70d822820d2c60f
Reviewed-on: https://gerrit.chromium.org/gerrit/48856
Commit-Queue: Jay Srinivasan <jaysri@chromium.org>
Reviewed-by: Jay Srinivasan <jaysri@chromium.org>
Tested-by: Jay Srinivasan <jaysri@chromium.org>
diff --git a/payload_state_unittest.cc b/payload_state_unittest.cc
index f7688c2..440d8b7 100644
--- a/payload_state_unittest.cc
+++ b/payload_state_unittest.cc
@@ -28,6 +28,7 @@
 using testing::Return;
 using testing::SetArgumentPointee;
 using testing::AtLeast;
+using testing::AnyNumber;
 
 namespace chromeos_update_engine {
 
@@ -88,7 +89,7 @@
   OmahaResponse response;
   MockSystemState mock_system_state;
   NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
-  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
+  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
     .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
@@ -131,7 +132,7 @@
   response.metadata_signature = "msign";
   MockSystemState mock_system_state;
   NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
-  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
+  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
     .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
@@ -179,7 +180,7 @@
   response.metadata_signature = "metasign";
   MockSystemState mock_system_state;
   NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
-  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
+  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
     .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
@@ -220,7 +221,7 @@
   NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
   PayloadState payload_state;
 
-  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
+  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
   // Payload attempt should start with 0 and then advance to 1.
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
     .Times(AtLeast(1));
@@ -304,7 +305,7 @@
   int progress_bytes = 100;
   NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
 
-  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
+  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
     .Times(AtLeast(2));
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
@@ -428,7 +429,7 @@
   MockSystemState mock_system_state;
   NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
 
-  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
+  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
     .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
@@ -602,8 +603,23 @@
   EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
   SetupPayloadStateWith2Urls("Hash3286", &payload_state, &response);
 
-  // Simulate a successful download and see that we are ready to download
-  // again without any backoff.
+  // Simulate a previous attempt with in order to set an initial non-zero value
+  // for the total bytes downloaded for HTTP.
+  int prev_chunk = 323456789;
+  http_total += prev_chunk;
+  payload_state.DownloadProgress(prev_chunk);
+
+  // Ensure that the initial values for HTTP reflect this attempt.
+  EXPECT_EQ(prev_chunk,
+            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
+  EXPECT_EQ(http_total,
+            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
+
+  // Change the response hash so as to simulate a new response which will
+  // reset the current bytes downloaded, but not the total bytes downloaded.
+  SetupPayloadStateWith2Urls("Hash9904", &payload_state, &response);
+
+  // First, simulate successful download of a few bytes over HTTP.
   int first_chunk = 5000000;
   http_total += first_chunk;
   payload_state.DownloadProgress(first_chunk);
@@ -645,16 +661,15 @@
   // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
   EXPECT_EQ(http_chunk,
             payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
-  EXPECT_EQ(http_chunk,
+  EXPECT_EQ(http_total,
             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
   EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
                  kDownloadSourceHttpsServer));
   EXPECT_EQ(https_total,
             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
 
-  // Don't care about other metrics in this test.
-  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
-      _,_,_,_,_)).Times(AtLeast(0));
+  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
+    .Times(AnyNumber());
   EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
       "Installer.SuccessfulMBsDownloadedFromHttpServer",
       http_chunk / kNumBytesInOneMiB, _, _, _));
@@ -676,6 +691,10 @@
   EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
       "Installer.UpdateDurationUptimeMinutes",
       _, _, _, _));
+  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
+      "Installer.DownloadSourcesUsed", 3, _, _, _));
+  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
+      "Installer.DownloadOverheadPercentage", 542, _, _, _));
 
   payload_state.UpdateSucceeded();