payload_state_unittest.cc revision f413fe59759c73d6a5624c2158260b4302d01fe2
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;
316f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
326f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasannamespace chromeos_update_engine {
336f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
3419409b74019d787100b768306e75ab3e5882898dJay Srinivasanconst char* kCurrentBytesDownloadedFromHttps =
3519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  "current-bytes-downloaded-from-HttpsServer";
3619409b74019d787100b768306e75ab3e5882898dJay Srinivasanconst char* kTotalBytesDownloadedFromHttps =
3719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  "total-bytes-downloaded-from-HttpsServer";
3819409b74019d787100b768306e75ab3e5882898dJay Srinivasanconst char* kCurrentBytesDownloadedFromHttp =
3919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  "current-bytes-downloaded-from-HttpServer";
4019409b74019d787100b768306e75ab3e5882898dJay Srinivasanconst char* kTotalBytesDownloadedFromHttp =
4119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  "total-bytes-downloaded-from-HttpServer";
4219409b74019d787100b768306e75ab3e5882898dJay Srinivasan
432b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasanstatic void SetupPayloadStateWith2Urls(string hash,
442b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan                                       PayloadState* payload_state,
452b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan                                       OmahaResponse* response) {
462b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->payload_urls.clear();
472b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->payload_urls.push_back("http://test");
482b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->payload_urls.push_back("https://test");
492b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->size = 523456789;
502b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->hash = hash;
512b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->metadata_size = 558123;
522b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->metadata_signature = "metasign";
532b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->max_failure_count_per_url = 3;
542b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state->SetResponse(*response);
55082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string stored_response_sign = payload_state->GetResponseSignature();
56082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string expected_response_sign = StringPrintf(
572b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      "NumURLs = 2\n"
582b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      "Url0 = http://test\n"
592b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      "Url1 = https://test\n"
602b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      "Payload Size = 523456789\n"
612b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      "Payload Sha256 Hash = %s\n"
622b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      "Metadata Size = 558123\n"
63082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      "Metadata Signature = metasign\n"
64082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      "Is Delta Payload = %d\n"
65082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      "Max Failure Count Per Url = %d\n"
66082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      "Disable Payload Backoff = %d\n",
67082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      hash.c_str(),
68082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      response->is_delta_payload,
69082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      response->max_failure_count_per_url,
70082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan      response->disable_payload_backoff);
71082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_response_sign, stored_response_sign);
722b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
732b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
746f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasanclass PayloadStateTest : public ::testing::Test { };
756f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
762b5a0f065187fd19179e3809148dbfc376ada7a0Jay SrinivasanTEST(PayloadStateTest, DidYouAddANewActionExitCode) {
771c0fe79c7ef2b43946d756b54c8505d2bf48b93bJay Srinivasan  if (kActionCodeUmaReportedMax != 43) {
782b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan    LOG(ERROR) << "The following failure is intentional. If you added a new "
792b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan               << "ActionExitCode enum value, make sure to add it to the "
802b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan               << "PayloadState::UpdateFailed method and then update this test "
812b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan               << "to the new value of kActionCodeUmaReportedMax, which is "
822b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan               << kActionCodeUmaReportedMax;
832b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan    EXPECT_FALSE("Please see the log line above");
842b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  }
852b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
862b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
876f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
886f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
8919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
9019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
9119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
9219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
9319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
9419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
9519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
9619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
9719409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
9819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
9919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
10019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
10119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
10219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
10319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
10419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
10519409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
106be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
1076f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
10819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1096f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.SetResponse(response);
110082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string stored_response_sign = payload_state.GetResponseSignature();
111082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string expected_response_sign = "NumURLs = 0\n"
112082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Size = 0\n"
113082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Sha256 Hash = \n"
114082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Size = 0\n"
115082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Signature = \n"
116082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Is Delta Payload = 0\n"
117082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Max Failure Count Per Url = 0\n"
118082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Disable Payload Backoff = 0\n";
119082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_response_sign, stored_response_sign);
1206f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
1212b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
122cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
1236f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
1246f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
1256f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
1266f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
1276f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.payload_urls.push_back("http://single.url.test");
1286f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.size = 123456789;
1296f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.hash = "hash";
1306f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.metadata_size = 58123;
1316f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.metadata_signature = "msign";
13219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
13319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
13419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
13519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
13619409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
13719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
13819409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
13919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
14019409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
14119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
14219409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
14319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
14419409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
14519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
14619409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
14719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
14819409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
14919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
15019409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
151be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
152be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa      .Times(AtLeast(1));
1536f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
15419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1556f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.SetResponse(response);
156082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string stored_response_sign = payload_state.GetResponseSignature();
157082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string expected_response_sign = "NumURLs = 1\n"
158082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Url0 = http://single.url.test\n"
159082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Size = 123456789\n"
160082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Sha256 Hash = hash\n"
161082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Size = 58123\n"
162082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Signature = msign\n"
163082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Is Delta Payload = 0\n"
164082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Max Failure Count Per Url = 0\n"
165082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Disable Payload Backoff = 0\n";
166082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_response_sign, stored_response_sign);
1676f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
1682b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
169cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
1706f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
1716f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
1726f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
1736f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
1746f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.payload_urls.push_back("http://multiple.url.test");
1756f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.payload_urls.push_back("https://multiple.url.test");
1766f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.size = 523456789;
1776f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.hash = "rhash";
1786f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.metadata_size = 558123;
1796f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.metadata_signature = "metasign";
18019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
18119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
18219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
18319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
18419409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
18519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
18619409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
18719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
18819409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
18919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
19019409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
19119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
19219409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
19319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
19419409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
195be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
196be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa      .Times(AtLeast(1));
1976f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
19819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1996f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.SetResponse(response);
200082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string stored_response_sign = payload_state.GetResponseSignature();
201082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string expected_response_sign = "NumURLs = 2\n"
202082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Url0 = http://multiple.url.test\n"
203082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Url1 = https://multiple.url.test\n"
204082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Size = 523456789\n"
205082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Sha256 Hash = rhash\n"
206082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Size = 558123\n"
207082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Signature = metasign\n"
208082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Is Delta Payload = 0\n"
209082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Max Failure Count Per Url = 0\n"
210082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Disable Payload Backoff = 0\n";
211082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_response_sign, stored_response_sign);
2126f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
2132b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
214cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
2156f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
2166f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2176f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
2186f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
21919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
22019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
2216f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
2222b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
22319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
2242b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Payload attempt should start with 0 and then advance to 1.
22519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
22619409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
22719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
22819409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
22919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
2309a017f2c5ae41c04a7c7c15b5dbd08faadae7606David Zeuthen
231be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  // Reboots will be set
232be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1));
233be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
2342b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Url index should go from 0 to 1 twice.
23519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
23619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
2372b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
2382b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Failure count should be called each times url index is set, so that's
2392b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // 4 times for this test.
24019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
24119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(4));
2422b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
24319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
2442b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
2452b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This does a SetResponse which causes all the states to be set to 0 for
2462b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // the first time.
2472b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash1235", &payload_state, &response);
2486f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
2496f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2506f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Verify that on the first error, the URL index advances to 1.
2516f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  ActionExitCode error = kActionCodeDownloadMetadataSignatureMismatch;
2526f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.UpdateFailed(error);
2536f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
2546f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2556f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Verify that on the next error, the URL index wraps around to 0.
2566f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.UpdateFailed(error);
2576f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
2586f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2596f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Verify that on the next error, it again advances to 1.
2606f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.UpdateFailed(error);
2616f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
262cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen
263cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  // Verify that we switched URLs three times
264cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
2656f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
2666f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2676f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, NewResponseResetsPayloadState) {
2686f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
26919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
2706f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
2712b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
27219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
2732b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
2742b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Set the first response.
2752b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash5823", &payload_state, &response);
2766f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2776f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Advance the URL index to 1 by faking an error.
2786f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  ActionExitCode error = kActionCodeDownloadMetadataSignatureMismatch;
2796f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.UpdateFailed(error);
2806f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
281cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
2826f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2836f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Now, slightly change the response and set it again.
2842b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash8225", &payload_state, &response);
2852b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
2862b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Make sure the url index was reset to 0 because of the new response.
2872b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
2882b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
289cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
29019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
29119409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
29219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
29319409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
29419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
29519409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
29619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
29719409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
2982b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
2992b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3002b5a0f065187fd19179e3809148dbfc376ada7a0Jay SrinivasanTEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
3012b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  OmahaResponse response;
3022b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  PayloadState payload_state;
30319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
30419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int progress_bytes = 100;
30519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
30619409b74019d787100b768306e75ab3e5882898dJay Srinivasan
30719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
30819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
30919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(2));
31019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
31119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
31219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
31319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
31419409b74019d787100b768306e75ab3e5882898dJay Srinivasan
31519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
31619409b74019d787100b768306e75ab3e5882898dJay Srinivasan
31719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
31819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
31919409b74019d787100b768306e75ab3e5882898dJay Srinivasan
32019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
32119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(7));
32219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
32319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(2));
32419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
32519409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
32619409b74019d787100b768306e75ab3e5882898dJay Srinivasan
32719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
32819409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
32919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
33019409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
33119409b74019d787100b768306e75ab3e5882898dJay Srinivasan
33219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
33319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
33419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
33519409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
33619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
33719409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
33819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
33919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
340be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
341be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa      .Times(AtLeast(1));
34219409b74019d787100b768306e75ab3e5882898dJay Srinivasan
34319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
3442b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3452b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash5873", &payload_state, &response);
3462b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3472b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the URL index.
3482b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
3492b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
3502b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
3512b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
352cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
3532b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3542b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the failure count only.
3552b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.UpdateFailed(kActionCodeDownloadTransferError);
3562b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
3572b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
3582b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlFailureCount());
359cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
3602b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3612b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the failure count only.
3622b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.UpdateFailed(kActionCodeDownloadTransferError);
3632b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
3642b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
3652b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetUrlFailureCount());
366cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
3672b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3682b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the URL index as we've reached the
3692b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // max failure count and reset the failure count for the new URL index.
3702b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should also wrap around the URL index and thus cause the payload
3712b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // attempt number to be incremented.
3722b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.UpdateFailed(kActionCodeDownloadTransferError);
3732b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
3742b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
3752b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
376cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(2, payload_state.GetUrlSwitchCount());
377082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
3782b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3792b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the URL index.
3802b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.UpdateFailed(kActionCodePayloadHashMismatchError);
3812b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
3822b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
3832b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
384cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
385082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
3862b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3872b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the URL index and payload attempt number due to
3882b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // wrap-around of URL index.
3892b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMissingError);
3902b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
3912b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
3922b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
393cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
394082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
3952b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3962b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This HTTP error code should only increase the failure count.
3972b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.UpdateFailed(static_cast<ActionExitCode>(
3982b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      kActionCodeOmahaRequestHTTPResponseBase + 404));
3992b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
4002b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
4012b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlFailureCount());
402cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
403082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
4042b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4052b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // And that failure count should be reset when we download some bytes
4062b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // afterwards.
40719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(progress_bytes);
4082b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
4092b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
4102b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
411cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
412082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
4132b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4142b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Now, slightly change the response and set it again.
4152b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash8532", &payload_state, &response);
4166f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
4176f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Make sure the url index was reset to 0 because of the new response.
4182b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
4196f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
4202b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
421cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
422082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
4236f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
4246f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
4252b5a0f065187fd19179e3809148dbfc376ada7a0Jay SrinivasanTEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDownload) {
4262b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  OmahaResponse response;
4272b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  PayloadState payload_state;
42819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
42919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
4302b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
43119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
43219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
43319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
43419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
43519409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
436082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
43719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
43819409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(2));
4392b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
44019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
44119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
44219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
44319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
4449a017f2c5ae41c04a7c7c15b5dbd08faadae7606David Zeuthen
44519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
4462b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4472b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash8593", &payload_state, &response);
4482b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4492b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should just advance the payload attempt number;
4502b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
4512b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.DownloadComplete();
4522b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
4532b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
4542b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
455cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
4562b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
4572b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4582b5a0f065187fd19179e3809148dbfc376ada7a0Jay SrinivasanTEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
4592b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  OmahaResponse response;
4602b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  PayloadState payload_state;
46119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
4622b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
46319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
4642b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash4427", &payload_state, &response);
4652b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4662b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Generate enough events to advance URL index, failure count and
4672b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // payload attempt number all to 1.
4682b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.DownloadComplete();
4692b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
4702b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.UpdateFailed(kActionCodeDownloadTransferError);
4712b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
4722b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlIndex());
4732b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlFailureCount());
474cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
4752b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4762b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Now, simulate a corrupted url index on persisted store which gets
4772b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // loaded when update_engine restarts. Using a different prefs object
4782b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // so as to not bother accounting for the uninteresting calls above.
47919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state2;
48019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs2 = mock_system_state2.mock_prefs();
48119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
48219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, GetInt64(_,_)).Times(AtLeast(1));
48319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
48419409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
48519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
48619409b74019d787100b768306e75ab3e5882898dJay Srinivasan      .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
48719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
48819409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
489cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _))
490cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen    .Times(AtLeast(1));
4912b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4922b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Note: This will be a different payload object, but the response should
4932b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // have the same hash as before so as to not trivially reset because the
4942b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // response was different. We want to specifically test that even if the
4952b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // response is same, we should reset the state if we find it corrupted.
49619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state2));
4972b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash4427", &payload_state, &response);
4982b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4992b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Make sure all counters get reset to 0 because of the corrupted URL index
5002b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // we supplied above.
5012b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
5022b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
5032b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
504cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
5052b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
506082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
507082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay SrinivasanTEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
508082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  OmahaResponse response;
509082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  response.is_delta_payload = true;
510082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  PayloadState payload_state;
51119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
512082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
51319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
514082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash6437", &payload_state, &response);
515082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
516082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Simulate a successful download and see that we're ready to download
517082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // again without any backoff as this is a delta payload.
518082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  payload_state.DownloadComplete();
519082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
520082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
521082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
522082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Simulate two failures (enough to cause payload backoff) and check
523082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // again that we're ready to re-download without any backoff as this is
524082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // a delta payload.
525082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
526082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
527082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlIndex());
528082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
529082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
530082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan}
531082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
532082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasanstatic void CheckPayloadBackoffState(PayloadState* payload_state,
533082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                     int expected_attempt_number,
534082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                     TimeDelta expected_days) {
535082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  payload_state->DownloadComplete();
536082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_attempt_number, payload_state->GetPayloadAttemptNumber());
537082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state->ShouldBackoffDownload());
538082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
539082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
540082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
541082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
542082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
543082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_LT(expected_min_time.ToInternalValue(),
544082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan            backoff_expiry_time.ToInternalValue());
545082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_GT(expected_max_time.ToInternalValue(),
546082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan            backoff_expiry_time.ToInternalValue());
547082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan}
548082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
549082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay SrinivasanTEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
550082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  OmahaResponse response;
551082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  response.is_delta_payload = false;
552082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  PayloadState payload_state;
55319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
554082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
55519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
556082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash8939", &payload_state, &response);
557082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
558082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 1,  TimeDelta::FromDays(1));
559082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 2,  TimeDelta::FromDays(2));
560082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 3,  TimeDelta::FromDays(4));
561082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 4,  TimeDelta::FromDays(8));
562082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 5,  TimeDelta::FromDays(16));
563082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 6,  TimeDelta::FromDays(16));
564082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 7,  TimeDelta::FromDays(16));
565082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 8,  TimeDelta::FromDays(16));
566082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 9,  TimeDelta::FromDays(16));
567082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 10,  TimeDelta::FromDays(16));
568082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan}
569082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
570082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay SrinivasanTEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
571082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  OmahaResponse response;
572082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  response.disable_payload_backoff = true;
573082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  PayloadState payload_state;
57419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
575082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
57619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
577082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  SetupPayloadStateWith2Urls("Hash8939", &payload_state, &response);
578082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
579082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Simulate a successful download and see that we are ready to download
580082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // again without any backoff.
581082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  payload_state.DownloadComplete();
582082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
583082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
584082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
585082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Test again, this time by simulating two errors that would cause
586082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // the payload attempt number to increment due to wrap around. And
587082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // check that we are still ready to re-download without any backoff.
588082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
589082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
590082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
591082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
592082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan}
593082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
59419409b74019d787100b768306e75ab3e5882898dJay SrinivasanTEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
59519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  OmahaResponse response;
59619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  response.disable_payload_backoff = true;
59719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  PayloadState payload_state;
59819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
59919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int https_total = 0;
60019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int http_total = 0;
60119409b74019d787100b768306e75ab3e5882898dJay Srinivasan
60219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
60319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  SetupPayloadStateWith2Urls("Hash3286", &payload_state, &response);
60419409b74019d787100b768306e75ab3e5882898dJay Srinivasan
60519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Simulate a successful download and see that we are ready to download
60619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // again without any backoff.
60719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int first_chunk = 5000000;
60819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  http_total += first_chunk;
60919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(first_chunk);
61019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Test that first all progress is made on HTTP and none on HTTPs.
61119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(first_chunk,
61219409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
61319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(http_total,
61419409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
61519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
61619409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
61719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(https_total,
61819409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
61919409b74019d787100b768306e75ab3e5882898dJay Srinivasan
62019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Simulate an error that'll cause the url index to point to https.
62119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  ActionExitCode error = kActionCodeDownloadMetadataSignatureMismatch;
62219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.UpdateFailed(error);
62319409b74019d787100b768306e75ab3e5882898dJay Srinivasan
62419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Test that no new progress is made on HTTP and new progress is on HTTPs.
62519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int second_chunk = 23456789;
62619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  https_total += second_chunk;
62719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(second_chunk);
62819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(first_chunk,
62919409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
63019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(http_total,
63119409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
63219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
63319409b74019d787100b768306e75ab3e5882898dJay Srinivasan              kDownloadSourceHttpsServer));
63419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(https_total,
63519409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
63619409b74019d787100b768306e75ab3e5882898dJay Srinivasan
63719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Simulate error to go back to http.
63819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.UpdateFailed(error);
63919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int third_chunk = 32345678;
64019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int http_chunk = first_chunk + third_chunk;
64119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  http_total += third_chunk;
64219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int https_chunk = second_chunk;
64319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(third_chunk);
64419409b74019d787100b768306e75ab3e5882898dJay Srinivasan
64519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
64619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(http_chunk,
64719409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
64819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(http_chunk,
64919409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
65019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
65119409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
65219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(https_total,
65319409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
65419409b74019d787100b768306e75ab3e5882898dJay Srinivasan
655be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  // Don't care about other metrics in this test.
656be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
657be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa      _,_,_,_,_)).Times(AtLeast(0));
65819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
65919409b74019d787100b768306e75ab3e5882898dJay Srinivasan      "Installer.SuccessfulMBsDownloadedFromHttpServer",
66019409b74019d787100b768306e75ab3e5882898dJay Srinivasan      http_chunk / kNumBytesInOneMiB, _, _, _));
66119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
66219409b74019d787100b768306e75ab3e5882898dJay Srinivasan      "Installer.TotalMBsDownloadedFromHttpServer",
66319409b74019d787100b768306e75ab3e5882898dJay Srinivasan      http_total / kNumBytesInOneMiB, _, _, _));
66419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
66519409b74019d787100b768306e75ab3e5882898dJay Srinivasan      "Installer.SuccessfulMBsDownloadedFromHttpsServer",
66619409b74019d787100b768306e75ab3e5882898dJay Srinivasan      https_chunk / kNumBytesInOneMiB, _, _, _));
66719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
66819409b74019d787100b768306e75ab3e5882898dJay Srinivasan      "Installer.TotalMBsDownloadedFromHttpsServer",
66919409b74019d787100b768306e75ab3e5882898dJay Srinivasan      https_total / kNumBytesInOneMiB, _, _, _));
670cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
671cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen      "Installer.UpdateURLSwitches",
672cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen      2, _, _, _));
673674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
674674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen      "Installer.UpdateDurationMinutes",
675674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen      _, _, _, _));
676674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
677674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen      "Installer.UpdateDurationUptimeMinutes",
678674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen      _, _, _, _));
67919409b74019d787100b768306e75ab3e5882898dJay Srinivasan
68019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.UpdateSucceeded();
68119409b74019d787100b768306e75ab3e5882898dJay Srinivasan
68219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Make sure the metrics are reset after a successful update.
68319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
68419409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
68519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
68619409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
68719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
68819409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
68919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
69019409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
69119409b74019d787100b768306e75ab3e5882898dJay Srinivasan}
69219409b74019d787100b768306e75ab3e5882898dJay Srinivasan
69319409b74019d787100b768306e75ab3e5882898dJay SrinivasanTEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
69419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  OmahaResponse response;
69519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
69619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  PayloadState payload_state;
69719409b74019d787100b768306e75ab3e5882898dJay Srinivasan
69819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
69919409b74019d787100b768306e75ab3e5882898dJay Srinivasan
70019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Set the first response.
70119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  SetupPayloadStateWith2Urls("Hash5823", &payload_state, &response);
70219409b74019d787100b768306e75ab3e5882898dJay Srinivasan
70319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int num_bytes = 10000;
70419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(num_bytes);
70519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(num_bytes,
70619409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
70719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(num_bytes,
70819409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
70919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
71019409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
71119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
71219409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
71319409b74019d787100b768306e75ab3e5882898dJay Srinivasan
71419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.UpdateRestarted();
71519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Make sure the current bytes downloaded is reset, but not the total bytes.
71619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
71719409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
71819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(num_bytes,
71919409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
72019409b74019d787100b768306e75ab3e5882898dJay Srinivasan}
72119409b74019d787100b768306e75ab3e5882898dJay Srinivasan
722be45bef9e283188b00e7def8967f81843669a7f1Chris SosaTEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
723be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  MockSystemState mock_system_state;
724be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  PayloadState payload_state;
725be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
726be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
727be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
728be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
72919409b74019d787100b768306e75ab3e5882898dJay Srinivasan
730be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
731be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
732be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  payload_state.UpdateRestarted();
733be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_EQ(0, payload_state.GetNumReboots());
734be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
735be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(true));
736be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  payload_state.UpdateResumed();
737be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  // Num reboots should be incremented because system rebooted detected.
738be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_EQ(1, payload_state.GetNumReboots());
739be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
740be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(false));
741be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  payload_state.UpdateResumed();
742be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  // Num reboots should now be 1 as reboot was not detected.
743be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_EQ(1, payload_state.GetNumReboots());
744be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
745be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  // Restart the update again to verify we set the num of reboots back to 0.
746be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  payload_state.UpdateRestarted();
747be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_EQ(0, payload_state.GetNumReboots());
748be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa}
74919409b74019d787100b768306e75ab3e5882898dJay Srinivasan
750f413fe59759c73d6a5624c2158260b4302d01fe2David ZeuthenTEST(PayloadStateTest, DurationsAreCorrect) {
751f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  OmahaResponse response;
752f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  PayloadState payload_state;
753f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  MockSystemState mock_system_state;
754f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  FakeClock fake_clock;
755f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  Prefs prefs;
756f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  string temp_dir;
757f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
758f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Set the clock to a well-known time - 1 second on the wall-clock
759f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // and 2 seconds on the monotonic clock
760f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
761f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
762f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
763f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // We need persistent preferences for this test
764f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateDurationTests.XXXXXX",
765f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen                                       &temp_dir));
766f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  prefs.Init(FilePath(temp_dir));
767f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
768f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  mock_system_state.set_clock(&fake_clock);
769f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  mock_system_state.set_prefs(&prefs);
770f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
771f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
772f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Check that durations are correct for a successful update where
773f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // time has advanced 7 seconds on the wall clock and 4 seconds on
774f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // the monotonic clock.
775f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  SetupPayloadStateWith2Urls("Hash8593", &payload_state, &response);
776f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
777f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
778f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  payload_state.UpdateSucceeded();
779f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
780f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
781f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
782f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Check that durations are reset when a new response comes in.
783f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  SetupPayloadStateWith2Urls("Hash8594", &payload_state, &response);
784f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
785f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
786f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
787f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Advance time a bit (10 secs), simulate download progress and
788f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // check that durations are updated.
789f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
790f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
791f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  payload_state.DownloadProgress(10);
792f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
793f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
794f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
795f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Now simulate a reboot by resetting monotonic time (to 5000) and
796f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // creating a new PayloadState object and check that we load the
797f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // durations correctly (e.g. they are the same as before).
798f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
799f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  PayloadState payload_state2;
800f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
801f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
802f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),10000000);
803f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
804f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
805f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // and check that the durations are increased accordingly.
806f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
807f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
808f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  payload_state2.UpdateSucceeded();
809f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
810f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),16000000);
811f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
812f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
813f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen}
814f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
8156f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
816