Home | History | Annotate | Download | only in update_engine
      1 //
      2 // Copyright (C) 2012 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include "update_engine/payload_state.h"
     18 
     19 #include <base/files/file_path.h>
     20 #include <base/files/file_util.h>
     21 #include <base/strings/stringprintf.h>
     22 #include <gmock/gmock.h>
     23 #include <gtest/gtest.h>
     24 
     25 #include "update_engine/common/constants.h"
     26 #include "update_engine/common/fake_clock.h"
     27 #include "update_engine/common/fake_hardware.h"
     28 #include "update_engine/common/fake_prefs.h"
     29 #include "update_engine/common/mock_prefs.h"
     30 #include "update_engine/common/prefs.h"
     31 #include "update_engine/common/test_utils.h"
     32 #include "update_engine/common/utils.h"
     33 #include "update_engine/fake_system_state.h"
     34 #include "update_engine/omaha_request_action.h"
     35 
     36 using base::Time;
     37 using base::TimeDelta;
     38 using std::string;
     39 using testing::AnyNumber;
     40 using testing::AtLeast;
     41 using testing::Mock;
     42 using testing::NiceMock;
     43 using testing::Return;
     44 using testing::SetArgumentPointee;
     45 using testing::_;
     46 
     47 namespace chromeos_update_engine {
     48 
     49 const char* kCurrentBytesDownloadedFromHttps =
     50   "current-bytes-downloaded-from-HttpsServer";
     51 const char* kTotalBytesDownloadedFromHttps =
     52   "total-bytes-downloaded-from-HttpsServer";
     53 const char* kCurrentBytesDownloadedFromHttp =
     54   "current-bytes-downloaded-from-HttpServer";
     55 const char* kTotalBytesDownloadedFromHttp =
     56   "total-bytes-downloaded-from-HttpServer";
     57 const char* kCurrentBytesDownloadedFromHttpPeer =
     58   "current-bytes-downloaded-from-HttpPeer";
     59 const char* kTotalBytesDownloadedFromHttpPeer =
     60   "total-bytes-downloaded-from-HttpPeer";
     61 
     62 static void SetupPayloadStateWith2Urls(string hash,
     63                                        bool http_enabled,
     64                                        bool is_delta_payload,
     65                                        PayloadState* payload_state,
     66                                        OmahaResponse* response) {
     67   response->packages.clear();
     68   response->packages.push_back({.payload_urls = {"http://test", "https://test"},
     69                                 .size = 523456789,
     70                                 .metadata_size = 558123,
     71                                 .metadata_signature = "metasign",
     72                                 .hash = hash,
     73                                 .is_delta = is_delta_payload});
     74   response->max_failure_count_per_url = 3;
     75   payload_state->SetResponse(*response);
     76   string stored_response_sign = payload_state->GetResponseSignature();
     77 
     78   string expected_url_https_only =
     79       "  NumURLs = 1\n"
     80       "  Candidate Url0 = https://test\n";
     81 
     82   string expected_urls_both =
     83       "  NumURLs = 2\n"
     84       "  Candidate Url0 = http://test\n"
     85       "  Candidate Url1 = https://test\n";
     86 
     87   string expected_response_sign = base::StringPrintf(
     88       "Payload 0:\n"
     89       "  Size = 523456789\n"
     90       "  Sha256 Hash = %s\n"
     91       "  Metadata Size = 558123\n"
     92       "  Metadata Signature = metasign\n"
     93       "  Is Delta = %d\n"
     94       "%s"
     95       "Max Failure Count Per Url = %d\n"
     96       "Disable Payload Backoff = %d\n",
     97       hash.c_str(),
     98       response->packages[0].is_delta,
     99       (http_enabled ? expected_urls_both : expected_url_https_only).c_str(),
    100       response->max_failure_count_per_url,
    101       response->disable_payload_backoff);
    102   EXPECT_EQ(expected_response_sign, stored_response_sign);
    103 }
    104 
    105 class PayloadStateTest : public ::testing::Test { };
    106 
    107 TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
    108   OmahaResponse response;
    109   FakeSystemState fake_system_state;
    110   NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
    111   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
    112   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
    113     .Times(AtLeast(1));
    114   EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
    115     .Times(AtLeast(1));
    116   EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
    117   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
    118   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
    119     .Times(AtLeast(1));
    120   EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
    121     .Times(AtLeast(1));
    122   EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
    123     .Times(AtLeast(1));
    124   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
    125     .Times(AtLeast(1));
    126   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
    127     .Times(AtLeast(1));
    128   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
    129     .Times(AtLeast(1));
    130   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
    131   PayloadState payload_state;
    132   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    133   payload_state.SetResponse(response);
    134   string stored_response_sign = payload_state.GetResponseSignature();
    135   string expected_response_sign =
    136       "Max Failure Count Per Url = 0\n"
    137       "Disable Payload Backoff = 0\n";
    138   EXPECT_EQ(expected_response_sign, stored_response_sign);
    139   EXPECT_EQ("", payload_state.GetCurrentUrl());
    140   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
    141   EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
    142   EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
    143 }
    144 
    145 TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
    146   OmahaResponse response;
    147   response.packages.push_back({.payload_urls = {"https://single.url.test"},
    148                                .size = 123456789,
    149                                .metadata_size = 58123,
    150                                .metadata_signature = "msign",
    151                                .hash = "hash"});
    152   FakeSystemState fake_system_state;
    153   NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
    154   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
    155   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
    156     .Times(AtLeast(1));
    157   EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
    158     .Times(AtLeast(1));
    159   EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
    160     .Times(AtLeast(1));
    161   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
    162     .Times(AtLeast(1));
    163   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
    164     .Times(AtLeast(1));
    165   EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
    166     .Times(AtLeast(1));
    167   EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
    168     .Times(AtLeast(1));
    169   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
    170     .Times(AtLeast(1));
    171   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
    172     .Times(AtLeast(1));
    173   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
    174     .Times(AtLeast(1));
    175   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
    176       .Times(AtLeast(1));
    177   PayloadState payload_state;
    178   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    179   payload_state.SetResponse(response);
    180   string stored_response_sign = payload_state.GetResponseSignature();
    181   string expected_response_sign =
    182       "Payload 0:\n"
    183       "  Size = 123456789\n"
    184       "  Sha256 Hash = hash\n"
    185       "  Metadata Size = 58123\n"
    186       "  Metadata Signature = msign\n"
    187       "  Is Delta = 0\n"
    188       "  NumURLs = 1\n"
    189       "  Candidate Url0 = https://single.url.test\n"
    190       "Max Failure Count Per Url = 0\n"
    191       "Disable Payload Backoff = 0\n";
    192   EXPECT_EQ(expected_response_sign, stored_response_sign);
    193   EXPECT_EQ("https://single.url.test", payload_state.GetCurrentUrl());
    194   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
    195   EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
    196   EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
    197 }
    198 
    199 TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
    200   OmahaResponse response;
    201   response.packages.push_back({.payload_urls = {"http://multiple.url.test",
    202                                                 "https://multiple.url.test"},
    203                                .size = 523456789,
    204                                .metadata_size = 558123,
    205                                .metadata_signature = "metasign",
    206                                .hash = "rhash"});
    207   FakeSystemState fake_system_state;
    208   NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
    209   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
    210   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
    211     .Times(AtLeast(1));
    212   EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
    213     .Times(AtLeast(1));
    214   EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
    215     .Times(AtLeast(1));
    216   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
    217     .Times(AtLeast(1));
    218   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
    219     .Times(AtLeast(1));
    220   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
    221     .Times(AtLeast(1));
    222   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
    223     .Times(AtLeast(1));
    224   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
    225     .Times(AtLeast(1));
    226   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
    227       .Times(AtLeast(1));
    228 
    229   PayloadState payload_state;
    230   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    231   payload_state.SetResponse(response);
    232   string stored_response_sign = payload_state.GetResponseSignature();
    233   string expected_response_sign =
    234       "Payload 0:\n"
    235       "  Size = 523456789\n"
    236       "  Sha256 Hash = rhash\n"
    237       "  Metadata Size = 558123\n"
    238       "  Metadata Signature = metasign\n"
    239       "  Is Delta = 0\n"
    240       "  NumURLs = 2\n"
    241       "  Candidate Url0 = http://multiple.url.test\n"
    242       "  Candidate Url1 = https://multiple.url.test\n"
    243       "Max Failure Count Per Url = 0\n"
    244       "Disable Payload Backoff = 0\n";
    245   EXPECT_EQ(expected_response_sign, stored_response_sign);
    246   EXPECT_EQ("http://multiple.url.test", payload_state.GetCurrentUrl());
    247   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
    248   EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
    249   EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
    250 }
    251 
    252 TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
    253   OmahaResponse response;
    254   FakeSystemState fake_system_state;
    255   NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
    256   PayloadState payload_state;
    257 
    258   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
    259   // Payload attempt should start with 0 and then advance to 1.
    260   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
    261     .Times(AtLeast(1));
    262   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
    263     .Times(AtLeast(1));
    264   EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
    265     .Times(AtLeast(1));
    266   EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
    267     .Times(AtLeast(1));
    268   EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
    269 
    270   // Reboots will be set
    271   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1));
    272 
    273   // Url index should go from 0 to 1 twice.
    274   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
    275   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
    276 
    277   // Failure count should be called each times url index is set, so that's
    278   // 4 times for this test.
    279   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
    280     .Times(AtLeast(4));
    281 
    282   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    283 
    284   // This does a SetResponse which causes all the states to be set to 0 for
    285   // the first time.
    286   SetupPayloadStateWith2Urls(
    287       "Hash1235", true, false, &payload_state, &response);
    288   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    289 
    290   // Verify that on the first error, the URL index advances to 1.
    291   ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
    292   payload_state.UpdateFailed(error);
    293   EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
    294 
    295   // Verify that on the next error, the URL index wraps around to 0.
    296   payload_state.UpdateFailed(error);
    297   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    298 
    299   // Verify that on the next error, it again advances to 1.
    300   payload_state.UpdateFailed(error);
    301   EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
    302 
    303   // Verify that we switched URLs three times
    304   EXPECT_EQ(3U, payload_state.GetUrlSwitchCount());
    305 }
    306 
    307 TEST(PayloadStateTest, NewResponseResetsPayloadState) {
    308   OmahaResponse response;
    309   FakeSystemState fake_system_state;
    310   PayloadState payload_state;
    311 
    312   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    313 
    314   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
    315     .Times(AnyNumber());
    316   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
    317     .Times(AnyNumber());
    318 
    319   // Set the first response.
    320   SetupPayloadStateWith2Urls(
    321       "Hash5823", true, false, &payload_state, &response);
    322   EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
    323 
    324   // Advance the URL index to 1 by faking an error.
    325   ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
    326   payload_state.UpdateFailed(error);
    327   EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
    328   EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
    329 
    330   // Now, slightly change the response and set it again.
    331   SetupPayloadStateWith2Urls(
    332       "Hash8225", true, false, &payload_state, &response);
    333   EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
    334 
    335   // Fake an error again.
    336   payload_state.UpdateFailed(error);
    337   EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
    338   EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
    339 
    340   // Return a third different response.
    341   SetupPayloadStateWith2Urls(
    342       "Hash9999", true, false, &payload_state, &response);
    343   EXPECT_EQ(3, payload_state.GetNumResponsesSeen());
    344 
    345   // Make sure the url index was reset to 0 because of the new response.
    346   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    347   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
    348   EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
    349   EXPECT_EQ(0U,
    350             payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
    351   EXPECT_EQ(0U,
    352             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
    353   EXPECT_EQ(
    354       0U, payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
    355   EXPECT_EQ(0U,
    356             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
    357 }
    358 
    359 TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
    360   OmahaResponse response;
    361   PayloadState payload_state;
    362   FakeSystemState fake_system_state;
    363   int progress_bytes = 100;
    364   NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
    365 
    366   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
    367   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
    368     .Times(AtLeast(2));
    369   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
    370     .Times(AtLeast(1));
    371   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
    372     .Times(AtLeast(1));
    373 
    374   EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
    375     .Times(AtLeast(2));
    376   EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
    377     .Times(AtLeast(1));
    378   EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 2))
    379     .Times(AtLeast(1));
    380 
    381   EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
    382 
    383   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
    384   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
    385 
    386   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
    387     .Times(AtLeast(7));
    388   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
    389     .Times(AtLeast(2));
    390   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
    391     .Times(AtLeast(1));
    392 
    393   EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
    394     .Times(AtLeast(1));
    395   EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
    396     .Times(AtLeast(1));
    397 
    398   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
    399     .Times(AtLeast(1));
    400   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
    401     .Times(AtLeast(1));
    402   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
    403     .Times(AtLeast(1));
    404   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
    405     .Times(AtLeast(1));
    406   EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
    407     .Times(AtLeast(1));
    408   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
    409       .Times(AtLeast(1));
    410 
    411   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    412 
    413   SetupPayloadStateWith2Urls(
    414       "Hash5873", true, false, &payload_state, &response);
    415   EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
    416 
    417   // This should advance the URL index.
    418   payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
    419   EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
    420   EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
    421   EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
    422   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
    423   EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
    424 
    425   // This should advance the failure count only.
    426   payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
    427   EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
    428   EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
    429   EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
    430   EXPECT_EQ(1U, payload_state.GetUrlFailureCount());
    431   EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
    432 
    433   // This should advance the failure count only.
    434   payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
    435   EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
    436   EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
    437   EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
    438   EXPECT_EQ(2U, payload_state.GetUrlFailureCount());
    439   EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
    440 
    441   // This should advance the URL index as we've reached the
    442   // max failure count and reset the failure count for the new URL index.
    443   // This should also wrap around the URL index and thus cause the payload
    444   // attempt number to be incremented.
    445   payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
    446   EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
    447   EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
    448   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    449   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
    450   EXPECT_EQ(2U, payload_state.GetUrlSwitchCount());
    451   EXPECT_TRUE(payload_state.ShouldBackoffDownload());
    452 
    453   // This should advance the URL index.
    454   payload_state.UpdateFailed(ErrorCode::kPayloadHashMismatchError);
    455   EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
    456   EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
    457   EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
    458   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
    459   EXPECT_EQ(3U, payload_state.GetUrlSwitchCount());
    460   EXPECT_TRUE(payload_state.ShouldBackoffDownload());
    461 
    462   // This should advance the URL index and payload attempt number due to
    463   // wrap-around of URL index.
    464   payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMissingError);
    465   EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
    466   EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
    467   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    468   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
    469   EXPECT_EQ(4U, payload_state.GetUrlSwitchCount());
    470   EXPECT_TRUE(payload_state.ShouldBackoffDownload());
    471 
    472   // This HTTP error code should only increase the failure count.
    473   payload_state.UpdateFailed(static_cast<ErrorCode>(
    474       static_cast<int>(ErrorCode::kOmahaRequestHTTPResponseBase) + 404));
    475   EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
    476   EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
    477   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    478   EXPECT_EQ(1U, payload_state.GetUrlFailureCount());
    479   EXPECT_EQ(4U, payload_state.GetUrlSwitchCount());
    480   EXPECT_TRUE(payload_state.ShouldBackoffDownload());
    481 
    482   // And that failure count should be reset when we download some bytes
    483   // afterwards.
    484   payload_state.DownloadProgress(progress_bytes);
    485   EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
    486   EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
    487   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    488   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
    489   EXPECT_EQ(4U, payload_state.GetUrlSwitchCount());
    490   EXPECT_TRUE(payload_state.ShouldBackoffDownload());
    491 
    492   // Now, slightly change the response and set it again.
    493   SetupPayloadStateWith2Urls(
    494       "Hash8532", true, false, &payload_state, &response);
    495   EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
    496 
    497   // Make sure the url index was reset to 0 because of the new response.
    498   EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
    499   EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
    500   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    501   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
    502   EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
    503   EXPECT_FALSE(payload_state.ShouldBackoffDownload());
    504 }
    505 
    506 TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulFullDownload) {
    507   OmahaResponse response;
    508   PayloadState payload_state;
    509   FakeSystemState fake_system_state;
    510   NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
    511 
    512   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
    513   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
    514     .Times(AtLeast(1));
    515   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
    516     .Times(AtLeast(1));
    517 
    518   EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
    519     .Times(AtLeast(1));
    520   EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
    521     .Times(AtLeast(1));
    522 
    523   EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
    524     .Times(AtLeast(2));
    525 
    526   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
    527     .Times(AtLeast(1));
    528   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
    529     .Times(AtLeast(1));
    530 
    531   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    532 
    533   SetupPayloadStateWith2Urls(
    534       "Hash8593", true, false, &payload_state, &response);
    535 
    536   // This should just advance the payload attempt number;
    537   EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
    538   EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
    539   payload_state.DownloadComplete();
    540   EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
    541   EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
    542   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    543   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
    544   EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
    545 }
    546 
    547 TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDeltaDownload) {
    548   OmahaResponse response;
    549   PayloadState payload_state;
    550   FakeSystemState fake_system_state;
    551   NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
    552 
    553   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
    554   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
    555     .Times(AtLeast(1));
    556   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
    557     .Times(AtLeast(1));
    558 
    559   // kPrefsFullPayloadAttemptNumber is not incremented for delta payloads.
    560   EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
    561     .Times(AtLeast(1));
    562 
    563   EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
    564     .Times(1);
    565 
    566   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
    567     .Times(AtLeast(1));
    568   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
    569     .Times(AtLeast(1));
    570 
    571   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    572 
    573   SetupPayloadStateWith2Urls("Hash8593", true, true, &payload_state, &response);
    574 
    575   // This should just advance the payload attempt number;
    576   EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
    577   EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
    578   payload_state.DownloadComplete();
    579   EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
    580   EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
    581   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    582   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
    583   EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
    584 }
    585 
    586 TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
    587   OmahaResponse response;
    588   PayloadState payload_state;
    589   FakeSystemState fake_system_state;
    590 
    591   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    592   SetupPayloadStateWith2Urls(
    593       "Hash4427", true, false, &payload_state, &response);
    594 
    595   // Generate enough events to advance URL index, failure count and
    596   // payload attempt number all to 1.
    597   payload_state.DownloadComplete();
    598   payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
    599   payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
    600   EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
    601   EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
    602   EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
    603   EXPECT_EQ(1U, payload_state.GetUrlFailureCount());
    604   EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
    605 
    606   // Now, simulate a corrupted url index on persisted store which gets
    607   // loaded when update_engine restarts. Using a different prefs object
    608   // so as to not bother accounting for the uninteresting calls above.
    609   FakeSystemState fake_system_state2;
    610   NiceMock<MockPrefs>* prefs2 = fake_system_state2.mock_prefs();
    611   EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
    612   EXPECT_CALL(*prefs2, GetInt64(_, _)).Times(AtLeast(1));
    613   EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
    614     .Times(AtLeast(1));
    615   EXPECT_CALL(*prefs2, GetInt64(kPrefsFullPayloadAttemptNumber, _))
    616     .Times(AtLeast(1));
    617   EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
    618       .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
    619   EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
    620     .Times(AtLeast(1));
    621   EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _))
    622     .Times(AtLeast(1));
    623 
    624   // Note: This will be a different payload object, but the response should
    625   // have the same hash as before so as to not trivially reset because the
    626   // response was different. We want to specifically test that even if the
    627   // response is same, we should reset the state if we find it corrupted.
    628   EXPECT_TRUE(payload_state.Initialize(&fake_system_state2));
    629   SetupPayloadStateWith2Urls(
    630       "Hash4427", true, false, &payload_state, &response);
    631 
    632   // Make sure all counters get reset to 0 because of the corrupted URL index
    633   // we supplied above.
    634   EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
    635   EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
    636   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    637   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
    638   EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
    639 }
    640 
    641 TEST(PayloadStateTest, NoBackoffInteractiveChecks) {
    642   OmahaResponse response;
    643   PayloadState payload_state;
    644   FakeSystemState fake_system_state;
    645   OmahaRequestParams params(&fake_system_state);
    646   params.Init("", "", true);  // is_interactive = True.
    647   fake_system_state.set_request_params(&params);
    648 
    649   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    650   SetupPayloadStateWith2Urls(
    651       "Hash6437", true, false, &payload_state, &response);
    652 
    653   // Simulate two failures (enough to cause payload backoff) and check
    654   // again that we're ready to re-download without any backoff as this is
    655   // an interactive check.
    656   payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
    657   payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
    658   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    659   EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
    660   EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
    661   EXPECT_FALSE(payload_state.ShouldBackoffDownload());
    662 }
    663 
    664 TEST(PayloadStateTest, NoBackoffForP2PUpdates) {
    665   OmahaResponse response;
    666   PayloadState payload_state;
    667   FakeSystemState fake_system_state;
    668   OmahaRequestParams params(&fake_system_state);
    669   params.Init("", "", false);  // is_interactive = False.
    670   fake_system_state.set_request_params(&params);
    671 
    672   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    673   SetupPayloadStateWith2Urls(
    674       "Hash6437", true, false, &payload_state, &response);
    675 
    676   // Simulate two failures (enough to cause payload backoff) and check
    677   // again that we're ready to re-download without any backoff as this is
    678   // an interactive check.
    679   payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
    680   payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
    681   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    682   EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
    683   EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
    684   // Set p2p url.
    685   payload_state.SetUsingP2PForDownloading(true);
    686   payload_state.SetP2PUrl("http://mypeer:52909/path/to/file");
    687   // Should not backoff for p2p updates.
    688   EXPECT_FALSE(payload_state.ShouldBackoffDownload());
    689 
    690   payload_state.SetP2PUrl("");
    691   // No actual p2p update if no url is provided.
    692   EXPECT_TRUE(payload_state.ShouldBackoffDownload());
    693 }
    694 
    695 TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
    696   OmahaResponse response;
    697   PayloadState payload_state;
    698   FakeSystemState fake_system_state;
    699 
    700   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    701   SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response);
    702 
    703   // Simulate a successful download and see that we're ready to download
    704   // again without any backoff as this is a delta payload.
    705   payload_state.DownloadComplete();
    706   EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
    707   EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
    708   EXPECT_FALSE(payload_state.ShouldBackoffDownload());
    709 
    710   // Simulate two failures (enough to cause payload backoff) and check
    711   // again that we're ready to re-download without any backoff as this is
    712   // a delta payload.
    713   payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
    714   payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
    715   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
    716   EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
    717   EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
    718   EXPECT_FALSE(payload_state.ShouldBackoffDownload());
    719 }
    720 
    721 static void CheckPayloadBackoffState(PayloadState* payload_state,
    722                                      int expected_attempt_number,
    723                                      TimeDelta expected_days) {
    724   payload_state->DownloadComplete();
    725   EXPECT_EQ(expected_attempt_number,
    726       payload_state->GetFullPayloadAttemptNumber());
    727   EXPECT_TRUE(payload_state->ShouldBackoffDownload());
    728   Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
    729   // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
    730   TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
    731   Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
    732   Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
    733   EXPECT_LT(expected_min_time.ToInternalValue(),
    734             backoff_expiry_time.ToInternalValue());
    735   EXPECT_GT(expected_max_time.ToInternalValue(),
    736             backoff_expiry_time.ToInternalValue());
    737 }
    738 
    739 TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
    740   OmahaResponse response;
    741   PayloadState payload_state;
    742   FakeSystemState fake_system_state;
    743 
    744   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    745   SetupPayloadStateWith2Urls(
    746       "Hash8939", true, false, &payload_state, &response);
    747 
    748   CheckPayloadBackoffState(&payload_state, 1,  TimeDelta::FromDays(1));
    749   CheckPayloadBackoffState(&payload_state, 2,  TimeDelta::FromDays(2));
    750   CheckPayloadBackoffState(&payload_state, 3,  TimeDelta::FromDays(4));
    751   CheckPayloadBackoffState(&payload_state, 4,  TimeDelta::FromDays(8));
    752   CheckPayloadBackoffState(&payload_state, 5,  TimeDelta::FromDays(16));
    753   CheckPayloadBackoffState(&payload_state, 6,  TimeDelta::FromDays(16));
    754   CheckPayloadBackoffState(&payload_state, 7,  TimeDelta::FromDays(16));
    755   CheckPayloadBackoffState(&payload_state, 8,  TimeDelta::FromDays(16));
    756   CheckPayloadBackoffState(&payload_state, 9,  TimeDelta::FromDays(16));
    757   CheckPayloadBackoffState(&payload_state, 10,  TimeDelta::FromDays(16));
    758 }
    759 
    760 TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
    761   OmahaResponse response;
    762   response.disable_payload_backoff = true;
    763   PayloadState payload_state;
    764   FakeSystemState fake_system_state;
    765 
    766   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    767   SetupPayloadStateWith2Urls(
    768       "Hash8939", true, false, &payload_state, &response);
    769 
    770   // Simulate a successful download and see that we are ready to download
    771   // again without any backoff.
    772   payload_state.DownloadComplete();
    773   EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
    774   EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
    775   EXPECT_FALSE(payload_state.ShouldBackoffDownload());
    776 
    777   // Test again, this time by simulating two errors that would cause
    778   // the payload attempt number to increment due to wrap around. And
    779   // check that we are still ready to re-download without any backoff.
    780   payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
    781   payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
    782   EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
    783   EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
    784   EXPECT_FALSE(payload_state.ShouldBackoffDownload());
    785 }
    786 
    787 TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
    788   OmahaResponse response;
    789   response.disable_payload_backoff = true;
    790   PayloadState payload_state;
    791   FakeSystemState fake_system_state;
    792   uint64_t https_total = 0;
    793   uint64_t http_total = 0;
    794 
    795   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    796   SetupPayloadStateWith2Urls(
    797       "Hash3286", true, false, &payload_state, &response);
    798   EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
    799 
    800   // Simulate a previous attempt with in order to set an initial non-zero value
    801   // for the total bytes downloaded for HTTP.
    802   uint64_t prev_chunk = 323456789;
    803   http_total += prev_chunk;
    804   payload_state.DownloadProgress(prev_chunk);
    805 
    806   // Ensure that the initial values for HTTP reflect this attempt.
    807   EXPECT_EQ(prev_chunk,
    808             payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
    809   EXPECT_EQ(http_total,
    810             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
    811 
    812   // Change the response hash so as to simulate a new response which will
    813   // reset the current bytes downloaded, but not the total bytes downloaded.
    814   SetupPayloadStateWith2Urls(
    815       "Hash9904", true, false, &payload_state, &response);
    816   EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
    817 
    818   // First, simulate successful download of a few bytes over HTTP.
    819   uint64_t first_chunk = 5000000;
    820   http_total += first_chunk;
    821   payload_state.DownloadProgress(first_chunk);
    822   // Test that first all progress is made on HTTP and none on HTTPS.
    823   EXPECT_EQ(first_chunk,
    824             payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
    825   EXPECT_EQ(http_total,
    826             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
    827   EXPECT_EQ(0U, payload_state.GetCurrentBytesDownloaded(
    828                  kDownloadSourceHttpsServer));
    829   EXPECT_EQ(https_total,
    830             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
    831 
    832   // Simulate an error that'll cause the url index to point to https.
    833   ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
    834   payload_state.UpdateFailed(error);
    835 
    836   // Test that no new progress is made on HTTP and new progress is on HTTPS.
    837   uint64_t second_chunk = 23456789;
    838   https_total += second_chunk;
    839   payload_state.DownloadProgress(second_chunk);
    840   EXPECT_EQ(first_chunk,
    841             payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
    842   EXPECT_EQ(http_total,
    843             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
    844   EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
    845               kDownloadSourceHttpsServer));
    846   EXPECT_EQ(https_total,
    847             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
    848 
    849   // Simulate error to go back to http.
    850   payload_state.UpdateFailed(error);
    851   uint64_t third_chunk = 32345678;
    852   uint64_t http_chunk = first_chunk + third_chunk;
    853   http_total += third_chunk;
    854   payload_state.DownloadProgress(third_chunk);
    855 
    856   // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
    857   EXPECT_EQ(http_chunk,
    858             payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
    859   EXPECT_EQ(http_total,
    860             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
    861   EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
    862                  kDownloadSourceHttpsServer));
    863   EXPECT_EQ(https_total,
    864             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
    865 
    866   // Simulate error (will cause URL switch), set p2p is to be used and
    867   // then do 42MB worth of progress
    868   payload_state.UpdateFailed(error);
    869   payload_state.SetUsingP2PForDownloading(true);
    870   uint64_t p2p_total = 42 * 1000 * 1000;
    871   payload_state.DownloadProgress(p2p_total);
    872 
    873   EXPECT_EQ(p2p_total,
    874             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpPeer));
    875 
    876   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
    877     .Times(AnyNumber());
    878   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
    879     .Times(AnyNumber());
    880   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
    881       metrics::kMetricSuccessfulUpdateUrlSwitchCount,
    882       3, _, _, _));
    883   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
    884       metrics::kMetricSuccessfulUpdateTotalDurationMinutes,
    885       _, _, _, _));
    886   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
    887       metrics::kMetricSuccessfulUpdateDownloadOverheadPercentage,
    888       314, _, _, _));
    889   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
    890       metrics::kMetricAttemptPayloadType, kPayloadTypeFull, kNumPayloadTypes));
    891   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
    892       metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeFull,
    893       kNumPayloadTypes));
    894   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
    895       metrics::kMetricSuccessfulUpdateAttemptCount, 1, _, _, _));
    896 
    897   payload_state.UpdateSucceeded();
    898 
    899   // Make sure the metrics are reset after a successful update.
    900   EXPECT_EQ(0U,
    901             payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
    902   EXPECT_EQ(0U,
    903             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
    904   EXPECT_EQ(0U, payload_state.GetCurrentBytesDownloaded(
    905                  kDownloadSourceHttpsServer));
    906   EXPECT_EQ(0U,
    907             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
    908   EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
    909 }
    910 
    911 TEST(PayloadStateTest, DownloadSourcesUsedIsCorrect) {
    912   OmahaResponse response;
    913   PayloadState payload_state;
    914   FakeSystemState fake_system_state;
    915 
    916   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    917   SetupPayloadStateWith2Urls(
    918       "Hash3286", true, false, &payload_state, &response);
    919 
    920   // Simulate progress in order to mark HTTP as one of the sources used.
    921   uint64_t num_bytes = 42 * 1000 * 1000;
    922   payload_state.DownloadProgress(num_bytes);
    923 
    924   // Check that this was done via HTTP.
    925   EXPECT_EQ(num_bytes,
    926             payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
    927   EXPECT_EQ(num_bytes,
    928             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
    929 
    930   // Check that only HTTP is reported as a download source.
    931   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
    932     .Times(AnyNumber());
    933   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
    934       metrics::kMetricSuccessfulUpdateDownloadSourcesUsed,
    935       (1 << kDownloadSourceHttpServer),
    936       _, _, _));
    937 
    938   payload_state.UpdateSucceeded();
    939 }
    940 
    941 TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
    942   OmahaResponse response;
    943   FakeSystemState fake_system_state;
    944   PayloadState payload_state;
    945 
    946   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    947 
    948   // Set the first response.
    949   SetupPayloadStateWith2Urls(
    950       "Hash5823", true, false, &payload_state, &response);
    951 
    952   uint64_t num_bytes = 10000;
    953   payload_state.DownloadProgress(num_bytes);
    954   EXPECT_EQ(num_bytes,
    955             payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
    956   EXPECT_EQ(num_bytes,
    957             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
    958   EXPECT_EQ(0U, payload_state.GetCurrentBytesDownloaded(
    959                  kDownloadSourceHttpsServer));
    960   EXPECT_EQ(0U,
    961             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
    962 
    963   payload_state.UpdateRestarted();
    964   // Make sure the current bytes downloaded is reset, but not the total bytes.
    965   EXPECT_EQ(0U,
    966             payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
    967   EXPECT_EQ(num_bytes,
    968             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
    969 }
    970 
    971 TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
    972   FakeSystemState fake_system_state;
    973   PayloadState payload_state;
    974 
    975   NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
    976   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AtLeast(0));
    977   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
    978 
    979   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
    980 
    981   payload_state.UpdateRestarted();
    982   EXPECT_EQ(0U, payload_state.GetNumReboots());
    983 
    984   fake_system_state.set_system_rebooted(true);
    985   payload_state.UpdateResumed();
    986   // Num reboots should be incremented because system rebooted detected.
    987   EXPECT_EQ(1U, payload_state.GetNumReboots());
    988 
    989   fake_system_state.set_system_rebooted(false);
    990   payload_state.UpdateResumed();
    991   // Num reboots should now be 1 as reboot was not detected.
    992   EXPECT_EQ(1U, payload_state.GetNumReboots());
    993 
    994   // Restart the update again to verify we set the num of reboots back to 0.
    995   payload_state.UpdateRestarted();
    996   EXPECT_EQ(0U, payload_state.GetNumReboots());
    997 }
    998 
    999 TEST(PayloadStateTest, RollbackVersion) {
   1000   FakeSystemState fake_system_state;
   1001   PayloadState payload_state;
   1002 
   1003   NiceMock<MockPrefs>* mock_powerwash_safe_prefs =
   1004       fake_system_state.mock_powerwash_safe_prefs();
   1005   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1006 
   1007   // Verify pre-conditions are good.
   1008   EXPECT_TRUE(payload_state.GetRollbackVersion().empty());
   1009 
   1010   // Mock out the os version and make sure it's blacklisted correctly.
   1011   string rollback_version = "2345.0.0";
   1012   OmahaRequestParams params(&fake_system_state);
   1013   params.Init(rollback_version, "", false);
   1014   fake_system_state.set_request_params(&params);
   1015 
   1016   EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion,
   1017                                                     rollback_version));
   1018   payload_state.Rollback();
   1019 
   1020   EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
   1021 
   1022   // Change it up a little and verify we load it correctly.
   1023   rollback_version = "2345.0.1";
   1024   // Let's verify we can reload it correctly.
   1025   EXPECT_CALL(*mock_powerwash_safe_prefs, GetString(
   1026       kPrefsRollbackVersion, _)).WillOnce(DoAll(
   1027           SetArgumentPointee<1>(rollback_version), Return(true)));
   1028   EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion,
   1029                                                     rollback_version));
   1030   payload_state.LoadRollbackVersion();
   1031   EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
   1032 
   1033   // Check that we report only UpdateEngine.Rollback.* metrics in
   1034   // UpdateSucceeded().
   1035   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
   1036     .Times(0);
   1037   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
   1038     .Times(0);
   1039   EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
   1040               SendEnumToUMA(
   1041                   metrics::kMetricRollbackResult,
   1042                   static_cast<int>(metrics::RollbackResult::kSuccess),
   1043                   static_cast<int>(metrics::RollbackResult::kNumConstants)));
   1044   payload_state.UpdateSucceeded();
   1045 }
   1046 
   1047 TEST(PayloadStateTest, DurationsAreCorrect) {
   1048   OmahaResponse response;
   1049   response.packages.resize(1);
   1050   PayloadState payload_state;
   1051   FakeSystemState fake_system_state;
   1052   FakeClock fake_clock;
   1053   FakePrefs fake_prefs;
   1054 
   1055   // Set the clock to a well-known time - 1 second on the wall-clock
   1056   // and 2 seconds on the monotonic clock
   1057   fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
   1058   fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
   1059 
   1060   fake_system_state.set_clock(&fake_clock);
   1061   fake_system_state.set_prefs(&fake_prefs);
   1062   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1063 
   1064   // Check that durations are correct for a successful update where
   1065   // time has advanced 7 seconds on the wall clock and 4 seconds on
   1066   // the monotonic clock.
   1067   SetupPayloadStateWith2Urls(
   1068       "Hash8593", true, false, &payload_state, &response);
   1069   fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
   1070   fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
   1071   payload_state.UpdateSucceeded();
   1072   EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
   1073   EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
   1074 
   1075   // Check that durations are reset when a new response comes in.
   1076   SetupPayloadStateWith2Urls(
   1077       "Hash8594", true, false, &payload_state, &response);
   1078   EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
   1079   EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
   1080 
   1081   // Advance time a bit (10 secs), simulate download progress and
   1082   // check that durations are updated.
   1083   fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
   1084   fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
   1085   payload_state.DownloadProgress(10);
   1086   EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
   1087   EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
   1088 
   1089   // Now simulate a reboot by resetting monotonic time (to 5000) and
   1090   // creating a new PayloadState object and check that we load the
   1091   // durations correctly (e.g. they are the same as before).
   1092   fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
   1093   PayloadState payload_state2;
   1094   EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
   1095   payload_state2.SetResponse(response);
   1096   EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
   1097   EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),
   1098             10000000);
   1099 
   1100   // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
   1101   // and check that the durations are increased accordingly.
   1102   fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
   1103   fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
   1104   payload_state2.UpdateSucceeded();
   1105   EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
   1106   EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),
   1107             16000000);
   1108 }
   1109 
   1110 TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
   1111   OmahaResponse response;
   1112   PayloadState payload_state;
   1113   FakeSystemState fake_system_state;
   1114   FakeClock fake_clock;
   1115   FakePrefs fake_prefs;
   1116 
   1117   // Set the clock to a well-known time (t = 30 seconds).
   1118   fake_clock.SetWallclockTime(Time::FromInternalValue(
   1119       30 * Time::kMicrosecondsPerSecond));
   1120 
   1121   fake_system_state.set_clock(&fake_clock);
   1122   fake_system_state.set_prefs(&fake_prefs);
   1123   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1124 
   1125   // Make the update succeed.
   1126   SetupPayloadStateWith2Urls(
   1127       "Hash8593", true, false, &payload_state, &response);
   1128   payload_state.UpdateSucceeded();
   1129 
   1130   // Check that the marker was written.
   1131   EXPECT_TRUE(fake_prefs.Exists(kPrefsSystemUpdatedMarker));
   1132 
   1133   // Now simulate a reboot and set the wallclock time to a later point
   1134   // (t = 500 seconds). We do this by using a new PayloadState object
   1135   // and checking that it emits the right UMA metric with the right
   1136   // value.
   1137   fake_clock.SetWallclockTime(Time::FromInternalValue(
   1138       500 * Time::kMicrosecondsPerSecond));
   1139   PayloadState payload_state2;
   1140   EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
   1141 
   1142   // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
   1143   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
   1144       metrics::kMetricTimeToRebootMinutes,
   1145       7, _, _, _));
   1146   fake_system_state.set_system_rebooted(true);
   1147 
   1148   payload_state2.UpdateEngineStarted();
   1149 
   1150   // Check that the marker was nuked.
   1151   EXPECT_FALSE(fake_prefs.Exists(kPrefsSystemUpdatedMarker));
   1152 }
   1153 
   1154 TEST(PayloadStateTest, RestartAfterCrash) {
   1155   PayloadState payload_state;
   1156   FakeSystemState fake_system_state;
   1157   NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
   1158 
   1159   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1160 
   1161   // Only the |kPrefsAttemptInProgress| state variable should be read.
   1162   EXPECT_CALL(*prefs, Exists(_)).Times(0);
   1163   EXPECT_CALL(*prefs, SetString(_, _)).Times(0);
   1164   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(0);
   1165   EXPECT_CALL(*prefs, SetBoolean(_, _)).Times(0);
   1166   EXPECT_CALL(*prefs, GetString(_, _)).Times(0);
   1167   EXPECT_CALL(*prefs, GetInt64(_, _)).Times(0);
   1168   EXPECT_CALL(*prefs, GetBoolean(_, _)).Times(0);
   1169   EXPECT_CALL(*prefs, GetBoolean(kPrefsAttemptInProgress, _));
   1170 
   1171   // No metrics are reported after a crash.
   1172   EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
   1173               SendToUMA(_, _, _, _, _)).Times(0);
   1174 
   1175   // Simulate an update_engine restart without a reboot.
   1176   fake_system_state.set_system_rebooted(false);
   1177 
   1178   payload_state.UpdateEngineStarted();
   1179 }
   1180 
   1181 TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsNoReporting) {
   1182   PayloadState payload_state;
   1183   FakeSystemState fake_system_state;
   1184 
   1185   // If there's no marker at startup, ensure we don't report a metric.
   1186   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1187   EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
   1188       SendEnumToUMA(
   1189           metrics::kMetricAttemptResult,
   1190           static_cast<int>(metrics::AttemptResult::kAbnormalTermination),
   1191           _)).Times(0);
   1192   payload_state.UpdateEngineStarted();
   1193 }
   1194 
   1195 TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsReported) {
   1196   PayloadState payload_state;
   1197   FakeSystemState fake_system_state;
   1198   FakePrefs fake_prefs;
   1199 
   1200   // If we have a marker at startup, ensure it's reported and the
   1201   // marker is then cleared.
   1202   fake_system_state.set_prefs(&fake_prefs);
   1203   fake_prefs.SetBoolean(kPrefsAttemptInProgress, true);
   1204 
   1205   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1206 
   1207   EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
   1208       SendEnumToUMA(
   1209           metrics::kMetricAttemptResult,
   1210           static_cast<int>(metrics::AttemptResult::kAbnormalTermination),
   1211           _)).Times(1);
   1212   payload_state.UpdateEngineStarted();
   1213 
   1214   EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
   1215 }
   1216 
   1217 TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsClearedOnSucceess) {
   1218   PayloadState payload_state;
   1219   FakeSystemState fake_system_state;
   1220   FakePrefs fake_prefs;
   1221 
   1222   // Make sure the marker is written and cleared during an attempt and
   1223   // also that we DO NOT emit the metric (since the attempt didn't end
   1224   // abnormally).
   1225   fake_system_state.set_prefs(&fake_prefs);
   1226   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1227   OmahaResponse response;
   1228   response.packages.resize(1);
   1229   payload_state.SetResponse(response);
   1230 
   1231   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
   1232     .Times(AnyNumber());
   1233   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
   1234     .Times(AnyNumber());
   1235   EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
   1236       SendEnumToUMA(
   1237           metrics::kMetricAttemptResult,
   1238           static_cast<int>(metrics::AttemptResult::kAbnormalTermination),
   1239           _)).Times(0);
   1240 
   1241   // Attempt not in progress, should be clear.
   1242   EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
   1243 
   1244   payload_state.UpdateRestarted();
   1245 
   1246   // Attempt not in progress, should be set.
   1247   EXPECT_TRUE(fake_prefs.Exists(kPrefsAttemptInProgress));
   1248 
   1249   payload_state.UpdateSucceeded();
   1250 
   1251   // Attempt not in progress, should be clear.
   1252   EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
   1253 }
   1254 
   1255 TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
   1256   OmahaResponse response;
   1257   FakeSystemState fake_system_state;
   1258   PayloadState payload_state;
   1259 
   1260   policy::MockDevicePolicy disable_http_policy;
   1261   fake_system_state.set_device_policy(&disable_http_policy);
   1262   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1263 
   1264   // Test with no device policy. Should default to allowing http.
   1265   EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
   1266       .WillRepeatedly(Return(false));
   1267 
   1268   // Set the first response.
   1269   SetupPayloadStateWith2Urls(
   1270       "Hash8433", true, false, &payload_state, &response);
   1271 
   1272   // Check that we use the HTTP URL since there is no value set for allowing
   1273   // http.
   1274   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
   1275 
   1276   // Test with device policy not allowing http updates.
   1277   EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
   1278       .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
   1279 
   1280   // Reset state and set again.
   1281   SetupPayloadStateWith2Urls(
   1282       "Hash8433", false, false, &payload_state, &response);
   1283 
   1284   // Check that we skip the HTTP URL and use only the HTTPS url.
   1285   EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
   1286 
   1287   // Advance the URL index to 1 by faking an error.
   1288   ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
   1289   payload_state.UpdateFailed(error);
   1290 
   1291   // Check that we still skip the HTTP URL and use only the HTTPS url.
   1292   EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
   1293   EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
   1294 
   1295   // Now, slightly change the response and set it again.
   1296   SetupPayloadStateWith2Urls(
   1297       "Hash2399", false, false, &payload_state, &response);
   1298 
   1299   // Check that we still skip the HTTP URL and use only the HTTPS url.
   1300   EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
   1301 
   1302   // Now, pretend that the HTTP policy is turned on. We want to make sure
   1303   // the new policy is honored.
   1304   policy::MockDevicePolicy enable_http_policy;
   1305   fake_system_state.set_device_policy(&enable_http_policy);
   1306   EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
   1307       .WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
   1308 
   1309   // Now, set the same response using the same hash
   1310   // so that we can test that the state is reset not because of the
   1311   // hash but because of the policy change which results in candidate url
   1312   // list change.
   1313   SetupPayloadStateWith2Urls(
   1314       "Hash2399", true, false, &payload_state, &response);
   1315 
   1316   // Check that we use the HTTP URL now and the failure count is reset.
   1317   EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
   1318   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
   1319 
   1320   // Fake a failure and see if we're moving over to the HTTPS url and update
   1321   // the URL switch count properly.
   1322   payload_state.UpdateFailed(error);
   1323   EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
   1324   EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
   1325   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
   1326 }
   1327 
   1328 TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
   1329   OmahaResponse response;
   1330   PayloadState payload_state;
   1331   FakeSystemState fake_system_state;
   1332 
   1333   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1334   SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response);
   1335 
   1336   // Simulate a successful download and update.
   1337   payload_state.DownloadComplete();
   1338 
   1339   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
   1340     .Times(AnyNumber());
   1341   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
   1342       metrics::kMetricAttemptPayloadType, kPayloadTypeDelta, kNumPayloadTypes));
   1343   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
   1344       metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeDelta,
   1345       kNumPayloadTypes));
   1346   payload_state.UpdateSucceeded();
   1347 
   1348   // Mock the request to a request where the delta was disabled but Omaha sends
   1349   // a delta anyway and test again.
   1350   OmahaRequestParams params(&fake_system_state);
   1351   params.set_delta_okay(false);
   1352   fake_system_state.set_request_params(&params);
   1353 
   1354   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1355   SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response);
   1356 
   1357   payload_state.DownloadComplete();
   1358 
   1359   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
   1360       metrics::kMetricAttemptPayloadType, kPayloadTypeDelta,
   1361       kNumPayloadTypes));
   1362   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
   1363       metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeDelta,
   1364       kNumPayloadTypes));
   1365   payload_state.UpdateSucceeded();
   1366 }
   1367 
   1368 TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
   1369   OmahaResponse response;
   1370   PayloadState payload_state;
   1371   FakeSystemState fake_system_state;
   1372 
   1373   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1374   SetupPayloadStateWith2Urls(
   1375       "Hash6437", true, false, &payload_state, &response);
   1376 
   1377   // Mock the request to a request where the delta was disabled.
   1378   OmahaRequestParams params(&fake_system_state);
   1379   params.set_delta_okay(false);
   1380   fake_system_state.set_request_params(&params);
   1381 
   1382   // Simulate a successful download and update.
   1383   payload_state.DownloadComplete();
   1384 
   1385   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
   1386     .Times(AnyNumber());
   1387   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
   1388       metrics::kMetricAttemptPayloadType, kPayloadTypeForcedFull,
   1389       kNumPayloadTypes));
   1390   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
   1391       metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeForcedFull,
   1392       kNumPayloadTypes));
   1393   payload_state.UpdateSucceeded();
   1394 }
   1395 
   1396 TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
   1397   OmahaResponse response;
   1398   PayloadState payload_state;
   1399   FakeSystemState fake_system_state;
   1400 
   1401   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1402   SetupPayloadStateWith2Urls(
   1403       "Hash6437", true, false, &payload_state, &response);
   1404 
   1405   // Mock the request to a request where the delta is enabled, although the
   1406   // result is full.
   1407   OmahaRequestParams params(&fake_system_state);
   1408   params.set_delta_okay(true);
   1409   fake_system_state.set_request_params(&params);
   1410 
   1411   // Simulate a successful download and update.
   1412   payload_state.DownloadComplete();
   1413 
   1414   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
   1415     .Times(AnyNumber());
   1416   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
   1417       metrics::kMetricAttemptPayloadType, kPayloadTypeFull,
   1418       kNumPayloadTypes));
   1419   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
   1420       metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeFull,
   1421       kNumPayloadTypes));
   1422   payload_state.UpdateSucceeded();
   1423 }
   1424 
   1425 TEST(PayloadStateTest, RebootAfterUpdateFailedMetric) {
   1426   FakeSystemState fake_system_state;
   1427   OmahaResponse response;
   1428   PayloadState payload_state;
   1429   FakePrefs fake_prefs;
   1430   fake_system_state.set_prefs(&fake_prefs);
   1431 
   1432   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1433   SetupPayloadStateWith2Urls(
   1434       "Hash3141", true, false, &payload_state, &response);
   1435 
   1436   // Simulate a successful download and update.
   1437   payload_state.DownloadComplete();
   1438   payload_state.UpdateSucceeded();
   1439   payload_state.ExpectRebootInNewVersion("Version:12345678");
   1440 
   1441   // Reboot into the same environment to get an UMA metric with a value of 1.
   1442   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
   1443       metrics::kMetricFailedUpdateCount, 1, _, _, _));
   1444   payload_state.ReportFailedBootIfNeeded();
   1445   Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_lib());
   1446 
   1447   // Simulate a second update and reboot into the same environment, this should
   1448   // send a value of 2.
   1449   payload_state.ExpectRebootInNewVersion("Version:12345678");
   1450 
   1451   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
   1452       metrics::kMetricFailedUpdateCount, 2, _, _, _));
   1453   payload_state.ReportFailedBootIfNeeded();
   1454   Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_lib());
   1455 
   1456   // Simulate a third failed reboot to new version, but this time for a
   1457   // different payload. This should send a value of 1 this time.
   1458   payload_state.ExpectRebootInNewVersion("Version:3141592");
   1459   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
   1460       metrics::kMetricFailedUpdateCount, 1, _, _, _));
   1461   payload_state.ReportFailedBootIfNeeded();
   1462   Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_lib());
   1463 }
   1464 
   1465 TEST(PayloadStateTest, RebootAfterUpdateSucceed) {
   1466   FakeSystemState fake_system_state;
   1467   OmahaResponse response;
   1468   PayloadState payload_state;
   1469   FakePrefs fake_prefs;
   1470   fake_system_state.set_prefs(&fake_prefs);
   1471 
   1472   FakeBootControl* fake_boot_control = fake_system_state.fake_boot_control();
   1473   fake_boot_control->SetCurrentSlot(0);
   1474 
   1475   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1476   SetupPayloadStateWith2Urls(
   1477       "Hash3141", true, false, &payload_state, &response);
   1478 
   1479   // Simulate a successful download and update.
   1480   payload_state.DownloadComplete();
   1481   payload_state.UpdateSucceeded();
   1482   payload_state.ExpectRebootInNewVersion("Version:12345678");
   1483 
   1484   // Change the BootDevice to a different one, no metric should be sent.
   1485   fake_boot_control->SetCurrentSlot(1);
   1486 
   1487   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
   1488       metrics::kMetricFailedUpdateCount, _, _, _, _))
   1489       .Times(0);
   1490   payload_state.ReportFailedBootIfNeeded();
   1491 
   1492   // A second reboot in either partition should not send a metric.
   1493   payload_state.ReportFailedBootIfNeeded();
   1494   fake_boot_control->SetCurrentSlot(0);
   1495   payload_state.ReportFailedBootIfNeeded();
   1496 }
   1497 
   1498 TEST(PayloadStateTest, RebootAfterCanceledUpdate) {
   1499   FakeSystemState fake_system_state;
   1500   OmahaResponse response;
   1501   PayloadState payload_state;
   1502   FakePrefs fake_prefs;
   1503 
   1504   fake_system_state.set_prefs(&fake_prefs);
   1505   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1506   SetupPayloadStateWith2Urls(
   1507       "Hash3141", true, false, &payload_state, &response);
   1508 
   1509   // Simulate a successful download and update.
   1510   payload_state.DownloadComplete();
   1511   payload_state.UpdateSucceeded();
   1512   payload_state.ExpectRebootInNewVersion("Version:12345678");
   1513 
   1514   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
   1515       metrics::kMetricFailedUpdateCount, _, _, _, _))
   1516       .Times(0);
   1517 
   1518   // Cancel the applied update.
   1519   payload_state.ResetUpdateStatus();
   1520 
   1521   // Simulate a reboot.
   1522   payload_state.ReportFailedBootIfNeeded();
   1523 }
   1524 
   1525 TEST(PayloadStateTest, UpdateSuccessWithWipedPrefs) {
   1526   FakeSystemState fake_system_state;
   1527   PayloadState payload_state;
   1528   FakePrefs fake_prefs;
   1529 
   1530   fake_system_state.set_prefs(&fake_prefs);
   1531   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1532 
   1533   EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
   1534       metrics::kMetricFailedUpdateCount, _, _, _, _))
   1535       .Times(0);
   1536 
   1537   // Simulate a reboot in this environment.
   1538   payload_state.ReportFailedBootIfNeeded();
   1539 }
   1540 
   1541 TEST(PayloadStateTest, DisallowP2PAfterTooManyAttempts) {
   1542   OmahaResponse response;
   1543   PayloadState payload_state;
   1544   FakeSystemState fake_system_state;
   1545   FakePrefs fake_prefs;
   1546   fake_system_state.set_prefs(&fake_prefs);
   1547 
   1548   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1549   SetupPayloadStateWith2Urls(
   1550       "Hash8593", true, false, &payload_state, &response);
   1551 
   1552   // Should allow exactly kMaxP2PAttempts...
   1553   for (int n = 0; n < kMaxP2PAttempts; n++) {
   1554     payload_state.P2PNewAttempt();
   1555     EXPECT_TRUE(payload_state.P2PAttemptAllowed());
   1556   }
   1557   // ... but not more than that.
   1558   payload_state.P2PNewAttempt();
   1559   EXPECT_FALSE(payload_state.P2PAttemptAllowed());
   1560 }
   1561 
   1562 TEST(PayloadStateTest, DisallowP2PAfterDeadline) {
   1563   OmahaResponse response;
   1564   PayloadState payload_state;
   1565   FakeSystemState fake_system_state;
   1566   FakeClock fake_clock;
   1567   FakePrefs fake_prefs;
   1568 
   1569   fake_system_state.set_clock(&fake_clock);
   1570   fake_system_state.set_prefs(&fake_prefs);
   1571   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1572   SetupPayloadStateWith2Urls(
   1573       "Hash8593", true, false, &payload_state, &response);
   1574 
   1575   // Set the clock to 1 second.
   1576   Time epoch = Time::FromInternalValue(1000000);
   1577   fake_clock.SetWallclockTime(epoch);
   1578 
   1579   // Do an attempt - this will set the timestamp.
   1580   payload_state.P2PNewAttempt();
   1581 
   1582   // Check that the timestamp equals what we just set.
   1583   EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
   1584 
   1585   // Time hasn't advanced - this should work.
   1586   EXPECT_TRUE(payload_state.P2PAttemptAllowed());
   1587 
   1588   // Set clock to half the deadline - this should work.
   1589   fake_clock.SetWallclockTime(epoch +
   1590       TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds) / 2);
   1591   EXPECT_TRUE(payload_state.P2PAttemptAllowed());
   1592 
   1593   // Check that the first attempt timestamp hasn't changed just
   1594   // because the wall-clock time changed.
   1595   EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
   1596 
   1597   // Set clock to _just_ before the deadline - this should work.
   1598   fake_clock.SetWallclockTime(epoch +
   1599       TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds - 1));
   1600   EXPECT_TRUE(payload_state.P2PAttemptAllowed());
   1601 
   1602   // Set clock to _just_ after the deadline - this should not work.
   1603   fake_clock.SetWallclockTime(epoch +
   1604       TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds + 1));
   1605   EXPECT_FALSE(payload_state.P2PAttemptAllowed());
   1606 }
   1607 
   1608 TEST(PayloadStateTest, P2PStateVarsInitialValue) {
   1609   OmahaResponse response;
   1610   PayloadState payload_state;
   1611   FakeSystemState fake_system_state;
   1612   FakePrefs fake_prefs;
   1613 
   1614   fake_system_state.set_prefs(&fake_prefs);
   1615   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1616   SetupPayloadStateWith2Urls(
   1617       "Hash8593", true, false, &payload_state, &response);
   1618 
   1619   Time null_time = Time();
   1620   EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
   1621   EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
   1622 }
   1623 
   1624 TEST(PayloadStateTest, P2PStateVarsArePersisted) {
   1625   OmahaResponse response;
   1626   PayloadState payload_state;
   1627   FakeSystemState fake_system_state;
   1628   FakeClock fake_clock;
   1629   FakePrefs fake_prefs;
   1630   fake_system_state.set_clock(&fake_clock);
   1631   fake_system_state.set_prefs(&fake_prefs);
   1632   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1633   SetupPayloadStateWith2Urls(
   1634       "Hash8593", true, false, &payload_state, &response);
   1635 
   1636   // Set the clock to something known.
   1637   Time time = Time::FromInternalValue(12345);
   1638   fake_clock.SetWallclockTime(time);
   1639 
   1640   // New p2p attempt - as a side-effect this will update the p2p state vars.
   1641   payload_state.P2PNewAttempt();
   1642   EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
   1643   EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
   1644 
   1645   // Now create a new PayloadState and check that it loads the state
   1646   // vars correctly.
   1647   PayloadState payload_state2;
   1648   EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
   1649   EXPECT_EQ(1, payload_state2.GetP2PNumAttempts());
   1650   EXPECT_EQ(time, payload_state2.GetP2PFirstAttemptTimestamp());
   1651 }
   1652 
   1653 TEST(PayloadStateTest, P2PStateVarsAreClearedOnNewResponse) {
   1654   OmahaResponse response;
   1655   PayloadState payload_state;
   1656   FakeSystemState fake_system_state;
   1657   FakeClock fake_clock;
   1658   FakePrefs fake_prefs;
   1659   fake_system_state.set_clock(&fake_clock);
   1660   fake_system_state.set_prefs(&fake_prefs);
   1661 
   1662   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
   1663   SetupPayloadStateWith2Urls(
   1664       "Hash8593", true, false, &payload_state, &response);
   1665 
   1666   // Set the clock to something known.
   1667   Time time = Time::FromInternalValue(12345);
   1668   fake_clock.SetWallclockTime(time);
   1669 
   1670   // New p2p attempt - as a side-effect this will update the p2p state vars.
   1671   payload_state.P2PNewAttempt();
   1672   EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
   1673   EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
   1674 
   1675   // Set a new response...
   1676   SetupPayloadStateWith2Urls(
   1677       "Hash9904", true, false, &payload_state, &response);
   1678 
   1679   // ... and check that it clears the P2P state vars.
   1680   Time null_time = Time();
   1681   EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
   1682   EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
   1683 }
   1684 
   1685 }  // namespace chromeos_update_engine
   1686