blob: 440d8b79e835525c042205fa75ca7c2924858c99 [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,
45 PayloadState* payload_state,
46 OmahaResponse* response) {
47 response->payload_urls.clear();
48 response->payload_urls.push_back("http://test");
49 response->payload_urls.push_back("https://test");
50 response->size = 523456789;
51 response->hash = hash;
52 response->metadata_size = 558123;
53 response->metadata_signature = "metasign";
54 response->max_failure_count_per_url = 3;
55 payload_state->SetResponse(*response);
Jay Srinivasan08262882012-12-28 19:29:43 -080056 string stored_response_sign = payload_state->GetResponseSignature();
57 string expected_response_sign = StringPrintf(
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080058 "NumURLs = 2\n"
59 "Url0 = http://test\n"
60 "Url1 = https://test\n"
61 "Payload Size = 523456789\n"
62 "Payload Sha256 Hash = %s\n"
63 "Metadata Size = 558123\n"
Jay Srinivasan08262882012-12-28 19:29:43 -080064 "Metadata Signature = metasign\n"
65 "Is Delta Payload = %d\n"
66 "Max Failure Count Per Url = %d\n"
67 "Disable Payload Backoff = %d\n",
68 hash.c_str(),
69 response->is_delta_payload,
70 response->max_failure_count_per_url,
71 response->disable_payload_backoff);
72 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080073}
74
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080075class PayloadStateTest : public ::testing::Test { };
76
David Zeuthena99981f2013-04-29 13:42:47 -070077TEST(PayloadStateTest, DidYouAddANewErrorCode) {
78 if (kErrorCodeUmaReportedMax != 43) {
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080079 LOG(ERROR) << "The following failure is intentional. If you added a new "
David Zeuthena99981f2013-04-29 13:42:47 -070080 << "ErrorCode enum value, make sure to add it to the "
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080081 << "PayloadState::UpdateFailed method and then update this test "
David Zeuthena99981f2013-04-29 13:42:47 -070082 << "to the new value of kErrorCodeUmaReportedMax, which is "
83 << kErrorCodeUmaReportedMax;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080084 EXPECT_FALSE("Please see the log line above");
85 }
86}
87
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080088TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
89 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -070090 MockSystemState mock_system_state;
91 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -070092 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -070093 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
94 .Times(AtLeast(1));
95 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
96 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
97 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
98 .Times(AtLeast(1));
99 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
100 .Times(AtLeast(1));
101 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
102 .Times(AtLeast(1));
103 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
104 .Times(AtLeast(1));
105 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
106 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700107 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800108 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700109 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800110 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800111 string stored_response_sign = payload_state.GetResponseSignature();
112 string expected_response_sign = "NumURLs = 0\n"
113 "Payload Size = 0\n"
114 "Payload Sha256 Hash = \n"
115 "Metadata Size = 0\n"
116 "Metadata Signature = \n"
117 "Is Delta Payload = 0\n"
118 "Max Failure Count Per Url = 0\n"
119 "Disable Payload Backoff = 0\n";
120 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800121 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800122 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700123 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800124}
125
126TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
127 OmahaResponse response;
128 response.payload_urls.push_back("http://single.url.test");
129 response.size = 123456789;
130 response.hash = "hash";
131 response.metadata_size = 58123;
132 response.metadata_signature = "msign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700133 MockSystemState mock_system_state;
134 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700135 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700136 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
137 .Times(AtLeast(1));
138 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
139 .Times(AtLeast(1));
140 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
141 .Times(AtLeast(1));
142 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
143 .Times(AtLeast(1));
144 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
145 .Times(AtLeast(1));
146 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
147 .Times(AtLeast(1));
148 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
149 .Times(AtLeast(1));
150 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
151 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700152 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
153 .Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800154 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700155 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800156 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800157 string stored_response_sign = payload_state.GetResponseSignature();
158 string expected_response_sign = "NumURLs = 1\n"
159 "Url0 = http://single.url.test\n"
160 "Payload Size = 123456789\n"
161 "Payload Sha256 Hash = hash\n"
162 "Metadata Size = 58123\n"
163 "Metadata Signature = msign\n"
164 "Is Delta Payload = 0\n"
165 "Max Failure Count Per Url = 0\n"
166 "Disable Payload Backoff = 0\n";
167 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800168 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800169 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700170 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800171}
172
173TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
174 OmahaResponse response;
175 response.payload_urls.push_back("http://multiple.url.test");
176 response.payload_urls.push_back("https://multiple.url.test");
177 response.size = 523456789;
178 response.hash = "rhash";
179 response.metadata_size = 558123;
180 response.metadata_signature = "metasign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700181 MockSystemState mock_system_state;
182 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700183 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700184 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
185 .Times(AtLeast(1));
186 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
187 .Times(AtLeast(1));
188 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
189 .Times(AtLeast(1));
190 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
191 .Times(AtLeast(1));
192 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
193 .Times(AtLeast(1));
194 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
195 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700196 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
197 .Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800198 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700199 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800200 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800201 string stored_response_sign = payload_state.GetResponseSignature();
202 string expected_response_sign = "NumURLs = 2\n"
203 "Url0 = http://multiple.url.test\n"
204 "Url1 = https://multiple.url.test\n"
205 "Payload Size = 523456789\n"
206 "Payload Sha256 Hash = rhash\n"
207 "Metadata Size = 558123\n"
208 "Metadata Signature = metasign\n"
209 "Is Delta Payload = 0\n"
210 "Max Failure Count Per Url = 0\n"
211 "Disable Payload Backoff = 0\n";
212 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800213 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800214 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700215 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800216}
217
218TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
219 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700220 MockSystemState mock_system_state;
221 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800222 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800223
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700224 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800225 // Payload attempt should start with 0 and then advance to 1.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700226 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
227 .Times(AtLeast(1));
228 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
229 .Times(AtLeast(1));
230 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
David Zeuthen9a017f22013-04-11 16:10:26 -0700231
Chris Sosabe45bef2013-04-09 18:25:12 -0700232 // Reboots will be set
233 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1));
234
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800235 // Url index should go from 0 to 1 twice.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700236 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
237 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800238
239 // Failure count should be called each times url index is set, so that's
240 // 4 times for this test.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700241 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
242 .Times(AtLeast(4));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800243
Jay Srinivasan19409b72013-04-12 19:23:36 -0700244 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800245
246 // This does a SetResponse which causes all the states to be set to 0 for
247 // the first time.
248 SetupPayloadStateWith2Urls("Hash1235", &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800249 EXPECT_EQ(0, payload_state.GetUrlIndex());
250
251 // Verify that on the first error, the URL index advances to 1.
David Zeuthena99981f2013-04-29 13:42:47 -0700252 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800253 payload_state.UpdateFailed(error);
254 EXPECT_EQ(1, payload_state.GetUrlIndex());
255
256 // Verify that on the next error, the URL index wraps around to 0.
257 payload_state.UpdateFailed(error);
258 EXPECT_EQ(0, payload_state.GetUrlIndex());
259
260 // Verify that on the next error, it again advances to 1.
261 payload_state.UpdateFailed(error);
262 EXPECT_EQ(1, payload_state.GetUrlIndex());
David Zeuthencc6f9962013-04-18 11:57:24 -0700263
264 // Verify that we switched URLs three times
265 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800266}
267
268TEST(PayloadStateTest, NewResponseResetsPayloadState) {
269 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700270 MockSystemState mock_system_state;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800271 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800272
Jay Srinivasan19409b72013-04-12 19:23:36 -0700273 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800274
275 // Set the first response.
276 SetupPayloadStateWith2Urls("Hash5823", &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800277
278 // Advance the URL index to 1 by faking an error.
David Zeuthena99981f2013-04-29 13:42:47 -0700279 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800280 payload_state.UpdateFailed(error);
281 EXPECT_EQ(1, payload_state.GetUrlIndex());
David Zeuthencc6f9962013-04-18 11:57:24 -0700282 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800283
284 // Now, slightly change the response and set it again.
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800285 SetupPayloadStateWith2Urls("Hash8225", &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800286
287 // Make sure the url index was reset to 0 because of the new response.
288 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800289 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700290 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700291 EXPECT_EQ(0,
292 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
293 EXPECT_EQ(0,
294 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
295 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
296 kDownloadSourceHttpsServer));
297 EXPECT_EQ(0,
298 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800299}
300
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800301TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
302 OmahaResponse response;
303 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700304 MockSystemState mock_system_state;
305 int progress_bytes = 100;
306 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800307
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700308 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700309 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
310 .Times(AtLeast(2));
311 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
312 .Times(AtLeast(1));
313 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
314 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800315
Jay Srinivasan19409b72013-04-12 19:23:36 -0700316 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
Jay Srinivasan08262882012-12-28 19:29:43 -0800317
Jay Srinivasan19409b72013-04-12 19:23:36 -0700318 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
319 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800320
Jay Srinivasan19409b72013-04-12 19:23:36 -0700321 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
322 .Times(AtLeast(7));
323 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
324 .Times(AtLeast(2));
325 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
326 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800327
Jay Srinivasan19409b72013-04-12 19:23:36 -0700328 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
329 .Times(AtLeast(1));
330 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
331 .Times(AtLeast(1));
David Zeuthen9a017f22013-04-11 16:10:26 -0700332
Jay Srinivasan19409b72013-04-12 19:23:36 -0700333 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
334 .Times(AtLeast(1));
335 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
336 .Times(AtLeast(1));
337 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
338 .Times(AtLeast(1));
339 EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
340 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700341 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
342 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700343
344 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800345
346 SetupPayloadStateWith2Urls("Hash5873", &payload_state, &response);
347
348 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700349 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800350 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
351 EXPECT_EQ(1, payload_state.GetUrlIndex());
352 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700353 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800354
355 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700356 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800357 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
358 EXPECT_EQ(1, payload_state.GetUrlIndex());
359 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700360 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800361
362 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700363 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800364 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
365 EXPECT_EQ(1, payload_state.GetUrlIndex());
366 EXPECT_EQ(2, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700367 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800368
369 // This should advance the URL index as we've reached the
370 // max failure count and reset the failure count for the new URL index.
371 // This should also wrap around the URL index and thus cause the payload
372 // attempt number to be incremented.
David Zeuthena99981f2013-04-29 13:42:47 -0700373 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800374 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
375 EXPECT_EQ(0, payload_state.GetUrlIndex());
376 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700377 EXPECT_EQ(2, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800378 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800379
380 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700381 payload_state.UpdateFailed(kErrorCodePayloadHashMismatchError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800382 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
383 EXPECT_EQ(1, payload_state.GetUrlIndex());
384 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700385 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800386 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800387
388 // This should advance the URL index and payload attempt number due to
389 // wrap-around of URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700390 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMissingError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800391 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
392 EXPECT_EQ(0, payload_state.GetUrlIndex());
393 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700394 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800395 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800396
397 // This HTTP error code should only increase the failure count.
David Zeuthena99981f2013-04-29 13:42:47 -0700398 payload_state.UpdateFailed(static_cast<ErrorCode>(
399 kErrorCodeOmahaRequestHTTPResponseBase + 404));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800400 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
401 EXPECT_EQ(0, payload_state.GetUrlIndex());
402 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700403 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800404 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800405
406 // And that failure count should be reset when we download some bytes
407 // afterwards.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700408 payload_state.DownloadProgress(progress_bytes);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800409 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
410 EXPECT_EQ(0, payload_state.GetUrlIndex());
411 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700412 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800413 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800414
415 // Now, slightly change the response and set it again.
416 SetupPayloadStateWith2Urls("Hash8532", &payload_state, &response);
417
418 // Make sure the url index was reset to 0 because of the new response.
419 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
420 EXPECT_EQ(0, payload_state.GetUrlIndex());
421 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700422 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800423 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800424}
425
426TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDownload) {
427 OmahaResponse response;
428 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700429 MockSystemState mock_system_state;
430 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800431
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700432 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700433 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
434 .Times(AtLeast(1));
435 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
436 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800437
Jay Srinivasan19409b72013-04-12 19:23:36 -0700438 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
439 .Times(AtLeast(2));
Jay Srinivasan08262882012-12-28 19:29:43 -0800440
Jay Srinivasan19409b72013-04-12 19:23:36 -0700441 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
442 .Times(AtLeast(1));
443 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
444 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800445
Jay Srinivasan19409b72013-04-12 19:23:36 -0700446 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800447
448 SetupPayloadStateWith2Urls("Hash8593", &payload_state, &response);
449
450 // This should just advance the payload attempt number;
451 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
452 payload_state.DownloadComplete();
453 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
454 EXPECT_EQ(0, payload_state.GetUrlIndex());
455 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700456 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800457}
458
459TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
460 OmahaResponse response;
461 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700462 MockSystemState mock_system_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800463
Jay Srinivasan19409b72013-04-12 19:23:36 -0700464 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800465 SetupPayloadStateWith2Urls("Hash4427", &payload_state, &response);
466
467 // Generate enough events to advance URL index, failure count and
468 // payload attempt number all to 1.
469 payload_state.DownloadComplete();
David Zeuthena99981f2013-04-29 13:42:47 -0700470 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
471 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800472 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
473 EXPECT_EQ(1, payload_state.GetUrlIndex());
474 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700475 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800476
477 // Now, simulate a corrupted url index on persisted store which gets
478 // loaded when update_engine restarts. Using a different prefs object
479 // so as to not bother accounting for the uninteresting calls above.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700480 MockSystemState mock_system_state2;
481 NiceMock<PrefsMock>* prefs2 = mock_system_state2.mock_prefs();
482 EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
483 EXPECT_CALL(*prefs2, GetInt64(_,_)).Times(AtLeast(1));
484 EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
485 .Times(AtLeast(1));
486 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
487 .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
488 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
489 .Times(AtLeast(1));
David Zeuthencc6f9962013-04-18 11:57:24 -0700490 EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _))
491 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800492
493 // Note: This will be a different payload object, but the response should
494 // have the same hash as before so as to not trivially reset because the
495 // response was different. We want to specifically test that even if the
496 // response is same, we should reset the state if we find it corrupted.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700497 EXPECT_TRUE(payload_state.Initialize(&mock_system_state2));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800498 SetupPayloadStateWith2Urls("Hash4427", &payload_state, &response);
499
500 // Make sure all counters get reset to 0 because of the corrupted URL index
501 // we supplied above.
502 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
503 EXPECT_EQ(0, payload_state.GetUrlIndex());
504 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700505 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800506}
Jay Srinivasan08262882012-12-28 19:29:43 -0800507
508TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
509 OmahaResponse response;
510 response.is_delta_payload = true;
511 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700512 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800513
Jay Srinivasan19409b72013-04-12 19:23:36 -0700514 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan08262882012-12-28 19:29:43 -0800515 SetupPayloadStateWith2Urls("Hash6437", &payload_state, &response);
516
517 // Simulate a successful download and see that we're ready to download
518 // again without any backoff as this is a delta payload.
519 payload_state.DownloadComplete();
520 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
521 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
522
523 // Simulate two failures (enough to cause payload backoff) and check
524 // again that we're ready to re-download without any backoff as this is
525 // a delta payload.
David Zeuthena99981f2013-04-29 13:42:47 -0700526 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
527 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan08262882012-12-28 19:29:43 -0800528 EXPECT_EQ(0, payload_state.GetUrlIndex());
529 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
530 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
531}
532
533static void CheckPayloadBackoffState(PayloadState* payload_state,
534 int expected_attempt_number,
535 TimeDelta expected_days) {
536 payload_state->DownloadComplete();
537 EXPECT_EQ(expected_attempt_number, payload_state->GetPayloadAttemptNumber());
538 EXPECT_TRUE(payload_state->ShouldBackoffDownload());
539 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
540 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
541 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
542 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
543 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
544 EXPECT_LT(expected_min_time.ToInternalValue(),
545 backoff_expiry_time.ToInternalValue());
546 EXPECT_GT(expected_max_time.ToInternalValue(),
547 backoff_expiry_time.ToInternalValue());
548}
549
550TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
551 OmahaResponse response;
552 response.is_delta_payload = false;
553 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700554 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800555
Jay Srinivasan19409b72013-04-12 19:23:36 -0700556 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan08262882012-12-28 19:29:43 -0800557 SetupPayloadStateWith2Urls("Hash8939", &payload_state, &response);
558
559 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
560 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
561 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
562 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
563 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
564 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
565 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
566 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
567 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
568 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
569}
570
571TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
572 OmahaResponse response;
573 response.disable_payload_backoff = true;
574 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700575 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800576
Jay Srinivasan19409b72013-04-12 19:23:36 -0700577 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan08262882012-12-28 19:29:43 -0800578 SetupPayloadStateWith2Urls("Hash8939", &payload_state, &response);
579
580 // Simulate a successful download and see that we are ready to download
581 // again without any backoff.
582 payload_state.DownloadComplete();
583 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
584 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
585
586 // Test again, this time by simulating two errors that would cause
587 // the payload attempt number to increment due to wrap around. And
588 // check that we are still ready to re-download without any backoff.
David Zeuthena99981f2013-04-29 13:42:47 -0700589 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
590 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan08262882012-12-28 19:29:43 -0800591 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
592 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
593}
594
Jay Srinivasan19409b72013-04-12 19:23:36 -0700595TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
596 OmahaResponse response;
597 response.disable_payload_backoff = true;
598 PayloadState payload_state;
599 MockSystemState mock_system_state;
600 int https_total = 0;
601 int http_total = 0;
602
603 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
604 SetupPayloadStateWith2Urls("Hash3286", &payload_state, &response);
605
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700606 // Simulate a previous attempt with in order to set an initial non-zero value
607 // for the total bytes downloaded for HTTP.
608 int prev_chunk = 323456789;
609 http_total += prev_chunk;
610 payload_state.DownloadProgress(prev_chunk);
611
612 // Ensure that the initial values for HTTP reflect this attempt.
613 EXPECT_EQ(prev_chunk,
614 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
615 EXPECT_EQ(http_total,
616 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
617
618 // Change the response hash so as to simulate a new response which will
619 // reset the current bytes downloaded, but not the total bytes downloaded.
620 SetupPayloadStateWith2Urls("Hash9904", &payload_state, &response);
621
622 // First, simulate successful download of a few bytes over HTTP.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700623 int first_chunk = 5000000;
624 http_total += first_chunk;
625 payload_state.DownloadProgress(first_chunk);
626 // Test that first all progress is made on HTTP and none on HTTPs.
627 EXPECT_EQ(first_chunk,
628 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
629 EXPECT_EQ(http_total,
630 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
631 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
632 kDownloadSourceHttpsServer));
633 EXPECT_EQ(https_total,
634 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
635
636 // Simulate an error that'll cause the url index to point to https.
David Zeuthena99981f2013-04-29 13:42:47 -0700637 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700638 payload_state.UpdateFailed(error);
639
640 // Test that no new progress is made on HTTP and new progress is on HTTPs.
641 int second_chunk = 23456789;
642 https_total += second_chunk;
643 payload_state.DownloadProgress(second_chunk);
644 EXPECT_EQ(first_chunk,
645 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
646 EXPECT_EQ(http_total,
647 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
648 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
649 kDownloadSourceHttpsServer));
650 EXPECT_EQ(https_total,
651 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
652
653 // Simulate error to go back to http.
654 payload_state.UpdateFailed(error);
655 int third_chunk = 32345678;
656 int http_chunk = first_chunk + third_chunk;
657 http_total += third_chunk;
658 int https_chunk = second_chunk;
659 payload_state.DownloadProgress(third_chunk);
660
661 // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
662 EXPECT_EQ(http_chunk,
663 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700664 EXPECT_EQ(http_total,
Jay Srinivasan19409b72013-04-12 19:23:36 -0700665 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
666 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
667 kDownloadSourceHttpsServer));
668 EXPECT_EQ(https_total,
669 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
670
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700671 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
672 .Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700673 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
674 "Installer.SuccessfulMBsDownloadedFromHttpServer",
675 http_chunk / kNumBytesInOneMiB, _, _, _));
676 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
677 "Installer.TotalMBsDownloadedFromHttpServer",
678 http_total / kNumBytesInOneMiB, _, _, _));
679 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
680 "Installer.SuccessfulMBsDownloadedFromHttpsServer",
681 https_chunk / kNumBytesInOneMiB, _, _, _));
682 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
683 "Installer.TotalMBsDownloadedFromHttpsServer",
684 https_total / kNumBytesInOneMiB, _, _, _));
David Zeuthencc6f9962013-04-18 11:57:24 -0700685 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
686 "Installer.UpdateURLSwitches",
687 2, _, _, _));
David Zeuthen674c3182013-04-18 14:05:20 -0700688 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
689 "Installer.UpdateDurationMinutes",
690 _, _, _, _));
691 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
692 "Installer.UpdateDurationUptimeMinutes",
693 _, _, _, _));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700694 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
695 "Installer.DownloadSourcesUsed", 3, _, _, _));
696 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
697 "Installer.DownloadOverheadPercentage", 542, _, _, _));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700698
699 payload_state.UpdateSucceeded();
700
701 // Make sure the metrics are reset after a successful update.
702 EXPECT_EQ(0,
703 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
704 EXPECT_EQ(0,
705 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
706 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
707 kDownloadSourceHttpsServer));
708 EXPECT_EQ(0,
709 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
710}
711
712TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
713 OmahaResponse response;
714 MockSystemState mock_system_state;
715 PayloadState payload_state;
716
717 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
718
719 // Set the first response.
720 SetupPayloadStateWith2Urls("Hash5823", &payload_state, &response);
721
722 int num_bytes = 10000;
723 payload_state.DownloadProgress(num_bytes);
724 EXPECT_EQ(num_bytes,
725 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
726 EXPECT_EQ(num_bytes,
727 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
728 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
729 kDownloadSourceHttpsServer));
730 EXPECT_EQ(0,
731 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
732
733 payload_state.UpdateRestarted();
734 // Make sure the current bytes downloaded is reset, but not the total bytes.
735 EXPECT_EQ(0,
736 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
737 EXPECT_EQ(num_bytes,
738 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
739}
740
Chris Sosabe45bef2013-04-09 18:25:12 -0700741TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
742 MockSystemState mock_system_state;
743 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700744
Chris Sosabe45bef2013-04-09 18:25:12 -0700745 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
746 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
747 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
748
749 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
750
751 payload_state.UpdateRestarted();
752 EXPECT_EQ(0, payload_state.GetNumReboots());
753
754 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(true));
755 payload_state.UpdateResumed();
756 // Num reboots should be incremented because system rebooted detected.
757 EXPECT_EQ(1, payload_state.GetNumReboots());
758
759 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(false));
760 payload_state.UpdateResumed();
761 // Num reboots should now be 1 as reboot was not detected.
762 EXPECT_EQ(1, payload_state.GetNumReboots());
763
764 // Restart the update again to verify we set the num of reboots back to 0.
765 payload_state.UpdateRestarted();
766 EXPECT_EQ(0, payload_state.GetNumReboots());
767}
Jay Srinivasan19409b72013-04-12 19:23:36 -0700768
David Zeuthenf413fe52013-04-22 14:04:39 -0700769TEST(PayloadStateTest, DurationsAreCorrect) {
770 OmahaResponse response;
771 PayloadState payload_state;
772 MockSystemState mock_system_state;
773 FakeClock fake_clock;
774 Prefs prefs;
775 string temp_dir;
776
777 // Set the clock to a well-known time - 1 second on the wall-clock
778 // and 2 seconds on the monotonic clock
779 fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
780 fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
781
782 // We need persistent preferences for this test
783 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateDurationTests.XXXXXX",
784 &temp_dir));
785 prefs.Init(FilePath(temp_dir));
786
787 mock_system_state.set_clock(&fake_clock);
788 mock_system_state.set_prefs(&prefs);
789 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
790
791 // Check that durations are correct for a successful update where
792 // time has advanced 7 seconds on the wall clock and 4 seconds on
793 // the monotonic clock.
794 SetupPayloadStateWith2Urls("Hash8593", &payload_state, &response);
795 fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
796 fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
797 payload_state.UpdateSucceeded();
798 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
799 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
800
801 // Check that durations are reset when a new response comes in.
802 SetupPayloadStateWith2Urls("Hash8594", &payload_state, &response);
803 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
804 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
805
806 // Advance time a bit (10 secs), simulate download progress and
807 // check that durations are updated.
808 fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
809 fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
810 payload_state.DownloadProgress(10);
811 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
812 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
813
814 // Now simulate a reboot by resetting monotonic time (to 5000) and
815 // creating a new PayloadState object and check that we load the
816 // durations correctly (e.g. they are the same as before).
817 fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
818 PayloadState payload_state2;
819 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
820 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
821 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),10000000);
822
823 // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
824 // and check that the durations are increased accordingly.
825 fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
826 fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
827 payload_state2.UpdateSucceeded();
828 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
829 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),16000000);
830
831 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
832}
833
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800834}