blob: ffd1b27653e033cb3462d5971b10d4afb17c031b [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
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08007#include "base/stringprintf.h"
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08008#include "gmock/gmock.h"
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08009#include "gtest/gtest.h"
10
Jay Srinivasand29695d2013-04-08 15:08:05 -070011#include "update_engine/constants.h"
Jay Srinivasan19409b72013-04-12 19:23:36 -070012#include "update_engine/mock_system_state.h"
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080013#include "update_engine/omaha_request_action.h"
14#include "update_engine/payload_state.h"
15#include "update_engine/prefs_mock.h"
16#include "update_engine/test_utils.h"
17#include "update_engine/utils.h"
18
Jay Srinivasan08262882012-12-28 19:29:43 -080019using base::Time;
20using base::TimeDelta;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080021using std::string;
22using testing::_;
23using testing::NiceMock;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080024using testing::Return;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080025using testing::SetArgumentPointee;
David Zeuthen9a017f22013-04-11 16:10:26 -070026using testing::AtLeast;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080027
28namespace chromeos_update_engine {
29
Jay Srinivasan19409b72013-04-12 19:23:36 -070030const char* kCurrentBytesDownloadedFromHttps =
31 "current-bytes-downloaded-from-HttpsServer";
32const char* kTotalBytesDownloadedFromHttps =
33 "total-bytes-downloaded-from-HttpsServer";
34const char* kCurrentBytesDownloadedFromHttp =
35 "current-bytes-downloaded-from-HttpServer";
36const char* kTotalBytesDownloadedFromHttp =
37 "total-bytes-downloaded-from-HttpServer";
38
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080039static void SetupPayloadStateWith2Urls(string hash,
40 PayloadState* payload_state,
41 OmahaResponse* response) {
42 response->payload_urls.clear();
43 response->payload_urls.push_back("http://test");
44 response->payload_urls.push_back("https://test");
45 response->size = 523456789;
46 response->hash = hash;
47 response->metadata_size = 558123;
48 response->metadata_signature = "metasign";
49 response->max_failure_count_per_url = 3;
50 payload_state->SetResponse(*response);
Jay Srinivasan08262882012-12-28 19:29:43 -080051 string stored_response_sign = payload_state->GetResponseSignature();
52 string expected_response_sign = StringPrintf(
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080053 "NumURLs = 2\n"
54 "Url0 = http://test\n"
55 "Url1 = https://test\n"
56 "Payload Size = 523456789\n"
57 "Payload Sha256 Hash = %s\n"
58 "Metadata Size = 558123\n"
Jay Srinivasan08262882012-12-28 19:29:43 -080059 "Metadata Signature = metasign\n"
60 "Is Delta Payload = %d\n"
61 "Max Failure Count Per Url = %d\n"
62 "Disable Payload Backoff = %d\n",
63 hash.c_str(),
64 response->is_delta_payload,
65 response->max_failure_count_per_url,
66 response->disable_payload_backoff);
67 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080068}
69
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080070class PayloadStateTest : public ::testing::Test { };
71
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080072TEST(PayloadStateTest, DidYouAddANewActionExitCode) {
Jay Srinivasan1c0fe792013-03-28 16:45:25 -070073 if (kActionCodeUmaReportedMax != 43) {
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080074 LOG(ERROR) << "The following failure is intentional. If you added a new "
75 << "ActionExitCode enum value, make sure to add it to the "
76 << "PayloadState::UpdateFailed method and then update this test "
77 << "to the new value of kActionCodeUmaReportedMax, which is "
78 << kActionCodeUmaReportedMax;
79 EXPECT_FALSE("Please see the log line above");
80 }
81}
82
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080083TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
84 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -070085 MockSystemState mock_system_state;
86 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
87 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
88 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
89 .Times(AtLeast(1));
90 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
91 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
92 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
93 .Times(AtLeast(1));
94 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
95 .Times(AtLeast(1));
96 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
97 .Times(AtLeast(1));
98 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
99 .Times(AtLeast(1));
100 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
101 .Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800102 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700103 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800104 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800105 string stored_response_sign = payload_state.GetResponseSignature();
106 string expected_response_sign = "NumURLs = 0\n"
107 "Payload Size = 0\n"
108 "Payload Sha256 Hash = \n"
109 "Metadata Size = 0\n"
110 "Metadata Signature = \n"
111 "Is Delta Payload = 0\n"
112 "Max Failure Count Per Url = 0\n"
113 "Disable Payload Backoff = 0\n";
114 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800115 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800116 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800117}
118
119TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
120 OmahaResponse response;
121 response.payload_urls.push_back("http://single.url.test");
122 response.size = 123456789;
123 response.hash = "hash";
124 response.metadata_size = 58123;
125 response.metadata_signature = "msign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700126 MockSystemState mock_system_state;
127 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
128 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
129 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
130 .Times(AtLeast(1));
131 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
132 .Times(AtLeast(1));
133 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
134 .Times(AtLeast(1));
135 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
136 .Times(AtLeast(1));
137 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
138 .Times(AtLeast(1));
139 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
140 .Times(AtLeast(1));
141 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
142 .Times(AtLeast(1));
143 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
144 .Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800145 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700146 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800147 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800148 string stored_response_sign = payload_state.GetResponseSignature();
149 string expected_response_sign = "NumURLs = 1\n"
150 "Url0 = http://single.url.test\n"
151 "Payload Size = 123456789\n"
152 "Payload Sha256 Hash = hash\n"
153 "Metadata Size = 58123\n"
154 "Metadata Signature = msign\n"
155 "Is Delta Payload = 0\n"
156 "Max Failure Count Per Url = 0\n"
157 "Disable Payload Backoff = 0\n";
158 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800159 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800160 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800161}
162
163TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
164 OmahaResponse response;
165 response.payload_urls.push_back("http://multiple.url.test");
166 response.payload_urls.push_back("https://multiple.url.test");
167 response.size = 523456789;
168 response.hash = "rhash";
169 response.metadata_size = 558123;
170 response.metadata_signature = "metasign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700171 MockSystemState mock_system_state;
172 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
173 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
174 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
175 .Times(AtLeast(1));
176 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
177 .Times(AtLeast(1));
178 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
179 .Times(AtLeast(1));
180 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
181 .Times(AtLeast(1));
182 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
183 .Times(AtLeast(1));
184 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
185 .Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800186 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700187 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800188 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800189 string stored_response_sign = payload_state.GetResponseSignature();
190 string expected_response_sign = "NumURLs = 2\n"
191 "Url0 = http://multiple.url.test\n"
192 "Url1 = https://multiple.url.test\n"
193 "Payload Size = 523456789\n"
194 "Payload Sha256 Hash = rhash\n"
195 "Metadata Size = 558123\n"
196 "Metadata Signature = metasign\n"
197 "Is Delta Payload = 0\n"
198 "Max Failure Count Per Url = 0\n"
199 "Disable Payload Backoff = 0\n";
200 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800201 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800202 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800203}
204
205TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
206 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700207 MockSystemState mock_system_state;
208 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800209 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800210
Jay Srinivasan19409b72013-04-12 19:23:36 -0700211 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800212 // Payload attempt should start with 0 and then advance to 1.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700213 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
214 .Times(AtLeast(1));
215 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
216 .Times(AtLeast(1));
217 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
David Zeuthen9a017f22013-04-11 16:10:26 -0700218
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800219 // Url index should go from 0 to 1 twice.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700220 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
221 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800222
223 // Failure count should be called each times url index is set, so that's
224 // 4 times for this test.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700225 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
226 .Times(AtLeast(4));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800227
Jay Srinivasan19409b72013-04-12 19:23:36 -0700228 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800229
230 // This does a SetResponse which causes all the states to be set to 0 for
231 // the first time.
232 SetupPayloadStateWith2Urls("Hash1235", &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800233 EXPECT_EQ(0, payload_state.GetUrlIndex());
234
235 // Verify that on the first error, the URL index advances to 1.
236 ActionExitCode error = kActionCodeDownloadMetadataSignatureMismatch;
237 payload_state.UpdateFailed(error);
238 EXPECT_EQ(1, payload_state.GetUrlIndex());
239
240 // Verify that on the next error, the URL index wraps around to 0.
241 payload_state.UpdateFailed(error);
242 EXPECT_EQ(0, payload_state.GetUrlIndex());
243
244 // Verify that on the next error, it again advances to 1.
245 payload_state.UpdateFailed(error);
246 EXPECT_EQ(1, payload_state.GetUrlIndex());
247}
248
249TEST(PayloadStateTest, NewResponseResetsPayloadState) {
250 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700251 MockSystemState mock_system_state;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800252 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800253
Jay Srinivasan19409b72013-04-12 19:23:36 -0700254 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800255
256 // Set the first response.
257 SetupPayloadStateWith2Urls("Hash5823", &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800258
259 // Advance the URL index to 1 by faking an error.
260 ActionExitCode error = kActionCodeDownloadMetadataSignatureMismatch;
261 payload_state.UpdateFailed(error);
262 EXPECT_EQ(1, payload_state.GetUrlIndex());
263
264 // Now, slightly change the response and set it again.
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800265 SetupPayloadStateWith2Urls("Hash8225", &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800266
267 // Make sure the url index was reset to 0 because of the new response.
268 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800269 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700270 EXPECT_EQ(0,
271 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
272 EXPECT_EQ(0,
273 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
274 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
275 kDownloadSourceHttpsServer));
276 EXPECT_EQ(0,
277 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800278}
279
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800280TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
281 OmahaResponse response;
282 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700283 MockSystemState mock_system_state;
284 int progress_bytes = 100;
285 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800286
Jay Srinivasan19409b72013-04-12 19:23:36 -0700287 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
288 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
289 .Times(AtLeast(2));
290 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
291 .Times(AtLeast(1));
292 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
293 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800294
Jay Srinivasan19409b72013-04-12 19:23:36 -0700295 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
Jay Srinivasan08262882012-12-28 19:29:43 -0800296
Jay Srinivasan19409b72013-04-12 19:23:36 -0700297 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
298 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800299
Jay Srinivasan19409b72013-04-12 19:23:36 -0700300 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
301 .Times(AtLeast(7));
302 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
303 .Times(AtLeast(2));
304 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
305 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800306
Jay Srinivasan19409b72013-04-12 19:23:36 -0700307 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
308 .Times(AtLeast(1));
309 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
310 .Times(AtLeast(1));
David Zeuthen9a017f22013-04-11 16:10:26 -0700311
Jay Srinivasan19409b72013-04-12 19:23:36 -0700312 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
313 .Times(AtLeast(1));
314 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
315 .Times(AtLeast(1));
316 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
317 .Times(AtLeast(1));
318 EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
319 .Times(AtLeast(1));
320
321 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800322
323 SetupPayloadStateWith2Urls("Hash5873", &payload_state, &response);
324
325 // This should advance the URL index.
326 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
327 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
328 EXPECT_EQ(1, payload_state.GetUrlIndex());
329 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
330
331 // This should advance the failure count only.
332 payload_state.UpdateFailed(kActionCodeDownloadTransferError);
333 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
334 EXPECT_EQ(1, payload_state.GetUrlIndex());
335 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
336
337 // This should advance the failure count only.
338 payload_state.UpdateFailed(kActionCodeDownloadTransferError);
339 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
340 EXPECT_EQ(1, payload_state.GetUrlIndex());
341 EXPECT_EQ(2, payload_state.GetUrlFailureCount());
342
343 // This should advance the URL index as we've reached the
344 // max failure count and reset the failure count for the new URL index.
345 // This should also wrap around the URL index and thus cause the payload
346 // attempt number to be incremented.
347 payload_state.UpdateFailed(kActionCodeDownloadTransferError);
348 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
349 EXPECT_EQ(0, payload_state.GetUrlIndex());
350 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800351 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800352
353 // This should advance the URL index.
354 payload_state.UpdateFailed(kActionCodePayloadHashMismatchError);
355 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
356 EXPECT_EQ(1, payload_state.GetUrlIndex());
357 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800358 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800359
360 // This should advance the URL index and payload attempt number due to
361 // wrap-around of URL index.
362 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMissingError);
363 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
364 EXPECT_EQ(0, payload_state.GetUrlIndex());
365 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800366 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800367
368 // This HTTP error code should only increase the failure count.
369 payload_state.UpdateFailed(static_cast<ActionExitCode>(
370 kActionCodeOmahaRequestHTTPResponseBase + 404));
371 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
372 EXPECT_EQ(0, payload_state.GetUrlIndex());
373 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800374 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800375
376 // And that failure count should be reset when we download some bytes
377 // afterwards.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700378 payload_state.DownloadProgress(progress_bytes);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800379 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
380 EXPECT_EQ(0, payload_state.GetUrlIndex());
381 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800382 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800383
384 // Now, slightly change the response and set it again.
385 SetupPayloadStateWith2Urls("Hash8532", &payload_state, &response);
386
387 // Make sure the url index was reset to 0 because of the new response.
388 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
389 EXPECT_EQ(0, payload_state.GetUrlIndex());
390 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800391 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800392}
393
394TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDownload) {
395 OmahaResponse response;
396 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700397 MockSystemState mock_system_state;
398 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800399
Jay Srinivasan19409b72013-04-12 19:23:36 -0700400 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
401 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
402 .Times(AtLeast(1));
403 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
404 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800405
Jay Srinivasan19409b72013-04-12 19:23:36 -0700406 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
407 .Times(AtLeast(2));
Jay Srinivasan08262882012-12-28 19:29:43 -0800408
Jay Srinivasan19409b72013-04-12 19:23:36 -0700409 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
410 .Times(AtLeast(1));
411 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
412 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800413
Jay Srinivasan19409b72013-04-12 19:23:36 -0700414 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800415
416 SetupPayloadStateWith2Urls("Hash8593", &payload_state, &response);
417
418 // This should just advance the payload attempt number;
419 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
420 payload_state.DownloadComplete();
421 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
422 EXPECT_EQ(0, payload_state.GetUrlIndex());
423 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
424}
425
426TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
427 OmahaResponse response;
428 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700429 MockSystemState mock_system_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800430
Jay Srinivasan19409b72013-04-12 19:23:36 -0700431 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800432 SetupPayloadStateWith2Urls("Hash4427", &payload_state, &response);
433
434 // Generate enough events to advance URL index, failure count and
435 // payload attempt number all to 1.
436 payload_state.DownloadComplete();
437 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
438 payload_state.UpdateFailed(kActionCodeDownloadTransferError);
439 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
440 EXPECT_EQ(1, payload_state.GetUrlIndex());
441 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
442
443 // Now, simulate a corrupted url index on persisted store which gets
444 // loaded when update_engine restarts. Using a different prefs object
445 // so as to not bother accounting for the uninteresting calls above.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700446 MockSystemState mock_system_state2;
447 NiceMock<PrefsMock>* prefs2 = mock_system_state2.mock_prefs();
448 EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
449 EXPECT_CALL(*prefs2, GetInt64(_,_)).Times(AtLeast(1));
450 EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
451 .Times(AtLeast(1));
452 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
453 .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
454 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
455 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800456
457 // Note: This will be a different payload object, but the response should
458 // have the same hash as before so as to not trivially reset because the
459 // response was different. We want to specifically test that even if the
460 // response is same, we should reset the state if we find it corrupted.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700461 EXPECT_TRUE(payload_state.Initialize(&mock_system_state2));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800462 SetupPayloadStateWith2Urls("Hash4427", &payload_state, &response);
463
464 // Make sure all counters get reset to 0 because of the corrupted URL index
465 // we supplied above.
466 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
467 EXPECT_EQ(0, payload_state.GetUrlIndex());
468 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
469}
Jay Srinivasan08262882012-12-28 19:29:43 -0800470
471TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
472 OmahaResponse response;
473 response.is_delta_payload = true;
474 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700475 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800476
Jay Srinivasan19409b72013-04-12 19:23:36 -0700477 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan08262882012-12-28 19:29:43 -0800478 SetupPayloadStateWith2Urls("Hash6437", &payload_state, &response);
479
480 // Simulate a successful download and see that we're ready to download
481 // again without any backoff as this is a delta payload.
482 payload_state.DownloadComplete();
483 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
484 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
485
486 // Simulate two failures (enough to cause payload backoff) and check
487 // again that we're ready to re-download without any backoff as this is
488 // a delta payload.
489 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
490 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
491 EXPECT_EQ(0, payload_state.GetUrlIndex());
492 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
493 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
494}
495
496static void CheckPayloadBackoffState(PayloadState* payload_state,
497 int expected_attempt_number,
498 TimeDelta expected_days) {
499 payload_state->DownloadComplete();
500 EXPECT_EQ(expected_attempt_number, payload_state->GetPayloadAttemptNumber());
501 EXPECT_TRUE(payload_state->ShouldBackoffDownload());
502 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
503 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
504 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
505 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
506 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
507 EXPECT_LT(expected_min_time.ToInternalValue(),
508 backoff_expiry_time.ToInternalValue());
509 EXPECT_GT(expected_max_time.ToInternalValue(),
510 backoff_expiry_time.ToInternalValue());
511}
512
513TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
514 OmahaResponse response;
515 response.is_delta_payload = false;
516 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700517 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800518
Jay Srinivasan19409b72013-04-12 19:23:36 -0700519 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan08262882012-12-28 19:29:43 -0800520 SetupPayloadStateWith2Urls("Hash8939", &payload_state, &response);
521
522 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
523 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
524 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
525 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
526 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
527 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
528 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
529 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
530 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
531 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
532}
533
534TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
535 OmahaResponse response;
536 response.disable_payload_backoff = true;
537 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700538 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800539
Jay Srinivasan19409b72013-04-12 19:23:36 -0700540 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan08262882012-12-28 19:29:43 -0800541 SetupPayloadStateWith2Urls("Hash8939", &payload_state, &response);
542
543 // Simulate a successful download and see that we are ready to download
544 // again without any backoff.
545 payload_state.DownloadComplete();
546 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
547 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
548
549 // Test again, this time by simulating two errors that would cause
550 // the payload attempt number to increment due to wrap around. And
551 // check that we are still ready to re-download without any backoff.
552 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
553 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
554 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
555 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
556}
557
Jay Srinivasan19409b72013-04-12 19:23:36 -0700558TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
559 OmahaResponse response;
560 response.disable_payload_backoff = true;
561 PayloadState payload_state;
562 MockSystemState mock_system_state;
563 int https_total = 0;
564 int http_total = 0;
565
566 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
567 SetupPayloadStateWith2Urls("Hash3286", &payload_state, &response);
568
569 // Simulate a successful download and see that we are ready to download
570 // again without any backoff.
571 int first_chunk = 5000000;
572 http_total += first_chunk;
573 payload_state.DownloadProgress(first_chunk);
574 // Test that first all progress is made on HTTP and none on HTTPs.
575 EXPECT_EQ(first_chunk,
576 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
577 EXPECT_EQ(http_total,
578 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
579 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
580 kDownloadSourceHttpsServer));
581 EXPECT_EQ(https_total,
582 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
583
584 // Simulate an error that'll cause the url index to point to https.
585 ActionExitCode error = kActionCodeDownloadMetadataSignatureMismatch;
586 payload_state.UpdateFailed(error);
587
588 // Test that no new progress is made on HTTP and new progress is on HTTPs.
589 int second_chunk = 23456789;
590 https_total += second_chunk;
591 payload_state.DownloadProgress(second_chunk);
592 EXPECT_EQ(first_chunk,
593 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
594 EXPECT_EQ(http_total,
595 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
596 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
597 kDownloadSourceHttpsServer));
598 EXPECT_EQ(https_total,
599 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
600
601 // Simulate error to go back to http.
602 payload_state.UpdateFailed(error);
603 int third_chunk = 32345678;
604 int http_chunk = first_chunk + third_chunk;
605 http_total += third_chunk;
606 int https_chunk = second_chunk;
607 payload_state.DownloadProgress(third_chunk);
608
609 // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
610 EXPECT_EQ(http_chunk,
611 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
612 EXPECT_EQ(http_chunk,
613 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
614 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
615 kDownloadSourceHttpsServer));
616 EXPECT_EQ(https_total,
617 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
618
619 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
620 "Installer.SuccessfulMBsDownloadedFromHttpServer",
621 http_chunk / kNumBytesInOneMiB, _, _, _));
622 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
623 "Installer.TotalMBsDownloadedFromHttpServer",
624 http_total / kNumBytesInOneMiB, _, _, _));
625 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
626 "Installer.SuccessfulMBsDownloadedFromHttpsServer",
627 https_chunk / kNumBytesInOneMiB, _, _, _));
628 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
629 "Installer.TotalMBsDownloadedFromHttpsServer",
630 https_total / kNumBytesInOneMiB, _, _, _));
631
632 payload_state.UpdateSucceeded();
633
634 // Make sure the metrics are reset after a successful update.
635 EXPECT_EQ(0,
636 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
637 EXPECT_EQ(0,
638 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
639 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
640 kDownloadSourceHttpsServer));
641 EXPECT_EQ(0,
642 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
643}
644
645TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
646 OmahaResponse response;
647 MockSystemState mock_system_state;
648 PayloadState payload_state;
649
650 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
651
652 // Set the first response.
653 SetupPayloadStateWith2Urls("Hash5823", &payload_state, &response);
654
655 int num_bytes = 10000;
656 payload_state.DownloadProgress(num_bytes);
657 EXPECT_EQ(num_bytes,
658 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
659 EXPECT_EQ(num_bytes,
660 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
661 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
662 kDownloadSourceHttpsServer));
663 EXPECT_EQ(0,
664 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
665
666 payload_state.UpdateRestarted();
667 // Make sure the current bytes downloaded is reset, but not the total bytes.
668 EXPECT_EQ(0,
669 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
670 EXPECT_EQ(num_bytes,
671 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
672}
673
674
675
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800676}