blob: dcdcd11354c269a9de50ef4aed525589942d3b8a [file] [log] [blame]
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <glib.h>
6
Chris Sosabe45bef2013-04-09 18:25:12 -07007#include "base/file_path.h"
8#include "base/file_util.h"
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08009#include "base/stringprintf.h"
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080010#include "gmock/gmock.h"
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080011#include "gtest/gtest.h"
12
Jay Srinivasand29695d2013-04-08 15:08:05 -070013#include "update_engine/constants.h"
David Zeuthenf413fe52013-04-22 14:04:39 -070014#include "update_engine/fake_clock.h"
Jay Srinivasan19409b72013-04-12 19:23:36 -070015#include "update_engine/mock_system_state.h"
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080016#include "update_engine/omaha_request_action.h"
17#include "update_engine/payload_state.h"
David Zeuthenf413fe52013-04-22 14:04:39 -070018#include "update_engine/prefs.h"
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080019#include "update_engine/prefs_mock.h"
20#include "update_engine/test_utils.h"
21#include "update_engine/utils.h"
22
Jay Srinivasan08262882012-12-28 19:29:43 -080023using base::Time;
24using base::TimeDelta;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080025using std::string;
26using testing::_;
27using testing::NiceMock;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080028using testing::Return;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080029using testing::SetArgumentPointee;
David Zeuthen9a017f22013-04-11 16:10:26 -070030using testing::AtLeast;
Jay Srinivasandbd9ea22013-04-22 17:45:19 -070031using testing::AnyNumber;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080032
33namespace chromeos_update_engine {
34
Jay Srinivasan19409b72013-04-12 19:23:36 -070035const char* kCurrentBytesDownloadedFromHttps =
36 "current-bytes-downloaded-from-HttpsServer";
37const char* kTotalBytesDownloadedFromHttps =
38 "total-bytes-downloaded-from-HttpsServer";
39const char* kCurrentBytesDownloadedFromHttp =
40 "current-bytes-downloaded-from-HttpServer";
41const char* kTotalBytesDownloadedFromHttp =
42 "total-bytes-downloaded-from-HttpServer";
43
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080044static void SetupPayloadStateWith2Urls(string hash,
Jay Srinivasan53173b92013-05-17 17:13:01 -070045 bool http_enabled,
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080046 PayloadState* payload_state,
47 OmahaResponse* response) {
48 response->payload_urls.clear();
49 response->payload_urls.push_back("http://test");
50 response->payload_urls.push_back("https://test");
51 response->size = 523456789;
52 response->hash = hash;
53 response->metadata_size = 558123;
54 response->metadata_signature = "metasign";
55 response->max_failure_count_per_url = 3;
56 payload_state->SetResponse(*response);
Jay Srinivasan08262882012-12-28 19:29:43 -080057 string stored_response_sign = payload_state->GetResponseSignature();
Jay Srinivasan53173b92013-05-17 17:13:01 -070058
59 string expected_url_https_only =
60 "NumURLs = 1\n"
61 "Candidate Url0 = https://test\n";
62
63 string expected_urls_both =
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080064 "NumURLs = 2\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -070065 "Candidate Url0 = http://test\n"
66 "Candidate Url1 = https://test\n";
67
68 string expected_response_sign =
69 (http_enabled ? expected_urls_both : expected_url_https_only) +
70 StringPrintf("Payload Size = 523456789\n"
71 "Payload Sha256 Hash = %s\n"
72 "Metadata Size = 558123\n"
73 "Metadata Signature = metasign\n"
74 "Is Delta Payload = %d\n"
75 "Max Failure Count Per Url = %d\n"
76 "Disable Payload Backoff = %d\n",
77 hash.c_str(),
78 response->is_delta_payload,
79 response->max_failure_count_per_url,
80 response->disable_payload_backoff);
Jay Srinivasan08262882012-12-28 19:29:43 -080081 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080082}
83
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080084class PayloadStateTest : public ::testing::Test { };
85
David Zeuthena99981f2013-04-29 13:42:47 -070086TEST(PayloadStateTest, DidYouAddANewErrorCode) {
87 if (kErrorCodeUmaReportedMax != 43) {
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080088 LOG(ERROR) << "The following failure is intentional. If you added a new "
David Zeuthena99981f2013-04-29 13:42:47 -070089 << "ErrorCode enum value, make sure to add it to the "
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080090 << "PayloadState::UpdateFailed method and then update this test "
David Zeuthena99981f2013-04-29 13:42:47 -070091 << "to the new value of kErrorCodeUmaReportedMax, which is "
92 << kErrorCodeUmaReportedMax;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080093 EXPECT_FALSE("Please see the log line above");
94 }
95}
96
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080097TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
98 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -070099 MockSystemState mock_system_state;
100 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700101 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700102 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
103 .Times(AtLeast(1));
104 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
105 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
106 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
107 .Times(AtLeast(1));
108 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
109 .Times(AtLeast(1));
110 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
111 .Times(AtLeast(1));
112 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
113 .Times(AtLeast(1));
114 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
115 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700116 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800117 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700118 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800119 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800120 string stored_response_sign = payload_state.GetResponseSignature();
121 string expected_response_sign = "NumURLs = 0\n"
122 "Payload Size = 0\n"
123 "Payload Sha256 Hash = \n"
124 "Metadata Size = 0\n"
125 "Metadata Signature = \n"
126 "Is Delta Payload = 0\n"
127 "Max Failure Count Per Url = 0\n"
128 "Disable Payload Backoff = 0\n";
129 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700130 EXPECT_EQ("", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800131 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700132 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700133 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800134}
135
136TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
137 OmahaResponse response;
Jay Srinivasan53173b92013-05-17 17:13:01 -0700138 response.payload_urls.push_back("https://single.url.test");
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800139 response.size = 123456789;
140 response.hash = "hash";
141 response.metadata_size = 58123;
142 response.metadata_signature = "msign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700143 MockSystemState mock_system_state;
144 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700145 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700146 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
147 .Times(AtLeast(1));
148 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
149 .Times(AtLeast(1));
150 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
151 .Times(AtLeast(1));
152 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
153 .Times(AtLeast(1));
154 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
155 .Times(AtLeast(1));
156 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
157 .Times(AtLeast(1));
158 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
159 .Times(AtLeast(1));
160 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
161 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700162 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
163 .Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800164 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700165 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800166 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800167 string stored_response_sign = payload_state.GetResponseSignature();
168 string expected_response_sign = "NumURLs = 1\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -0700169 "Candidate Url0 = https://single.url.test\n"
Jay Srinivasan08262882012-12-28 19:29:43 -0800170 "Payload Size = 123456789\n"
171 "Payload Sha256 Hash = hash\n"
172 "Metadata Size = 58123\n"
173 "Metadata Signature = msign\n"
174 "Is Delta Payload = 0\n"
175 "Max Failure Count Per Url = 0\n"
176 "Disable Payload Backoff = 0\n";
177 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700178 EXPECT_EQ("https://single.url.test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800179 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700180 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700181 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800182}
183
184TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
185 OmahaResponse response;
186 response.payload_urls.push_back("http://multiple.url.test");
187 response.payload_urls.push_back("https://multiple.url.test");
188 response.size = 523456789;
189 response.hash = "rhash";
190 response.metadata_size = 558123;
191 response.metadata_signature = "metasign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700192 MockSystemState mock_system_state;
193 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700194 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700195 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
196 .Times(AtLeast(1));
197 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
198 .Times(AtLeast(1));
199 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
200 .Times(AtLeast(1));
201 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
202 .Times(AtLeast(1));
203 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
204 .Times(AtLeast(1));
205 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
206 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700207 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
208 .Times(AtLeast(1));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700209
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800210 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700211 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800212 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800213 string stored_response_sign = payload_state.GetResponseSignature();
214 string expected_response_sign = "NumURLs = 2\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -0700215 "Candidate Url0 = http://multiple.url.test\n"
216 "Candidate Url1 = https://multiple.url.test\n"
Jay Srinivasan08262882012-12-28 19:29:43 -0800217 "Payload Size = 523456789\n"
218 "Payload Sha256 Hash = rhash\n"
219 "Metadata Size = 558123\n"
220 "Metadata Signature = metasign\n"
221 "Is Delta Payload = 0\n"
222 "Max Failure Count Per Url = 0\n"
223 "Disable Payload Backoff = 0\n";
224 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700225 EXPECT_EQ("http://multiple.url.test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800226 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700227 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700228 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800229}
230
231TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
232 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700233 MockSystemState mock_system_state;
234 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800235 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800236
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700237 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800238 // Payload attempt should start with 0 and then advance to 1.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700239 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
240 .Times(AtLeast(1));
241 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
242 .Times(AtLeast(1));
243 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
David Zeuthen9a017f22013-04-11 16:10:26 -0700244
Chris Sosabe45bef2013-04-09 18:25:12 -0700245 // Reboots will be set
246 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1));
247
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800248 // Url index should go from 0 to 1 twice.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700249 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
250 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800251
252 // Failure count should be called each times url index is set, so that's
253 // 4 times for this test.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700254 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
255 .Times(AtLeast(4));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800256
Jay Srinivasan19409b72013-04-12 19:23:36 -0700257 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800258
259 // This does a SetResponse which causes all the states to be set to 0 for
260 // the first time.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700261 SetupPayloadStateWith2Urls("Hash1235", true, &payload_state, &response);
262 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800263
264 // Verify that on the first error, the URL index advances to 1.
David Zeuthena99981f2013-04-29 13:42:47 -0700265 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800266 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700267 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800268
269 // Verify that on the next error, the URL index wraps around to 0.
270 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700271 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800272
273 // Verify that on the next error, it again advances to 1.
274 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700275 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
David Zeuthencc6f9962013-04-18 11:57:24 -0700276
277 // Verify that we switched URLs three times
278 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800279}
280
281TEST(PayloadStateTest, NewResponseResetsPayloadState) {
282 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700283 MockSystemState mock_system_state;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800284 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800285
Jay Srinivasan19409b72013-04-12 19:23:36 -0700286 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800287
288 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700289 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700290 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800291
292 // Advance the URL index to 1 by faking an error.
David Zeuthena99981f2013-04-29 13:42:47 -0700293 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800294 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700295 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
David Zeuthencc6f9962013-04-18 11:57:24 -0700296 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800297
298 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700299 SetupPayloadStateWith2Urls("Hash8225", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700300 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800301
302 // Make sure the url index was reset to 0 because of the new response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700303 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800304 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700305 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700306 EXPECT_EQ(0,
307 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
308 EXPECT_EQ(0,
309 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
310 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
311 kDownloadSourceHttpsServer));
312 EXPECT_EQ(0,
313 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800314}
315
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800316TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
317 OmahaResponse response;
318 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700319 MockSystemState mock_system_state;
320 int progress_bytes = 100;
321 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800322
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700323 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700324 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
325 .Times(AtLeast(2));
326 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
327 .Times(AtLeast(1));
328 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
329 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800330
Jay Srinivasan19409b72013-04-12 19:23:36 -0700331 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
Jay Srinivasan08262882012-12-28 19:29:43 -0800332
Jay Srinivasan19409b72013-04-12 19:23:36 -0700333 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
334 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800335
Jay Srinivasan19409b72013-04-12 19:23:36 -0700336 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
337 .Times(AtLeast(7));
338 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
339 .Times(AtLeast(2));
340 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
341 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800342
Jay Srinivasan19409b72013-04-12 19:23:36 -0700343 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
344 .Times(AtLeast(1));
345 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
346 .Times(AtLeast(1));
David Zeuthen9a017f22013-04-11 16:10:26 -0700347
Jay Srinivasan19409b72013-04-12 19:23:36 -0700348 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
349 .Times(AtLeast(1));
350 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
351 .Times(AtLeast(1));
352 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
353 .Times(AtLeast(1));
354 EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
355 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700356 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
357 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700358
359 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800360
Jay Srinivasan53173b92013-05-17 17:13:01 -0700361 SetupPayloadStateWith2Urls("Hash5873", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700362 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800363
364 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700365 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800366 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700367 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800368 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700369 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800370
371 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700372 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800373 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700374 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800375 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700376 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800377
378 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700379 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800380 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700381 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800382 EXPECT_EQ(2, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700383 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800384
385 // This should advance the URL index as we've reached the
386 // max failure count and reset the failure count for the new URL index.
387 // This should also wrap around the URL index and thus cause the payload
388 // attempt number to be incremented.
David Zeuthena99981f2013-04-29 13:42:47 -0700389 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800390 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700391 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800392 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700393 EXPECT_EQ(2, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800394 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800395
396 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700397 payload_state.UpdateFailed(kErrorCodePayloadHashMismatchError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800398 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700399 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800400 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700401 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800402 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800403
404 // This should advance the URL index and payload attempt number due to
405 // wrap-around of URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700406 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMissingError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800407 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700408 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800409 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700410 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800411 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800412
413 // This HTTP error code should only increase the failure count.
David Zeuthena99981f2013-04-29 13:42:47 -0700414 payload_state.UpdateFailed(static_cast<ErrorCode>(
415 kErrorCodeOmahaRequestHTTPResponseBase + 404));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800416 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700417 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800418 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700419 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800420 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800421
422 // And that failure count should be reset when we download some bytes
423 // afterwards.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700424 payload_state.DownloadProgress(progress_bytes);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800425 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700426 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800427 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700428 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800429 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800430
431 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700432 SetupPayloadStateWith2Urls("Hash8532", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700433 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800434
435 // Make sure the url index was reset to 0 because of the new response.
436 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700437 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800438 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700439 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800440 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800441}
442
443TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDownload) {
444 OmahaResponse response;
445 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700446 MockSystemState mock_system_state;
447 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800448
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700449 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700450 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
451 .Times(AtLeast(1));
452 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
453 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800454
Jay Srinivasan19409b72013-04-12 19:23:36 -0700455 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
456 .Times(AtLeast(2));
Jay Srinivasan08262882012-12-28 19:29:43 -0800457
Jay Srinivasan19409b72013-04-12 19:23:36 -0700458 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
459 .Times(AtLeast(1));
460 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
461 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800462
Jay Srinivasan19409b72013-04-12 19:23:36 -0700463 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800464
Jay Srinivasan53173b92013-05-17 17:13:01 -0700465 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800466
467 // This should just advance the payload attempt number;
468 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
469 payload_state.DownloadComplete();
470 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700471 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800472 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700473 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800474}
475
476TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
477 OmahaResponse response;
478 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700479 MockSystemState mock_system_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800480
Jay Srinivasan19409b72013-04-12 19:23:36 -0700481 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700482 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800483
484 // Generate enough events to advance URL index, failure count and
485 // payload attempt number all to 1.
486 payload_state.DownloadComplete();
David Zeuthena99981f2013-04-29 13:42:47 -0700487 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
488 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800489 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700490 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800491 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700492 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800493
494 // Now, simulate a corrupted url index on persisted store which gets
495 // loaded when update_engine restarts. Using a different prefs object
496 // so as to not bother accounting for the uninteresting calls above.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700497 MockSystemState mock_system_state2;
498 NiceMock<PrefsMock>* prefs2 = mock_system_state2.mock_prefs();
499 EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
500 EXPECT_CALL(*prefs2, GetInt64(_,_)).Times(AtLeast(1));
501 EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
502 .Times(AtLeast(1));
503 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
504 .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
505 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
506 .Times(AtLeast(1));
David Zeuthencc6f9962013-04-18 11:57:24 -0700507 EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _))
508 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800509
510 // Note: This will be a different payload object, but the response should
511 // have the same hash as before so as to not trivially reset because the
512 // response was different. We want to specifically test that even if the
513 // response is same, we should reset the state if we find it corrupted.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700514 EXPECT_TRUE(payload_state.Initialize(&mock_system_state2));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700515 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800516
517 // Make sure all counters get reset to 0 because of the corrupted URL index
518 // we supplied above.
519 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700520 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800521 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700522 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800523}
Jay Srinivasan08262882012-12-28 19:29:43 -0800524
525TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
526 OmahaResponse response;
527 response.is_delta_payload = true;
528 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700529 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800530
Jay Srinivasan19409b72013-04-12 19:23:36 -0700531 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700532 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800533
534 // Simulate a successful download and see that we're ready to download
535 // again without any backoff as this is a delta payload.
536 payload_state.DownloadComplete();
537 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
538 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
539
540 // Simulate two failures (enough to cause payload backoff) and check
541 // again that we're ready to re-download without any backoff as this is
542 // a delta payload.
David Zeuthena99981f2013-04-29 13:42:47 -0700543 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
544 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700545 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan08262882012-12-28 19:29:43 -0800546 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
547 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
548}
549
550static void CheckPayloadBackoffState(PayloadState* payload_state,
551 int expected_attempt_number,
552 TimeDelta expected_days) {
553 payload_state->DownloadComplete();
554 EXPECT_EQ(expected_attempt_number, payload_state->GetPayloadAttemptNumber());
555 EXPECT_TRUE(payload_state->ShouldBackoffDownload());
556 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
557 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
558 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
559 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
560 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
561 EXPECT_LT(expected_min_time.ToInternalValue(),
562 backoff_expiry_time.ToInternalValue());
563 EXPECT_GT(expected_max_time.ToInternalValue(),
564 backoff_expiry_time.ToInternalValue());
565}
566
567TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
568 OmahaResponse response;
569 response.is_delta_payload = false;
570 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700571 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800572
Jay Srinivasan19409b72013-04-12 19:23:36 -0700573 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700574 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800575
576 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
577 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
578 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
579 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
580 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
581 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
582 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
583 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
584 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
585 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
586}
587
588TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
589 OmahaResponse response;
590 response.disable_payload_backoff = true;
591 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700592 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800593
Jay Srinivasan19409b72013-04-12 19:23:36 -0700594 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700595 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800596
597 // Simulate a successful download and see that we are ready to download
598 // again without any backoff.
599 payload_state.DownloadComplete();
600 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
601 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
602
603 // Test again, this time by simulating two errors that would cause
604 // the payload attempt number to increment due to wrap around. And
605 // check that we are still ready to re-download without any backoff.
David Zeuthena99981f2013-04-29 13:42:47 -0700606 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
607 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan08262882012-12-28 19:29:43 -0800608 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
609 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
610}
611
Jay Srinivasan19409b72013-04-12 19:23:36 -0700612TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
613 OmahaResponse response;
614 response.disable_payload_backoff = true;
615 PayloadState payload_state;
616 MockSystemState mock_system_state;
617 int https_total = 0;
618 int http_total = 0;
619
620 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700621 SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700622 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700623
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700624 // Simulate a previous attempt with in order to set an initial non-zero value
625 // for the total bytes downloaded for HTTP.
626 int prev_chunk = 323456789;
627 http_total += prev_chunk;
628 payload_state.DownloadProgress(prev_chunk);
629
630 // Ensure that the initial values for HTTP reflect this attempt.
631 EXPECT_EQ(prev_chunk,
632 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
633 EXPECT_EQ(http_total,
634 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
635
636 // Change the response hash so as to simulate a new response which will
637 // reset the current bytes downloaded, but not the total bytes downloaded.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700638 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700639 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700640
641 // First, simulate successful download of a few bytes over HTTP.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700642 int first_chunk = 5000000;
643 http_total += first_chunk;
644 payload_state.DownloadProgress(first_chunk);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700645 // Test that first all progress is made on HTTP and none on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700646 EXPECT_EQ(first_chunk,
647 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
648 EXPECT_EQ(http_total,
649 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
650 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
651 kDownloadSourceHttpsServer));
652 EXPECT_EQ(https_total,
653 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
654
655 // Simulate an error that'll cause the url index to point to https.
David Zeuthena99981f2013-04-29 13:42:47 -0700656 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700657 payload_state.UpdateFailed(error);
658
Jay Srinivasan53173b92013-05-17 17:13:01 -0700659 // Test that no new progress is made on HTTP and new progress is on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700660 int second_chunk = 23456789;
661 https_total += second_chunk;
662 payload_state.DownloadProgress(second_chunk);
663 EXPECT_EQ(first_chunk,
664 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
665 EXPECT_EQ(http_total,
666 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
667 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
668 kDownloadSourceHttpsServer));
669 EXPECT_EQ(https_total,
670 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
671
672 // Simulate error to go back to http.
673 payload_state.UpdateFailed(error);
674 int third_chunk = 32345678;
675 int http_chunk = first_chunk + third_chunk;
676 http_total += third_chunk;
677 int https_chunk = second_chunk;
678 payload_state.DownloadProgress(third_chunk);
679
680 // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
681 EXPECT_EQ(http_chunk,
682 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700683 EXPECT_EQ(http_total,
Jay Srinivasan19409b72013-04-12 19:23:36 -0700684 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
685 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
686 kDownloadSourceHttpsServer));
687 EXPECT_EQ(https_total,
688 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
689
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700690 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
691 .Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700692 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
693 "Installer.SuccessfulMBsDownloadedFromHttpServer",
694 http_chunk / kNumBytesInOneMiB, _, _, _));
695 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
696 "Installer.TotalMBsDownloadedFromHttpServer",
697 http_total / kNumBytesInOneMiB, _, _, _));
698 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
699 "Installer.SuccessfulMBsDownloadedFromHttpsServer",
700 https_chunk / kNumBytesInOneMiB, _, _, _));
701 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
702 "Installer.TotalMBsDownloadedFromHttpsServer",
703 https_total / kNumBytesInOneMiB, _, _, _));
David Zeuthencc6f9962013-04-18 11:57:24 -0700704 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
705 "Installer.UpdateURLSwitches",
706 2, _, _, _));
David Zeuthen674c3182013-04-18 14:05:20 -0700707 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
708 "Installer.UpdateDurationMinutes",
709 _, _, _, _));
710 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
711 "Installer.UpdateDurationUptimeMinutes",
712 _, _, _, _));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700713 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
714 "Installer.DownloadSourcesUsed", 3, _, _, _));
715 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
716 "Installer.DownloadOverheadPercentage", 542, _, _, _));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700717
718 payload_state.UpdateSucceeded();
719
720 // Make sure the metrics are reset after a successful update.
721 EXPECT_EQ(0,
722 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
723 EXPECT_EQ(0,
724 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
725 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
726 kDownloadSourceHttpsServer));
727 EXPECT_EQ(0,
728 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
David Zeuthena573d6f2013-06-14 16:13:36 -0700729 EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700730}
731
732TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
733 OmahaResponse response;
734 MockSystemState mock_system_state;
735 PayloadState payload_state;
736
737 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
738
739 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700740 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
Jay Srinivasan19409b72013-04-12 19:23:36 -0700741
742 int num_bytes = 10000;
743 payload_state.DownloadProgress(num_bytes);
744 EXPECT_EQ(num_bytes,
745 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
746 EXPECT_EQ(num_bytes,
747 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
748 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
749 kDownloadSourceHttpsServer));
750 EXPECT_EQ(0,
751 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
752
753 payload_state.UpdateRestarted();
754 // Make sure the current bytes downloaded is reset, but not the total bytes.
755 EXPECT_EQ(0,
756 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
757 EXPECT_EQ(num_bytes,
758 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
759}
760
Chris Sosabe45bef2013-04-09 18:25:12 -0700761TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
762 MockSystemState mock_system_state;
763 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700764
Chris Sosabe45bef2013-04-09 18:25:12 -0700765 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
766 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
767 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
768
769 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
770
771 payload_state.UpdateRestarted();
772 EXPECT_EQ(0, payload_state.GetNumReboots());
773
774 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(true));
775 payload_state.UpdateResumed();
776 // Num reboots should be incremented because system rebooted detected.
777 EXPECT_EQ(1, payload_state.GetNumReboots());
778
779 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(false));
780 payload_state.UpdateResumed();
781 // Num reboots should now be 1 as reboot was not detected.
782 EXPECT_EQ(1, payload_state.GetNumReboots());
783
784 // Restart the update again to verify we set the num of reboots back to 0.
785 payload_state.UpdateRestarted();
786 EXPECT_EQ(0, payload_state.GetNumReboots());
787}
Jay Srinivasan19409b72013-04-12 19:23:36 -0700788
Chris Sosaaa18e162013-06-20 13:20:30 -0700789TEST(PayloadStateTest, RollbackVersion) {
790 MockSystemState mock_system_state;
791 PayloadState payload_state;
792
793 NiceMock<PrefsMock>* mock_powerwash_safe_prefs =
794 mock_system_state.mock_powerwash_safe_prefs();
795 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
796
797 // Verify pre-conditions are good.
798 EXPECT_TRUE(payload_state.GetRollbackVersion().empty());
799
800 // Mock out the os version and make sure it's blacklisted correctly.
801 string rollback_version = "2345.0.0";
802 OmahaRequestParams params(&mock_system_state);
803 params.Init(rollback_version, "", false);
804 mock_system_state.set_request_params(&params);
805
806 EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion,
807 rollback_version));
808 payload_state.Rollback();
809
810 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
811}
812
David Zeuthenf413fe52013-04-22 14:04:39 -0700813TEST(PayloadStateTest, DurationsAreCorrect) {
814 OmahaResponse response;
815 PayloadState payload_state;
816 MockSystemState mock_system_state;
817 FakeClock fake_clock;
818 Prefs prefs;
819 string temp_dir;
820
821 // Set the clock to a well-known time - 1 second on the wall-clock
822 // and 2 seconds on the monotonic clock
823 fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
824 fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
825
826 // We need persistent preferences for this test
827 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateDurationTests.XXXXXX",
828 &temp_dir));
829 prefs.Init(FilePath(temp_dir));
830
831 mock_system_state.set_clock(&fake_clock);
832 mock_system_state.set_prefs(&prefs);
833 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
834
835 // Check that durations are correct for a successful update where
836 // time has advanced 7 seconds on the wall clock and 4 seconds on
837 // the monotonic clock.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700838 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -0700839 fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
840 fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
841 payload_state.UpdateSucceeded();
842 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
843 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
844
845 // Check that durations are reset when a new response comes in.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700846 SetupPayloadStateWith2Urls("Hash8594", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -0700847 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
848 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
849
850 // Advance time a bit (10 secs), simulate download progress and
851 // check that durations are updated.
852 fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
853 fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
854 payload_state.DownloadProgress(10);
855 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
856 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
857
858 // Now simulate a reboot by resetting monotonic time (to 5000) and
859 // creating a new PayloadState object and check that we load the
860 // durations correctly (e.g. they are the same as before).
861 fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
862 PayloadState payload_state2;
863 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
864 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
865 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),10000000);
866
867 // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
868 // and check that the durations are increased accordingly.
869 fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
870 fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
871 payload_state2.UpdateSucceeded();
872 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
873 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),16000000);
874
875 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
876}
877
David Zeuthene4c58bf2013-06-18 17:26:50 -0700878TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
879 OmahaResponse response;
880 PayloadState payload_state;
881 MockSystemState mock_system_state;
882 FakeClock fake_clock;
883 Prefs prefs;
884 string temp_dir;
885
886 // Set the clock to a well-known time (t = 30 seconds).
887 fake_clock.SetWallclockTime(Time::FromInternalValue(
888 30 * Time::kMicrosecondsPerSecond));
889
890 // We need persistent preferences for this test
891 EXPECT_TRUE(utils::MakeTempDirectory(
892 "/tmp/RebootAfterSuccessfulUpdateTest.XXXXXX", &temp_dir));
893 prefs.Init(FilePath(temp_dir));
894
895 mock_system_state.set_clock(&fake_clock);
896 mock_system_state.set_prefs(&prefs);
897 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
898
899 // Make the update succeed.
900 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
901 payload_state.UpdateSucceeded();
902
903 // Check that the marker was written.
904 EXPECT_TRUE(prefs.Exists(kPrefsSystemUpdatedMarker));
905
906 // Now simulate a reboot and set the wallclock time to a later point
907 // (t = 500 seconds). We do this by using a new PayloadState object
908 // and checking that it emits the right UMA metric with the right
909 // value.
910 fake_clock.SetWallclockTime(Time::FromInternalValue(
911 500 * Time::kMicrosecondsPerSecond));
912 PayloadState payload_state2;
913 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
914
915 // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
916 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
917 "Installer.TimeToRebootMinutes",
918 7, _, _, _));
919
920 payload_state2.UpdateEngineStarted();
921
922 // Check that the marker was nuked.
923 EXPECT_FALSE(prefs.Exists(kPrefsSystemUpdatedMarker));
924
925 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
926}
927
Jay Srinivasan53173b92013-05-17 17:13:01 -0700928TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
929 OmahaResponse response;
930 MockSystemState mock_system_state;
931 PayloadState payload_state;
932
933 // Pretend that this is an offical build so that the HTTP download policy
934 // is honored.
935 EXPECT_CALL(mock_system_state, IsOfficialBuild())
936 .WillRepeatedly(Return(true));
937
938 policy::MockDevicePolicy disable_http_policy;
939 EXPECT_CALL(mock_system_state, device_policy())
940 .WillRepeatedly(Return(&disable_http_policy));
941 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
942 .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
943
944 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
945
946 // Set the first response.
947 SetupPayloadStateWith2Urls("Hash8433", false, &payload_state, &response);
948
949 // Check that we skip the HTTP URL and use only the HTTPS url.
950 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
951
952 // Advance the URL index to 1 by faking an error.
953 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
954 payload_state.UpdateFailed(error);
955
956 // Check that we still skip the HTTP URL and use only the HTTPS url.
957 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
958 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
959
960 // Now, slightly change the response and set it again.
961 SetupPayloadStateWith2Urls("Hash2399", false, &payload_state, &response);
962
963 // Check that we still skip the HTTP URL and use only the HTTPS url.
964 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
965
966 // Now, pretend that the HTTP policy is turned on. We want to make sure
967 // the new policy is honored.
968 policy::MockDevicePolicy enable_http_policy;
969 EXPECT_CALL(mock_system_state, device_policy())
970 .WillRepeatedly(Return(&enable_http_policy));
971 EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
972 .WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
973
974 // Now, set the same response using the same hash
975 // so that we can test that the state is reset not because of the
976 // hash but because of the policy change which results in candidate url
977 // list change.
978 SetupPayloadStateWith2Urls("Hash2399", true, &payload_state, &response);
979
980 // Check that we use the HTTP URL now and the failure count is reset.
981 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
982 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
983
984 // Fake a failure and see if we're moving over to the HTTPS url and update
985 // the URL switch count properly.
986 payload_state.UpdateFailed(error);
987 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
988 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
989 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
990}
991
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800992}