payload_state_unittest.cc revision 1c656c48886cf5054b526ed7e95b05903d7644db
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,
4553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                                       bool http_enabled,
462b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan                                       PayloadState* payload_state,
472b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan                                       OmahaResponse* response) {
482b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->payload_urls.clear();
492b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->payload_urls.push_back("http://test");
502b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->payload_urls.push_back("https://test");
512b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->size = 523456789;
522b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->hash = hash;
532b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->metadata_size = 558123;
542b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->metadata_signature = "metasign";
552b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  response->max_failure_count_per_url = 3;
562b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state->SetResponse(*response);
57082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string stored_response_sign = payload_state->GetResponseSignature();
5853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
5953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  string expected_url_https_only =
6053173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan      "NumURLs = 1\n"
6153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan      "Candidate Url0 = https://test\n";
6253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
6353173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  string expected_urls_both =
642b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan      "NumURLs = 2\n"
6553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan      "Candidate Url0 = http://test\n"
6653173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan      "Candidate Url1 = https://test\n";
6753173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
6853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  string expected_response_sign =
6953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan      (http_enabled ? expected_urls_both : expected_url_https_only) +
7053173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan      StringPrintf("Payload Size = 523456789\n"
7153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                   "Payload Sha256 Hash = %s\n"
7253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                   "Metadata Size = 558123\n"
7353173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                   "Metadata Signature = metasign\n"
7453173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                   "Is Delta Payload = %d\n"
7553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                   "Max Failure Count Per Url = %d\n"
7653173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                   "Disable Payload Backoff = %d\n",
7753173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                   hash.c_str(),
7853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                   response->is_delta_payload,
7953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                   response->max_failure_count_per_url,
8053173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                   response->disable_payload_backoff);
81082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_response_sign, stored_response_sign);
822b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
832b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
846f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasanclass PayloadStateTest : public ::testing::Test { };
856f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
86a99981fda75fe0b17e96c700e3ddc93eca1cebe5David ZeuthenTEST(PayloadStateTest, DidYouAddANewErrorCode) {
87a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  if (kErrorCodeUmaReportedMax != 43) {
882b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan    LOG(ERROR) << "The following failure is intentional. If you added a new "
89a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen               << "ErrorCode enum value, make sure to add it to the "
902b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan               << "PayloadState::UpdateFailed method and then update this test "
91a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen               << "to the new value of kErrorCodeUmaReportedMax, which is "
92a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen               << kErrorCodeUmaReportedMax;
932b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan    EXPECT_FALSE("Please see the log line above");
942b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  }
952b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
962b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
976f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
986f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
9919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
10019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
101dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
10219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
10319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
10419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
10519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
10619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
10719409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
10819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
10919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
11019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
11119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
11219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
11319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
11419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
11519409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
116be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
1176f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
11819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1196f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.SetResponse(response);
120082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string stored_response_sign = payload_state.GetResponseSignature();
121082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string expected_response_sign = "NumURLs = 0\n"
122082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Size = 0\n"
123082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Sha256 Hash = \n"
124082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Size = 0\n"
125082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Signature = \n"
126082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Is Delta Payload = 0\n"
127082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Max Failure Count Per Url = 0\n"
128082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Disable Payload Backoff = 0\n";
129082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_response_sign, stored_response_sign);
13053173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("", payload_state.GetCurrentUrl());
1312b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
132cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
133a573d6fd046dc203b96bff6df8e57b35319906fdDavid Zeuthen  EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
1346f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
1356f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
1366f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
1376f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
13853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  response.payload_urls.push_back("https://single.url.test");
1396f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.size = 123456789;
1406f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.hash = "hash";
1416f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.metadata_size = 58123;
1426f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.metadata_signature = "msign";
14319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
14419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
145dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
14619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
14719409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
14819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
14919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
15019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
15119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
15219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
15319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
15419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
15519409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
15619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
15719409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
15819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
15919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
16019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
16119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
162be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
163be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa      .Times(AtLeast(1));
1646f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
16519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1666f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.SetResponse(response);
167082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string stored_response_sign = payload_state.GetResponseSignature();
168082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string expected_response_sign = "NumURLs = 1\n"
16953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                                  "Candidate Url0 = https://single.url.test\n"
170082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Size = 123456789\n"
171082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Sha256 Hash = hash\n"
172082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Size = 58123\n"
173082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Signature = msign\n"
174082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Is Delta Payload = 0\n"
175082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Max Failure Count Per Url = 0\n"
176082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Disable Payload Backoff = 0\n";
177082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_response_sign, stored_response_sign);
17853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("https://single.url.test", payload_state.GetCurrentUrl());
1792b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
180cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
181a573d6fd046dc203b96bff6df8e57b35319906fdDavid Zeuthen  EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
1826f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
1836f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
1846f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
1856f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
1866f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.payload_urls.push_back("http://multiple.url.test");
1876f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.payload_urls.push_back("https://multiple.url.test");
1886f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.size = 523456789;
1896f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.hash = "rhash";
1906f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.metadata_size = 558123;
1916f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  response.metadata_signature = "metasign";
19219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
19319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
194dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
19519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
19619409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
19719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
19819409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
19919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
20019409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
20119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
20219409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
20319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
20419409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
20519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
20619409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
207be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
208be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa      .Times(AtLeast(1));
20953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
2106f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
21119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
2126f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.SetResponse(response);
213082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string stored_response_sign = payload_state.GetResponseSignature();
214082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  string expected_response_sign = "NumURLs = 2\n"
21553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                                  "Candidate Url0 = http://multiple.url.test\n"
21653173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan                                  "Candidate Url1 = https://multiple.url.test\n"
217082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Size = 523456789\n"
218082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Payload Sha256 Hash = rhash\n"
219082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Size = 558123\n"
220082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Metadata Signature = metasign\n"
221082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Is Delta Payload = 0\n"
222082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Max Failure Count Per Url = 0\n"
223082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                  "Disable Payload Backoff = 0\n";
224082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_response_sign, stored_response_sign);
22553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("http://multiple.url.test", payload_state.GetCurrentUrl());
2262b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
227cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
228a573d6fd046dc203b96bff6df8e57b35319906fdDavid Zeuthen  EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
2296f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
2306f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2316f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
2326f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
23319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
23419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
2356f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
2362b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
237dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
2382b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Payload attempt should start with 0 and then advance to 1.
23919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
24019409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
24119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
24219409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
24319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
2449a017f2c5ae41c04a7c7c15b5dbd08faadae7606David Zeuthen
245be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  // Reboots will be set
246be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1));
247be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
2482b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Url index should go from 0 to 1 twice.
24919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
25019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
2512b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
2522b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Failure count should be called each times url index is set, so that's
2532b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // 4 times for this test.
25419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
25519409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(4));
2562b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
25719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
2582b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
2592b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This does a SetResponse which causes all the states to be set to 0 for
2602b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // the first time.
26153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash1235", true, &payload_state, &response);
26253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
2636f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2646f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Verify that on the first error, the URL index advances to 1.
265a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
2666f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.UpdateFailed(error);
26753173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
2686f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2696f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Verify that on the next error, the URL index wraps around to 0.
2706f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.UpdateFailed(error);
27153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
2726f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2736f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Verify that on the next error, it again advances to 1.
2746f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.UpdateFailed(error);
27553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
276cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen
277cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  // Verify that we switched URLs three times
278cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
2796f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
2806f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2816f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay SrinivasanTEST(PayloadStateTest, NewResponseResetsPayloadState) {
2826f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  OmahaResponse response;
28319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
2846f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  PayloadState payload_state;
2852b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
28619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
2872b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
2882b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Set the first response.
28953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
290a573d6fd046dc203b96bff6df8e57b35319906fdDavid Zeuthen  EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
2916f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2926f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Advance the URL index to 1 by faking an error.
293a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
2946f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  payload_state.UpdateFailed(error);
29553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
296cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
2976f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
2986f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Now, slightly change the response and set it again.
29953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash8225", true, &payload_state, &response);
300a573d6fd046dc203b96bff6df8e57b35319906fdDavid Zeuthen  EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
3012b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3022b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Make sure the url index was reset to 0 because of the new response.
30353173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
3042b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
305cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
30619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
30719409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
30819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
30919409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
31019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
31119409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
31219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
31319409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
3142b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
3152b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3162b5a0f065187fd19179e3809148dbfc376ada7a0Jay SrinivasanTEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
3172b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  OmahaResponse response;
3182b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  PayloadState payload_state;
31919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
32019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int progress_bytes = 100;
32119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
32219409b74019d787100b768306e75ab3e5882898dJay Srinivasan
323dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
32419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
32519409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(2));
32619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
32719409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
32819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
32919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
33019409b74019d787100b768306e75ab3e5882898dJay Srinivasan
33119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
33219409b74019d787100b768306e75ab3e5882898dJay Srinivasan
33319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
33419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
33519409b74019d787100b768306e75ab3e5882898dJay Srinivasan
33619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
33719409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(7));
33819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
33919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(2));
34019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
34119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
34219409b74019d787100b768306e75ab3e5882898dJay Srinivasan
34319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
34419409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
34519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
34619409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
34719409b74019d787100b768306e75ab3e5882898dJay Srinivasan
34819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
34919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
35019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
35119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
35219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
35319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
35419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
35519409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
356be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
357be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa      .Times(AtLeast(1));
35819409b74019d787100b768306e75ab3e5882898dJay Srinivasan
35919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
3602b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
36153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash5873", true, &payload_state, &response);
362a573d6fd046dc203b96bff6df8e57b35319906fdDavid Zeuthen  EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
3632b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3642b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the URL index.
365a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
3662b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
36753173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
3682b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
369cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
3702b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3712b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the failure count only.
372a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
3732b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
37453173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
3752b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlFailureCount());
376cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
3772b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3782b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the failure count only.
379a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
3802b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
38153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
3822b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetUrlFailureCount());
383cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
3842b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3852b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the URL index as we've reached the
3862b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // max failure count and reset the failure count for the new URL index.
3872b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should also wrap around the URL index and thus cause the payload
3882b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // attempt number to be incremented.
389a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
3902b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
39153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
3922b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
393cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(2, payload_state.GetUrlSwitchCount());
394082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
3952b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
3962b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the URL index.
397a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodePayloadHashMismatchError);
3982b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
39953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
4002b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
401cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
402082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
4032b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4042b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should advance the URL index and payload attempt number due to
4052b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // wrap-around of URL index.
406a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMissingError);
4072b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
40853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
4092b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
410cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
411082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
4122b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4132b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This HTTP error code should only increase the failure count.
414a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(static_cast<ErrorCode>(
415a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen      kErrorCodeOmahaRequestHTTPResponseBase + 404));
4162b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
41753173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
4182b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlFailureCount());
419cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
420082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
4212b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4222b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // And that failure count should be reset when we download some bytes
4232b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // afterwards.
42419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(progress_bytes);
4252b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
42653173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
4272b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
428cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
429082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state.ShouldBackoffDownload());
4302b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4312b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Now, slightly change the response and set it again.
43253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash8532", true, &payload_state, &response);
433a573d6fd046dc203b96bff6df8e57b35319906fdDavid Zeuthen  EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
4346f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
4356f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  // Make sure the url index was reset to 0 because of the new response.
4362b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
43753173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
4382b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
439cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
440082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
4416f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
4426f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan
4432b5a0f065187fd19179e3809148dbfc376ada7a0Jay SrinivasanTEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDownload) {
4442b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  OmahaResponse response;
4452b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  PayloadState payload_state;
44619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
44719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
4482b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
449dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
45019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
45119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
45219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
45319409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
454082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
45519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
45619409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(2));
4572b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
45819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
45919409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
46019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
46119409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
4629a017f2c5ae41c04a7c7c15b5dbd08faadae7606David Zeuthen
46319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
4642b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
46553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
4662b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4672b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // This should just advance the payload attempt number;
4682b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
4692b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.DownloadComplete();
4702b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
47153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
4722b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
473cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
4742b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
4752b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4762b5a0f065187fd19179e3809148dbfc376ada7a0Jay SrinivasanTEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
4772b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  OmahaResponse response;
4782b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  PayloadState payload_state;
47919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
4802b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
48119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
48253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
4832b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4842b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Generate enough events to advance URL index, failure count and
4852b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // payload attempt number all to 1.
4862b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  payload_state.DownloadComplete();
487a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
488a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
4892b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
49053173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
4912b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlFailureCount());
492cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
4932b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
4942b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Now, simulate a corrupted url index on persisted store which gets
4952b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // loaded when update_engine restarts. Using a different prefs object
4962b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // so as to not bother accounting for the uninteresting calls above.
49719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state2;
49819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  NiceMock<PrefsMock>* prefs2 = mock_system_state2.mock_prefs();
49919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
50019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, GetInt64(_,_)).Times(AtLeast(1));
50119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
50219409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
50319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
50419409b74019d787100b768306e75ab3e5882898dJay Srinivasan      .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
50519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
50619409b74019d787100b768306e75ab3e5882898dJay Srinivasan    .Times(AtLeast(1));
507cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _))
508cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen    .Times(AtLeast(1));
5092b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
5102b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Note: This will be a different payload object, but the response should
5112b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // have the same hash as before so as to not trivially reset because the
5122b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // response was different. We want to specifically test that even if the
5132b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // response is same, we should reset the state if we find it corrupted.
51419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state2));
51553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
5162b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
5172b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // Make sure all counters get reset to 0 because of the corrupted URL index
5182b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  // we supplied above.
5192b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
52053173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
5212b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
522cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
5232b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan}
524082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
525082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay SrinivasanTEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
526082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  OmahaResponse response;
527082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  response.is_delta_payload = true;
528082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  PayloadState payload_state;
52919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
530082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
53119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
53253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
533082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
534082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Simulate a successful download and see that we're ready to download
535082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // again without any backoff as this is a delta payload.
536082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  payload_state.DownloadComplete();
537082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
538082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
539082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
540082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Simulate two failures (enough to cause payload backoff) and check
541082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // again that we're ready to re-download without any backoff as this is
542082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // a delta payload.
543a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
544a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
54553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
546082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
547082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
548082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan}
549082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
550082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasanstatic void CheckPayloadBackoffState(PayloadState* payload_state,
551082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                     int expected_attempt_number,
552082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan                                     TimeDelta expected_days) {
553082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  payload_state->DownloadComplete();
554082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(expected_attempt_number, payload_state->GetPayloadAttemptNumber());
555082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_TRUE(payload_state->ShouldBackoffDownload());
556082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
557082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
558082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
559082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
560082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
561082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_LT(expected_min_time.ToInternalValue(),
562082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan            backoff_expiry_time.ToInternalValue());
563082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_GT(expected_max_time.ToInternalValue(),
564082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan            backoff_expiry_time.ToInternalValue());
565082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan}
566082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
567082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay SrinivasanTEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
568082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  OmahaResponse response;
569082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  response.is_delta_payload = false;
570082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  PayloadState payload_state;
57119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
572082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
57319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
57453173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
575082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
576082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 1,  TimeDelta::FromDays(1));
577082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 2,  TimeDelta::FromDays(2));
578082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 3,  TimeDelta::FromDays(4));
579082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 4,  TimeDelta::FromDays(8));
580082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 5,  TimeDelta::FromDays(16));
581082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 6,  TimeDelta::FromDays(16));
582082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 7,  TimeDelta::FromDays(16));
583082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 8,  TimeDelta::FromDays(16));
584082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 9,  TimeDelta::FromDays(16));
585082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  CheckPayloadBackoffState(&payload_state, 10,  TimeDelta::FromDays(16));
586082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan}
587082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
588082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay SrinivasanTEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
589082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  OmahaResponse response;
590082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  response.disable_payload_backoff = true;
591082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  PayloadState payload_state;
59219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
593082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
59419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
59553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
596082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
597082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Simulate a successful download and see that we are ready to download
598082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // again without any backoff.
599082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  payload_state.DownloadComplete();
600082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
601082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
602082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
603082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // Test again, this time by simulating two errors that would cause
604082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // the payload attempt number to increment due to wrap around. And
605082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  // check that we are still ready to re-download without any backoff.
606a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
607a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
608082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
609082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan  EXPECT_FALSE(payload_state.ShouldBackoffDownload());
610082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan}
611082628869ed3ee3e173c08354d3fc40cdb7df2c0Jay Srinivasan
61219409b74019d787100b768306e75ab3e5882898dJay SrinivasanTEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
61319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  OmahaResponse response;
61419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  response.disable_payload_backoff = true;
61519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  PayloadState payload_state;
61619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
61719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int https_total = 0;
61819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int http_total = 0;
61919409b74019d787100b768306e75ab3e5882898dJay Srinivasan
62019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
62153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
622a573d6fd046dc203b96bff6df8e57b35319906fdDavid Zeuthen  EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
62319409b74019d787100b768306e75ab3e5882898dJay Srinivasan
624dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  // Simulate a previous attempt with in order to set an initial non-zero value
625dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  // for the total bytes downloaded for HTTP.
626dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  int prev_chunk = 323456789;
627dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  http_total += prev_chunk;
628dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  payload_state.DownloadProgress(prev_chunk);
629dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan
630dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  // Ensure that the initial values for HTTP reflect this attempt.
631dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_EQ(prev_chunk,
632dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
633dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_EQ(http_total,
634dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
635dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan
636dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  // Change the response hash so as to simulate a new response which will
637dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  // reset the current bytes downloaded, but not the total bytes downloaded.
63853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
639a573d6fd046dc203b96bff6df8e57b35319906fdDavid Zeuthen  EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
640dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan
641dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  // First, simulate successful download of a few bytes over HTTP.
64219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int first_chunk = 5000000;
64319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  http_total += first_chunk;
64419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(first_chunk);
64553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // Test that first all progress is made on HTTP and none on HTTPS.
64619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(first_chunk,
64719409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
64819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(http_total,
64919409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
65019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
65119409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
65219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(https_total,
65319409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
65419409b74019d787100b768306e75ab3e5882898dJay Srinivasan
65519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Simulate an error that'll cause the url index to point to https.
656a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
65719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.UpdateFailed(error);
65819409b74019d787100b768306e75ab3e5882898dJay Srinivasan
65953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // Test that no new progress is made on HTTP and new progress is on HTTPS.
66019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int second_chunk = 23456789;
66119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  https_total += second_chunk;
66219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(second_chunk);
66319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(first_chunk,
66419409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
66519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(http_total,
66619409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
66719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
66819409b74019d787100b768306e75ab3e5882898dJay Srinivasan              kDownloadSourceHttpsServer));
66919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(https_total,
67019409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
67119409b74019d787100b768306e75ab3e5882898dJay Srinivasan
67219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Simulate error to go back to http.
67319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.UpdateFailed(error);
67419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int third_chunk = 32345678;
67519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int http_chunk = first_chunk + third_chunk;
67619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  http_total += third_chunk;
67719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int https_chunk = second_chunk;
67819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(third_chunk);
67919409b74019d787100b768306e75ab3e5882898dJay Srinivasan
68019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
68119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(http_chunk,
68219409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
683dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_EQ(http_total,
68419409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
68519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
68619409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
68719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(https_total,
68819409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
68919409b74019d787100b768306e75ab3e5882898dJay Srinivasan
690dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
691dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan    .Times(AnyNumber());
69219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
69319409b74019d787100b768306e75ab3e5882898dJay Srinivasan      "Installer.SuccessfulMBsDownloadedFromHttpServer",
69419409b74019d787100b768306e75ab3e5882898dJay Srinivasan      http_chunk / kNumBytesInOneMiB, _, _, _));
69519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
69619409b74019d787100b768306e75ab3e5882898dJay Srinivasan      "Installer.TotalMBsDownloadedFromHttpServer",
69719409b74019d787100b768306e75ab3e5882898dJay Srinivasan      http_total / kNumBytesInOneMiB, _, _, _));
69819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
69919409b74019d787100b768306e75ab3e5882898dJay Srinivasan      "Installer.SuccessfulMBsDownloadedFromHttpsServer",
70019409b74019d787100b768306e75ab3e5882898dJay Srinivasan      https_chunk / kNumBytesInOneMiB, _, _, _));
70119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
70219409b74019d787100b768306e75ab3e5882898dJay Srinivasan      "Installer.TotalMBsDownloadedFromHttpsServer",
70319409b74019d787100b768306e75ab3e5882898dJay Srinivasan      https_total / kNumBytesInOneMiB, _, _, _));
704cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
705cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen      "Installer.UpdateURLSwitches",
706cc6f99600b3354cfe3a0d212241e1ee1dc3421b6David Zeuthen      2, _, _, _));
707674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
708674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen      "Installer.UpdateDurationMinutes",
709674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen      _, _, _, _));
710674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
711674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen      "Installer.UpdateDurationUptimeMinutes",
712674c318a84e4344fce0fdaee039784ed7900d188David Zeuthen      _, _, _, _));
713dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
714dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan      "Installer.DownloadSourcesUsed", 3, _, _, _));
715dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
716dbd9ea2ad94c3d1ac3e9fdac66c4b5ed11c7cf22Jay Srinivasan      "Installer.DownloadOverheadPercentage", 542, _, _, _));
7171c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
7181c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo      "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
71919409b74019d787100b768306e75ab3e5882898dJay Srinivasan
72019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.UpdateSucceeded();
72119409b74019d787100b768306e75ab3e5882898dJay Srinivasan
72219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Make sure the metrics are reset after a successful update.
72319409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
72419409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
72519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
72619409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
72719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
72819409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
72919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
73019409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
731a573d6fd046dc203b96bff6df8e57b35319906fdDavid Zeuthen  EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
73219409b74019d787100b768306e75ab3e5882898dJay Srinivasan}
73319409b74019d787100b768306e75ab3e5882898dJay Srinivasan
73419409b74019d787100b768306e75ab3e5882898dJay SrinivasanTEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
73519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  OmahaResponse response;
73619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  MockSystemState mock_system_state;
73719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  PayloadState payload_state;
73819409b74019d787100b768306e75ab3e5882898dJay Srinivasan
73919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
74019409b74019d787100b768306e75ab3e5882898dJay Srinivasan
74119409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Set the first response.
74253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
74319409b74019d787100b768306e75ab3e5882898dJay Srinivasan
74419409b74019d787100b768306e75ab3e5882898dJay Srinivasan  int num_bytes = 10000;
74519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.DownloadProgress(num_bytes);
74619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(num_bytes,
74719409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
74819409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(num_bytes,
74919409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
75019409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
75119409b74019d787100b768306e75ab3e5882898dJay Srinivasan                 kDownloadSourceHttpsServer));
75219409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
75319409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
75419409b74019d787100b768306e75ab3e5882898dJay Srinivasan
75519409b74019d787100b768306e75ab3e5882898dJay Srinivasan  payload_state.UpdateRestarted();
75619409b74019d787100b768306e75ab3e5882898dJay Srinivasan  // Make sure the current bytes downloaded is reset, but not the total bytes.
75719409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(0,
75819409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
75919409b74019d787100b768306e75ab3e5882898dJay Srinivasan  EXPECT_EQ(num_bytes,
76019409b74019d787100b768306e75ab3e5882898dJay Srinivasan            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
76119409b74019d787100b768306e75ab3e5882898dJay Srinivasan}
76219409b74019d787100b768306e75ab3e5882898dJay Srinivasan
763be45bef9e283188b00e7def8967f81843669a7f1Chris SosaTEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
764be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  MockSystemState mock_system_state;
765be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  PayloadState payload_state;
766be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
767be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
768be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
769be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
77019409b74019d787100b768306e75ab3e5882898dJay Srinivasan
771be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
772be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
773be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  payload_state.UpdateRestarted();
774be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_EQ(0, payload_state.GetNumReboots());
775be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
776be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(true));
777be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  payload_state.UpdateResumed();
778be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  // Num reboots should be incremented because system rebooted detected.
779be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_EQ(1, payload_state.GetNumReboots());
780be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
781be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(false));
782be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  payload_state.UpdateResumed();
783be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  // Num reboots should now be 1 as reboot was not detected.
784be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_EQ(1, payload_state.GetNumReboots());
785be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa
786be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  // Restart the update again to verify we set the num of reboots back to 0.
787be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  payload_state.UpdateRestarted();
788be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa  EXPECT_EQ(0, payload_state.GetNumReboots());
789be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa}
79019409b74019d787100b768306e75ab3e5882898dJay Srinivasan
791aa18e1641879f2df5993c2b02eb6f50d4443a649Chris SosaTEST(PayloadStateTest, RollbackVersion) {
792aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  MockSystemState mock_system_state;
793aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  PayloadState payload_state;
794aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa
795aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  NiceMock<PrefsMock>* mock_powerwash_safe_prefs =
796aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa      mock_system_state.mock_powerwash_safe_prefs();
797aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
798aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa
799aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  // Verify pre-conditions are good.
800aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  EXPECT_TRUE(payload_state.GetRollbackVersion().empty());
801aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa
802aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  // Mock out the os version and make sure it's blacklisted correctly.
803aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  string rollback_version = "2345.0.0";
804aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  OmahaRequestParams params(&mock_system_state);
805aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  params.Init(rollback_version, "", false);
806aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  mock_system_state.set_request_params(&params);
807aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa
808aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion,
809aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa                                                    rollback_version));
810aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  payload_state.Rollback();
811aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa
812aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa  EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
813aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa}
814aa18e1641879f2df5993c2b02eb6f50d4443a649Chris Sosa
815f413fe59759c73d6a5624c2158260b4302d01fe2David ZeuthenTEST(PayloadStateTest, DurationsAreCorrect) {
816f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  OmahaResponse response;
817f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  PayloadState payload_state;
818f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  MockSystemState mock_system_state;
819f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  FakeClock fake_clock;
820f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  Prefs prefs;
821f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  string temp_dir;
822f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
823f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Set the clock to a well-known time - 1 second on the wall-clock
824f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // and 2 seconds on the monotonic clock
825f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
826f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
827f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
828f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // We need persistent preferences for this test
829f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateDurationTests.XXXXXX",
830f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen                                       &temp_dir));
831f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  prefs.Init(FilePath(temp_dir));
832f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
833f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  mock_system_state.set_clock(&fake_clock);
834f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  mock_system_state.set_prefs(&prefs);
835f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
836f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
837f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Check that durations are correct for a successful update where
838f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // time has advanced 7 seconds on the wall clock and 4 seconds on
839f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // the monotonic clock.
84053173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
841f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
842f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
843f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  payload_state.UpdateSucceeded();
844f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
845f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
846f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
847f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Check that durations are reset when a new response comes in.
84853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash8594", true, &payload_state, &response);
849f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
850f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
851f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
852f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Advance time a bit (10 secs), simulate download progress and
853f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // check that durations are updated.
854f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
855f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
856f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  payload_state.DownloadProgress(10);
857f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
858f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
859f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
860f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Now simulate a reboot by resetting monotonic time (to 5000) and
861f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // creating a new PayloadState object and check that we load the
862f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // durations correctly (e.g. they are the same as before).
863f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
864f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  PayloadState payload_state2;
865f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
866f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
867f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),10000000);
868f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
869f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
870f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  // and check that the durations are increased accordingly.
871f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
872f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
873f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  payload_state2.UpdateSucceeded();
874f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
875f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),16000000);
876f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
877f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen  EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
878f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen}
879f413fe59759c73d6a5624c2158260b4302d01fe2David Zeuthen
880e4c58bf01b6ccc915c6b261007dbb75241ed69b8David ZeuthenTEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
881e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  OmahaResponse response;
882e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  PayloadState payload_state;
883e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  MockSystemState mock_system_state;
884e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  FakeClock fake_clock;
885e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  Prefs prefs;
886e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  string temp_dir;
887e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen
888e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  // Set the clock to a well-known time (t = 30 seconds).
889e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(
890e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen      30 * Time::kMicrosecondsPerSecond));
891e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen
892e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  // We need persistent preferences for this test
893e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  EXPECT_TRUE(utils::MakeTempDirectory(
894e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen      "/tmp/RebootAfterSuccessfulUpdateTest.XXXXXX", &temp_dir));
895e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  prefs.Init(FilePath(temp_dir));
896e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen
897e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  mock_system_state.set_clock(&fake_clock);
898e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  mock_system_state.set_prefs(&prefs);
899e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
900e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen
901e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  // Make the update succeed.
902e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
903e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  payload_state.UpdateSucceeded();
904e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen
905e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  // Check that the marker was written.
906e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  EXPECT_TRUE(prefs.Exists(kPrefsSystemUpdatedMarker));
907e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen
908e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  // Now simulate a reboot and set the wallclock time to a later point
909e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  // (t = 500 seconds). We do this by using a new PayloadState object
910e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  // and checking that it emits the right UMA metric with the right
911e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  // value.
912e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  fake_clock.SetWallclockTime(Time::FromInternalValue(
913e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen      500 * Time::kMicrosecondsPerSecond));
914e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  PayloadState payload_state2;
915e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
916e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen
917e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
918e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
919e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen      "Installer.TimeToRebootMinutes",
920e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen      7, _, _, _));
921e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen
922e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  payload_state2.UpdateEngineStarted();
923e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen
924e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  // Check that the marker was nuked.
925e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  EXPECT_FALSE(prefs.Exists(kPrefsSystemUpdatedMarker));
926e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen
927e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
928e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen}
929e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen
93053173b964f6f43c89dbaba41875fcadd7077b2eaJay SrinivasanTEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
93153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  OmahaResponse response;
93253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  MockSystemState mock_system_state;
93353173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  PayloadState payload_state;
93453173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
93553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // Pretend that this is an offical build so that the HTTP download policy
93653173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // is honored.
93753173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_CALL(mock_system_state, IsOfficialBuild())
93853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan      .WillRepeatedly(Return(true));
93953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
94053173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  policy::MockDevicePolicy disable_http_policy;
94153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_CALL(mock_system_state, device_policy())
94253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan      .WillRepeatedly(Return(&disable_http_policy));
94353173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
94453173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan      .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
94553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
94653173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
94753173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
94853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // Set the first response.
94953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash8433", false, &payload_state, &response);
95053173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
95153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // Check that we skip the HTTP URL and use only the HTTPS url.
95253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
95353173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
95453173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // Advance the URL index to 1 by faking an error.
95553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
95653173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  payload_state.UpdateFailed(error);
95753173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
95853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // Check that we still skip the HTTP URL and use only the HTTPS url.
95953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
96053173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
96153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
96253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // Now, slightly change the response and set it again.
96353173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash2399", false, &payload_state, &response);
96453173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
96553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // Check that we still skip the HTTP URL and use only the HTTPS url.
96653173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
96753173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
96853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // Now, pretend that the HTTP policy is turned on. We want to make sure
96953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // the new policy is honored.
97053173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  policy::MockDevicePolicy enable_http_policy;
97153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_CALL(mock_system_state, device_policy())
97253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan      .WillRepeatedly(Return(&enable_http_policy));
97353173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
97453173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan      .WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
97553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
97653173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // Now, set the same response using the same hash
97753173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // so that we can test that the state is reset not because of the
97853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // hash but because of the policy change which results in candidate url
97953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // list change.
98053173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  SetupPayloadStateWith2Urls("Hash2399", true, &payload_state, &response);
98153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
98253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // Check that we use the HTTP URL now and the failure count is reset.
98353173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
98453173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
98553173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
98653173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // Fake a failure and see if we're moving over to the HTTPS url and update
98753173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  // the URL switch count properly.
98853173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  payload_state.UpdateFailed(error);
98953173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
99053173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
99153173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan  EXPECT_EQ(0, payload_state.GetUrlFailureCount());
99253173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan}
99353173b964f6f43c89dbaba41875fcadd7077b2eaJay Srinivasan
9941c656c48886cf5054b526ed7e95b05903d7644dbAlex DeymoTEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
9951c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  OmahaResponse response;
9961c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  response.is_delta_payload = true;
9971c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  PayloadState payload_state;
9981c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  MockSystemState mock_system_state;
9991c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10001c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
10011c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
10021c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10031c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  // Simulate a successful download and update.
10041c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  payload_state.DownloadComplete();
10051c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10061c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
10071c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo      "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
10081c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  payload_state.UpdateSucceeded();
10091c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10101c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  // Mock the request to a request where the delta was disabled but Omaha sends
10111c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  // a delta anyway and test again.
10121c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  OmahaRequestParams params(&mock_system_state);
10131c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  params.set_delta_okay(false);
10141c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  mock_system_state.set_request_params(&params);
10151c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10161c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
10171c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
10181c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10191c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  payload_state.DownloadComplete();
10201c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10211c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
10221c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo      "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
10231c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  payload_state.UpdateSucceeded();
10241c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo}
10251c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10261c656c48886cf5054b526ed7e95b05903d7644dbAlex DeymoTEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
10271c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  OmahaResponse response;
10281c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  response.is_delta_payload = false;
10291c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  PayloadState payload_state;
10301c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  MockSystemState mock_system_state;
10311c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10321c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
10331c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
10341c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10351c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  // Mock the request to a request where the delta was disabled.
10361c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  OmahaRequestParams params(&mock_system_state);
10371c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  params.set_delta_okay(false);
10381c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  mock_system_state.set_request_params(&params);
10391c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10401c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  // Simulate a successful download and update.
10411c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  payload_state.DownloadComplete();
10421c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10431c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
10441c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo      "Installer.PayloadFormat", kPayloadTypeForcedFull, kNumPayloadTypes));
10451c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  payload_state.UpdateSucceeded();
10461c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo}
10471c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10481c656c48886cf5054b526ed7e95b05903d7644dbAlex DeymoTEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
10491c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  OmahaResponse response;
10501c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  response.is_delta_payload = false;
10511c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  PayloadState payload_state;
10521c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  MockSystemState mock_system_state;
10531c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10541c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
10551c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
10561c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10571c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  // Mock the request to a request where the delta was disabled.
10581c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  OmahaRequestParams params(&mock_system_state);
10591c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  params.set_delta_okay(true);
10601c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  mock_system_state.set_request_params(&params);
10611c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10621c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  // Simulate a successful download and update.
10631c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  payload_state.DownloadComplete();
10641c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10651c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
10661c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo      "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
10671c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo  payload_state.UpdateSucceeded();
10681c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo}
10691c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
10706f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan}
1071