payload_state_unittest.cc revision dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22
16f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
26f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan// Use of this source code is governed by a BSD-style license that can be
36f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan// found in the LICENSE file.
46f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
56f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan#include <glib.h>
66f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
7be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa#include "base/file_path.h"
8be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa#include "base/file_util.h"
92b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan#include "base/stringprintf.h"
106f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan#include "gmock/gmock.h"
112b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan#include "gtest/gtest.h"
122b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
13d29695df35b7192faef4009d42a62c37bdd90a8fJay Srinivasan#include "update_engine/constants.h"
14f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen#include "update_engine/fake_clock.h"
1519409b74019d787100b768306e75ab3e5882898dJay Srinivasan#include "update_engine/mock_system_state.h"
166f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan#include "update_engine/omaha_request_action.h"
176f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan#include "update_engine/payload_state.h"
18f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen#include "update_engine/prefs.h"
196f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan#include "update_engine/prefs_mock.h"
206f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan#include "update_engine/test_utils.h"
216f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan#include "update_engine/utils.h"
226f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
23082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasanusing base::Time;
24082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasanusing base::TimeDelta;
256f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasanusing std::string;
266f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasanusing testing::_;
276f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasanusing testing::NiceMock;
282b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasanusing testing::Return;
296f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasanusing testing::SetArgumentPointee;
309a017f2c5ae41c04a7c7c15b5dbd08faadae7606David Zeuthenusing testing::AtLeast;
31dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasanusing testing::AnyNumber;
326f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
336f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasannamespace chromeos_update_engine {
346f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
3519409b74019d787100b768306e75ab3e5882898dJay Srinivasanconst char* kCurrentBytesDownloadedFromHttps =
3619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  "current-bytes-downloaded-from-HttpsServer";
3719409b74019d787100b768306e75ab3e5882898dJay Srinivasanconst char* kTotalBytesDownloadedFromHttps =
3819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  "total-bytes-downloaded-from-HttpsServer";
3919409b74019d787100b768306e75ab3e5882898dJay Srinivasanconst char* kCurrentBytesDownloadedFromHttp =
4019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  "current-bytes-downloaded-from-HttpServer";
4119409b74019d787100b768306e75ab3e5882898dJay Srinivasanconst char* kTotalBytesDownloadedFromHttp =
4219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  "total-bytes-downloaded-from-HttpServer";
4319409b74019d787100b768306e75ab3e5882898dJay Srinivasan
442b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasanstatic void SetupPayloadStateWith2Urls(string hash,
452b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan                                       PayloadState* payload_state,
462b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan                                       OmahaResponse* response) {
472b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->payload_urls.clear();
482b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->payload_urls.push_back("http://test");
492b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->payload_urls.push_back("https://test");
502b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->size = 523456789;
512b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->hash = hash;
522b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->metadata_size = 558123;
532b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->metadata_signature = "metasign";
542b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->max_failure_count_per_url = 3;
552b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state->SetResponse(*response);
56082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string stored_response_sign = payload_state->GetResponseSignature();
57082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string expected_response_sign = StringPrintf(
582b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      "NumURLs = 2\n"
592b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      "Url0 = http://test\n"
602b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      "Url1 = https://test\n"
612b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      "Payload Size = 523456789\n"
622b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      "Payload Sha256 Hash = %s\n"
632b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      "Metadata Size = 558123\n"
64082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      "Metadata Signature = metasign\n"
65082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      "Is Delta Payload = %d\n"
66082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      "Max Failure Count Per Url = %d\n"
67082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      "Disable Payload Backoff = %d\n",
68082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      hash.c_str(),
69082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      response->is_delta_payload,
70082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      response->max_failure_count_per_url,
71082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      response->disable_payload_backoff);
72082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_response_sign, stored_response_sign);
732b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
742b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
756f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasanclass PayloadStateTest : public ::testing::Test { };
766f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
77a99981fda75fe0b17e96c700e3ddc93eca1cebe5David ZeuthenTEST(PayloadStateTest, DidYouAddANewErrorCode) {
78a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  if (kErrorCodeUmaReportedMax != 43) {
792b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan    LOG(ERROR) << "The following failure is intentional. If you added a new "
80a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen               << "ErrorCode enum value, make sure to add it to the "
812b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan               << "PayloadState::UpdateFailed method and then update this test "
82a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen               << "to the new value of kErrorCodeUmaReportedMax, which is "
83a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen               << kErrorCodeUmaReportedMax;
842b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan    EXPECT_FALSE("Please see the log line above");
852b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  }
862b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
872b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
886f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
896f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
9019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
9119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
92dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
9319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
9419409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
9519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
9619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
9719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
9819409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
9919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
10019409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
10119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
10219409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
10319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
10419409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
10519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
10619409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
107be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
1086f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
10919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1106f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.SetResponse(response);
111082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string stored_response_sign = payload_state.GetResponseSignature();
112082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string expected_response_sign = "NumURLs = 0\n"
113082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Size = 0\n"
114082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Sha256 Hash = \n"
115082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Size = 0\n"
116082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Signature = \n"
117082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Is Delta Payload = 0\n"
118082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Max Failure Count Per Url = 0\n"
119082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Disable Payload Backoff = 0\n";
120082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_response_sign, stored_response_sign);
1216f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
1222b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
123cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
1246f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
1256f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
1266f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
1276f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
1286f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.payload_urls.push_back("http://single.url.test");
1296f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.size = 123456789;
1306f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.hash = "hash";
1316f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.metadata_size = 58123;
1326f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.metadata_signature = "msign";
13319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
13419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
135dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
13619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
13719409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
13819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
13919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
14019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
14119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
14219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
14319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
14419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
14519409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
14619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
14719409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
14819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
14919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
15019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
15119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
152be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
153be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa      .Times(AtLeast(1));
1546f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
15519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1566f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.SetResponse(response);
157082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string stored_response_sign = payload_state.GetResponseSignature();
158082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string expected_response_sign = "NumURLs = 1\n"
159082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Url0 = http://single.url.test\n"
160082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Size = 123456789\n"
161082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Sha256 Hash = hash\n"
162082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Size = 58123\n"
163082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Signature = msign\n"
164082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Is Delta Payload = 0\n"
165082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Max Failure Count Per Url = 0\n"
166082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Disable Payload Backoff = 0\n";
167082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_response_sign, stored_response_sign);
1686f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
1692b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
170cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
1716f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
1726f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
1736f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
1746f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
1756f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.payload_urls.push_back("http://multiple.url.test");
1766f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.payload_urls.push_back("https://multiple.url.test");
1776f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.size = 523456789;
1786f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.hash = "rhash";
1796f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.metadata_size = 558123;
1806f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.metadata_signature = "metasign";
18119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
18219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
183dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
18419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
18519409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
18619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
18719409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
18819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
18919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
19019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
19119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
19219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
19319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
19419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
19519409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
196be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
197be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa      .Times(AtLeast(1));
1986f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
19919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
2006f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.SetResponse(response);
201082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string stored_response_sign = payload_state.GetResponseSignature();
202082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string expected_response_sign = "NumURLs = 2\n"
203082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Url0 = http://multiple.url.test\n"
204082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Url1 = https://multiple.url.test\n"
205082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Size = 523456789\n"
206082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Sha256 Hash = rhash\n"
207082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Size = 558123\n"
208082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Signature = metasign\n"
209082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Is Delta Payload = 0\n"
210082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Max Failure Count Per Url = 0\n"
211082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Disable Payload Backoff = 0\n";
212082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_response_sign, stored_response_sign);
2136f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
2142b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
215cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
2166f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
2176f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2186f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
2196f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
22019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
22119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
2226f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
2232b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
224dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
2252b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Payload attempt should start with 0 and then advance to 1.
22619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
22719409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
22819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
22919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
23019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
2319a017f2c5ae41c04a7c7c15b5dbd08faadae7606David Zeuthen
232be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  // Reboots will be set
233be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1));
234be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
2352b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Url index should go from 0 to 1 twice.
23619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
23719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
2382b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
2392b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Failure count should be called each times url index is set, so that's
2402b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // 4 times for this test.
24119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
24219409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(4));
2432b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
24419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
2452b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
2462b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This does a SetResponse which causes all the states to be set to 0 for
2472b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // the first time.
2482b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash1235", &payload_state, &response);
2496f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
2506f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2516f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Verify that on the first error, the URL index advances to 1.
252a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
2536f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.UpdateFailed(error);
2546f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
2556f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2566f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Verify that on the next error, the URL index wraps around to 0.
2576f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.UpdateFailed(error);
2586f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
2596f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2606f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Verify that on the next error, it again advances to 1.
2616f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.UpdateFailed(error);
2626f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
263cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen
264cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  // Verify that we switched URLs three times
265cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
2666f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
2676f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2686f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, NewResponseResetsPayloadState) {
2696f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
27019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
2716f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
2722b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
27319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
2742b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
2752b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Set the first response.
2762b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash5823", &payload_state, &response);
2776f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2786f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Advance the URL index to 1 by faking an error.
279a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
2806f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.UpdateFailed(error);
2816f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
282cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
2836f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2846f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Now, slightly change the response and set it again.
2852b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash8225", &payload_state, &response);
2862b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
2872b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Make sure the url index was reset to 0 because of the new response.
2882b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
2892b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
290cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
29119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
29219409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
29319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
29419409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
29519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
29619409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
29719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
29819409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
2992b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
3002b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3012b5a0f065187fd19179e3809148dbfc376ada7a0Jay SrinivasanTEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
3022b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  OmahaResponse response;
3032b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  PayloadState payload_state;
30419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
30519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int progress_bytes = 100;
30619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
30719409b74019d787100b768306e75ab3e5882898dJay Srinivasan
308dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
30919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
31019409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(2));
31119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
31219409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
31319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
31419409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
31519409b74019d787100b768306e75ab3e5882898dJay Srinivasan
31619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
31719409b74019d787100b768306e75ab3e5882898dJay Srinivasan
31819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
31919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
32019409b74019d787100b768306e75ab3e5882898dJay Srinivasan
32119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
32219409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(7));
32319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
32419409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(2));
32519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
32619409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
32719409b74019d787100b768306e75ab3e5882898dJay Srinivasan
32819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
32919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
33019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
33119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
33219409b74019d787100b768306e75ab3e5882898dJay Srinivasan
33319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
33419409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
33519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
33619409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
33719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
33819409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
33919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
34019409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
341be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
342be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa      .Times(AtLeast(1));
34319409b74019d787100b768306e75ab3e5882898dJay Srinivasan
34419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
3452b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3462b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash5873", &payload_state, &response);
3472b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3482b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the URL index.
349a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
3502b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
3512b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
3522b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
353cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
3542b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3552b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the failure count only.
356a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
3572b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
3582b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
3592b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlFailureCount());
360cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
3612b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3622b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the failure count only.
363a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
3642b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
3652b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
3662b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetUrlFailureCount());
367cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
3682b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3692b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the URL index as we've reached the
3702b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // max failure count and reset the failure count for the new URL index.
3712b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should also wrap around the URL index and thus cause the payload
3722b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // attempt number to be incremented.
373a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
3742b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
3752b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
3762b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
377cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(2, payload_state.GetUrlSwitchCount());
378082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
3792b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3802b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the URL index.
381a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodePayloadHashMismatchError);
3822b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
3832b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
3842b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
385cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
386082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
3872b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3882b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the URL index and payload attempt number due to
3892b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // wrap-around of URL index.
390a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMissingError);
3912b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
3922b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
3932b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
394cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
395082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
3962b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3972b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This HTTP error code should only increase the failure count.
398a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(static_cast<ErrorCode>(
399a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen      kErrorCodeOmahaRequestHTTPResponseBase + 404));
4002b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
4012b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
4022b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlFailureCount());
403cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
404082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
4052b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4062b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // And that failure count should be reset when we download some bytes
4072b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // afterwards.
40819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(progress_bytes);
4092b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
4102b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
4112b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
412cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
413082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
4142b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4152b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Now, slightly change the response and set it again.
4162b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash8532", &payload_state, &response);
4176f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
4186f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Make sure the url index was reset to 0 because of the new response.
4192b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
4206f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
4212b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
422cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
423082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
4246f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
4256f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
4262b5a0f065187fd19179e3809148dbfc376ada7a0Jay SrinivasanTEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDownload) {
4272b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  OmahaResponse response;
4282b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  PayloadState payload_state;
42919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
43019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
4312b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
432dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
43319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
43419409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
43519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
43619409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
437082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
43819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
43919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(2));
4402b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
44119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
44219409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
44319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
44419409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
4459a017f2c5ae41c04a7c7c15b5dbd08faadae7606David Zeuthen
44619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
4472b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4482b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash8593", &payload_state, &response);
4492b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4502b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should just advance the payload attempt number;
4512b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
4522b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.DownloadComplete();
4532b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
4542b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
4552b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
456cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
4572b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
4582b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4592b5a0f065187fd19179e3809148dbfc376ada7a0Jay SrinivasanTEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
4602b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  OmahaResponse response;
4612b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  PayloadState payload_state;
46219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
4632b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
46419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
4652b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash4427", &payload_state, &response);
4662b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4672b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Generate enough events to advance URL index, failure count and
4682b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // payload attempt number all to 1.
4692b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.DownloadComplete();
470a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
471a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
4722b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
4732b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
4742b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlFailureCount());
475cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
4762b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4772b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Now, simulate a corrupted url index on persisted store which gets
4782b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // loaded when update_engine restarts. Using a different prefs object
4792b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // so as to not bother accounting for the uninteresting calls above.
48019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state2;
48119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs2 = mock_system_state2.mock_prefs();
48219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
48319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, GetInt64(_,_)).Times(AtLeast(1));
48419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
48519409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
48619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
48719409b74019d787100b768306e75ab3e5882898dJay Srinivasan      .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
48819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
48919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
490cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _))
491cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen    .Times(AtLeast(1));
4922b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4932b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Note: This will be a different payload object, but the response should
4942b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // have the same hash as before so as to not trivially reset because the
4952b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // response was different. We want to specifically test that even if the
4962b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // response is same, we should reset the state if we find it corrupted.
49719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state2));
4982b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash4427", &payload_state, &response);
4992b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
5002b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Make sure all counters get reset to 0 because of the corrupted URL index
5012b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // we supplied above.
5022b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
5032b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
5042b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
505cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
5062b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
507082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
508082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay SrinivasanTEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
509082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  OmahaResponse response;
510082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  response.is_delta_payload = true;
511082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  PayloadState payload_state;
51219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
513082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
51419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
515082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash6437", &payload_state, &response);
516082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
517082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Simulate a successful download and see that we're ready to download
518082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // again without any backoff as this is a delta payload.
519082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  payload_state.DownloadComplete();
520082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
521082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
522082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
523082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Simulate two failures (enough to cause payload backoff) and check
524082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // again that we're ready to re-download without any backoff as this is
525082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // a delta payload.
526a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
527a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
528082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
529082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
530082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
531082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan}
532082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
533082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasanstatic void CheckPayloadBackoffState(PayloadState* payload_state,
534082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                     int expected_attempt_number,
535082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                     TimeDelta expected_days) {
536082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  payload_state->DownloadComplete();
537082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_attempt_number, payload_state->GetPayloadAttemptNumber());
538082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state->ShouldBackoffDownload());
539082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
540082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
541082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
542082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
543082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
544082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_LT(expected_min_time.ToInternalValue(),
545082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan            backoff_expiry_time.ToInternalValue());
546082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_GT(expected_max_time.ToInternalValue(),
547082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan            backoff_expiry_time.ToInternalValue());
548082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan}
549082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
550082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay SrinivasanTEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
551082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  OmahaResponse response;
552082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  response.is_delta_payload = false;
553082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  PayloadState payload_state;
55419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
555082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
55619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
557082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash8939", &payload_state, &response);
558082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
559082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 1,  TimeDelta::FromDays(1));
560082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 2,  TimeDelta::FromDays(2));
561082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 3,  TimeDelta::FromDays(4));
562082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 4,  TimeDelta::FromDays(8));
563082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 5,  TimeDelta::FromDays(16));
564082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 6,  TimeDelta::FromDays(16));
565082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 7,  TimeDelta::FromDays(16));
566082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 8,  TimeDelta::FromDays(16));
567082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 9,  TimeDelta::FromDays(16));
568082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 10,  TimeDelta::FromDays(16));
569082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan}
570082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
571082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay SrinivasanTEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
572082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  OmahaResponse response;
573082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  response.disable_payload_backoff = true;
574082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  PayloadState payload_state;
57519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
576082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
57719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
578082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash8939", &payload_state, &response);
579082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
580082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Simulate a successful download and see that we are ready to download
581082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // again without any backoff.
582082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  payload_state.DownloadComplete();
583082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
584082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
585082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
586082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Test again, this time by simulating two errors that would cause
587082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // the payload attempt number to increment due to wrap around. And
588082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // check that we are still ready to re-download without any backoff.
589a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
590a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
591082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
592082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
593082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan}
594082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
59519409b74019d787100b768306e75ab3e5882898dJay SrinivasanTEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
59619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  OmahaResponse response;
59719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  response.disable_payload_backoff = true;
59819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  PayloadState payload_state;
59919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
60019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int https_total = 0;
60119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int http_total = 0;
60219409b74019d787100b768306e75ab3e5882898dJay Srinivasan
60319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
60419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  SetupPayloadStateWith2Urls("Hash3286", &payload_state, &response);
60519409b74019d787100b768306e75ab3e5882898dJay Srinivasan
606dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  // Simulate a previous attempt with in order to set an initial non-zero value
607dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  // for the total bytes downloaded for HTTP.
608dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  int prev_chunk = 323456789;
609dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  http_total += prev_chunk;
610dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  payload_state.DownloadProgress(prev_chunk);
611dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan
612dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  // Ensure that the initial values for HTTP reflect this attempt.
613dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_EQ(prev_chunk,
614dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
615dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_EQ(http_total,
616dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
617dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan
618dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  // Change the response hash so as to simulate a new response which will
619dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  // reset the current bytes downloaded, but not the total bytes downloaded.
620dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  SetupPayloadStateWith2Urls("Hash9904", &payload_state, &response);
621dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan
622dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  // First, simulate successful download of a few bytes over HTTP.
62319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int first_chunk = 5000000;
62419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  http_total += first_chunk;
62519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(first_chunk);
62619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Test that first all progress is made on HTTP and none on HTTPs.
62719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(first_chunk,
62819409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
62919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(http_total,
63019409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
63119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
63219409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
63319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(https_total,
63419409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
63519409b74019d787100b768306e75ab3e5882898dJay Srinivasan
63619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Simulate an error that'll cause the url index to point to https.
637a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
63819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.UpdateFailed(error);
63919409b74019d787100b768306e75ab3e5882898dJay Srinivasan
64019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Test that no new progress is made on HTTP and new progress is on HTTPs.
64119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int second_chunk = 23456789;
64219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  https_total += second_chunk;
64319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(second_chunk);
64419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(first_chunk,
64519409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
64619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(http_total,
64719409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
64819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
64919409b74019d787100b768306e75ab3e5882898dJay Srinivasan              kDownloadSourceHttpsServer));
65019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(https_total,
65119409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
65219409b74019d787100b768306e75ab3e5882898dJay Srinivasan
65319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Simulate error to go back to http.
65419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.UpdateFailed(error);
65519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int third_chunk = 32345678;
65619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int http_chunk = first_chunk + third_chunk;
65719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  http_total += third_chunk;
65819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int https_chunk = second_chunk;
65919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(third_chunk);
66019409b74019d787100b768306e75ab3e5882898dJay Srinivasan
66119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
66219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(http_chunk,
66319409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
664dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_EQ(http_total,
66519409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
66619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
66719409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
66819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(https_total,
66919409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
67019409b74019d787100b768306e75ab3e5882898dJay Srinivasan
671dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
672dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan    .Times(AnyNumber());
67319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
67419409b74019d787100b768306e75ab3e5882898dJay Srinivasan      "Installer.SuccessfulMBsDownloadedFromHttpServer",
67519409b74019d787100b768306e75ab3e5882898dJay Srinivasan      http_chunk / kNumBytesInOneMiB, _, _, _));
67619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
67719409b74019d787100b768306e75ab3e5882898dJay Srinivasan      "Installer.TotalMBsDownloadedFromHttpServer",
67819409b74019d787100b768306e75ab3e5882898dJay Srinivasan      http_total / kNumBytesInOneMiB, _, _, _));
67919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
68019409b74019d787100b768306e75ab3e5882898dJay Srinivasan      "Installer.SuccessfulMBsDownloadedFromHttpsServer",
68119409b74019d787100b768306e75ab3e5882898dJay Srinivasan      https_chunk / kNumBytesInOneMiB, _, _, _));
68219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
68319409b74019d787100b768306e75ab3e5882898dJay Srinivasan      "Installer.TotalMBsDownloadedFromHttpsServer",
68419409b74019d787100b768306e75ab3e5882898dJay Srinivasan      https_total / kNumBytesInOneMiB, _, _, _));
685cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
686cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen      "Installer.UpdateURLSwitches",
687cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen      2, _, _, _));
688674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
689674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen      "Installer.UpdateDurationMinutes",
690674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen      _, _, _, _));
691674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
692674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen      "Installer.UpdateDurationUptimeMinutes",
693674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen      _, _, _, _));
694dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
695dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan      "Installer.DownloadSourcesUsed", 3, _, _, _));
696dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
697dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan      "Installer.DownloadOverheadPercentage", 542, _, _, _));
69819409b74019d787100b768306e75ab3e5882898dJay Srinivasan
69919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.UpdateSucceeded();
70019409b74019d787100b768306e75ab3e5882898dJay Srinivasan
70119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Make sure the metrics are reset after a successful update.
70219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
70319409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
70419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
70519409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
70619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
70719409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
70819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
70919409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
71019409b74019d787100b768306e75ab3e5882898dJay Srinivasan}
71119409b74019d787100b768306e75ab3e5882898dJay Srinivasan
71219409b74019d787100b768306e75ab3e5882898dJay SrinivasanTEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
71319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  OmahaResponse response;
71419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
71519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  PayloadState payload_state;
71619409b74019d787100b768306e75ab3e5882898dJay Srinivasan
71719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
71819409b74019d787100b768306e75ab3e5882898dJay Srinivasan
71919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Set the first response.
72019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  SetupPayloadStateWith2Urls("Hash5823", &payload_state, &response);
72119409b74019d787100b768306e75ab3e5882898dJay Srinivasan
72219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int num_bytes = 10000;
72319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(num_bytes);
72419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(num_bytes,
72519409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
72619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(num_bytes,
72719409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
72819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
72919409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
73019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
73119409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
73219409b74019d787100b768306e75ab3e5882898dJay Srinivasan
73319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.UpdateRestarted();
73419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Make sure the current bytes downloaded is reset, but not the total bytes.
73519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
73619409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
73719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(num_bytes,
73819409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
73919409b74019d787100b768306e75ab3e5882898dJay Srinivasan}
74019409b74019d787100b768306e75ab3e5882898dJay Srinivasan
741be45bef9e283188b00e7def8967f81843669a7f1Chris SosaTEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
742be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  MockSystemState mock_system_state;
743be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  PayloadState payload_state;
744be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
745be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
746be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
747be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
74819409b74019d787100b768306e75ab3e5882898dJay Srinivasan
749be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
750be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
751be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  payload_state.UpdateRestarted();
752be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_EQ(0, payload_state.GetNumReboots());
753be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
754be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(true));
755be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  payload_state.UpdateResumed();
756be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  // Num reboots should be incremented because system rebooted detected.
757be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_EQ(1, payload_state.GetNumReboots());
758be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
759be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(false));
760be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  payload_state.UpdateResumed();
761be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  // Num reboots should now be 1 as reboot was not detected.
762be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_EQ(1, payload_state.GetNumReboots());
763be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
764be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  // Restart the update again to verify we set the num of reboots back to 0.
765be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  payload_state.UpdateRestarted();
766be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_EQ(0, payload_state.GetNumReboots());
767be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa}
76819409b74019d787100b768306e75ab3e5882898dJay Srinivasan
769f413fe59759c73d6a5624c2158260b4302d01fe2David ZeuthenTEST(PayloadStateTest, DurationsAreCorrect) {
770f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  OmahaResponse response;
771f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  PayloadState payload_state;
772f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  MockSystemState mock_system_state;
773f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  FakeClock fake_clock;
774f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  Prefs prefs;
775f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  string temp_dir;
776f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
777f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Set the clock to a well-known time - 1 second on the wall-clock
778f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // and 2 seconds on the monotonic clock
779f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
780f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
781f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
782f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // We need persistent preferences for this test
783f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateDurationTests.XXXXXX",
784f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen                                       &temp_dir));
785f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  prefs.Init(FilePath(temp_dir));
786f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
787f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  mock_system_state.set_clock(&fake_clock);
788f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  mock_system_state.set_prefs(&prefs);
789f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
790f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
791f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Check that durations are correct for a successful update where
792f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // time has advanced 7 seconds on the wall clock and 4 seconds on
793f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // the monotonic clock.
794f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  SetupPayloadStateWith2Urls("Hash8593", &payload_state, &response);
795f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
796f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
797f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  payload_state.UpdateSucceeded();
798f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
799f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
800f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
801f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Check that durations are reset when a new response comes in.
802f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  SetupPayloadStateWith2Urls("Hash8594", &payload_state, &response);
803f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
804f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
805f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
806f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Advance time a bit (10 secs), simulate download progress and
807f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // check that durations are updated.
808f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
809f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
810f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  payload_state.DownloadProgress(10);
811f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
812f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
813f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
814f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Now simulate a reboot by resetting monotonic time (to 5000) and
815f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // creating a new PayloadState object and check that we load the
816f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // durations correctly (e.g. they are the same as before).
817f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
818f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  PayloadState payload_state2;
819f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
820f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
821f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),10000000);
822f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
823f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
824f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // and check that the durations are increased accordingly.
825f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
826f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
827f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  payload_state2.UpdateSucceeded();
828f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
829f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),16000000);
830f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
831f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
832f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen}
833f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
8346f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
835