blob: 62de02b14fc97122a897022afa4653940214b594 [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 Srinivasan6f6ea002012-12-14 11:26:28 -080012#include "update_engine/omaha_request_action.h"
13#include "update_engine/payload_state.h"
14#include "update_engine/prefs_mock.h"
15#include "update_engine/test_utils.h"
16#include "update_engine/utils.h"
17
Jay Srinivasan08262882012-12-28 19:29:43 -080018using base::Time;
19using base::TimeDelta;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080020using std::string;
21using testing::_;
22using testing::NiceMock;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080023using testing::Return;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080024using testing::SetArgumentPointee;
David Zeuthen9a017f22013-04-11 16:10:26 -070025using testing::AtLeast;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080026
27namespace chromeos_update_engine {
28
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080029static void SetupPayloadStateWith2Urls(string hash,
30 PayloadState* payload_state,
31 OmahaResponse* response) {
32 response->payload_urls.clear();
33 response->payload_urls.push_back("http://test");
34 response->payload_urls.push_back("https://test");
35 response->size = 523456789;
36 response->hash = hash;
37 response->metadata_size = 558123;
38 response->metadata_signature = "metasign";
39 response->max_failure_count_per_url = 3;
40 payload_state->SetResponse(*response);
Jay Srinivasan08262882012-12-28 19:29:43 -080041 string stored_response_sign = payload_state->GetResponseSignature();
42 string expected_response_sign = StringPrintf(
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080043 "NumURLs = 2\n"
44 "Url0 = http://test\n"
45 "Url1 = https://test\n"
46 "Payload Size = 523456789\n"
47 "Payload Sha256 Hash = %s\n"
48 "Metadata Size = 558123\n"
Jay Srinivasan08262882012-12-28 19:29:43 -080049 "Metadata Signature = metasign\n"
50 "Is Delta Payload = %d\n"
51 "Max Failure Count Per Url = %d\n"
52 "Disable Payload Backoff = %d\n",
53 hash.c_str(),
54 response->is_delta_payload,
55 response->max_failure_count_per_url,
56 response->disable_payload_backoff);
57 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080058}
59
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080060class PayloadStateTest : public ::testing::Test { };
61
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080062TEST(PayloadStateTest, DidYouAddANewActionExitCode) {
Jay Srinivasan1c0fe792013-03-28 16:45:25 -070063 if (kActionCodeUmaReportedMax != 43) {
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080064 LOG(ERROR) << "The following failure is intentional. If you added a new "
65 << "ActionExitCode enum value, make sure to add it to the "
66 << "PayloadState::UpdateFailed method and then update this test "
67 << "to the new value of kActionCodeUmaReportedMax, which is "
68 << kActionCodeUmaReportedMax;
69 EXPECT_FALSE("Please see the log line above");
70 }
71}
72
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080073TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
74 OmahaResponse response;
75 NiceMock<PrefsMock> prefs;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080076 EXPECT_CALL(prefs, SetInt64(kPrefsPayloadAttemptNumber, 0));
Jay Srinivasan08262882012-12-28 19:29:43 -080077 EXPECT_CALL(prefs, SetInt64(kPrefsBackoffExpiryTime, 0));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080078 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlIndex, 0));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080079 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0));
David Zeuthen9a017f22013-04-11 16:10:26 -070080 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateTimestampStart, _)).Times(AtLeast(1));
81 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateDurationUptime, _)).Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080082 PayloadState payload_state;
83 EXPECT_TRUE(payload_state.Initialize(&prefs));
84 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -080085 string stored_response_sign = payload_state.GetResponseSignature();
86 string expected_response_sign = "NumURLs = 0\n"
87 "Payload Size = 0\n"
88 "Payload Sha256 Hash = \n"
89 "Metadata Size = 0\n"
90 "Metadata Signature = \n"
91 "Is Delta Payload = 0\n"
92 "Max Failure Count Per Url = 0\n"
93 "Disable Payload Backoff = 0\n";
94 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080095 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080096 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080097}
98
99TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
100 OmahaResponse response;
101 response.payload_urls.push_back("http://single.url.test");
102 response.size = 123456789;
103 response.hash = "hash";
104 response.metadata_size = 58123;
105 response.metadata_signature = "msign";
106 NiceMock<PrefsMock> prefs;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800107 EXPECT_CALL(prefs, SetInt64(kPrefsPayloadAttemptNumber, 0));
Jay Srinivasan08262882012-12-28 19:29:43 -0800108 EXPECT_CALL(prefs, SetInt64(kPrefsBackoffExpiryTime, 0));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800109 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlIndex, 0));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800110 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0));
David Zeuthen9a017f22013-04-11 16:10:26 -0700111 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateTimestampStart, _)).Times(AtLeast(1));
112 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateDurationUptime, _)).Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800113 PayloadState payload_state;
114 EXPECT_TRUE(payload_state.Initialize(&prefs));
115 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800116 string stored_response_sign = payload_state.GetResponseSignature();
117 string expected_response_sign = "NumURLs = 1\n"
118 "Url0 = http://single.url.test\n"
119 "Payload Size = 123456789\n"
120 "Payload Sha256 Hash = hash\n"
121 "Metadata Size = 58123\n"
122 "Metadata Signature = msign\n"
123 "Is Delta Payload = 0\n"
124 "Max Failure Count Per Url = 0\n"
125 "Disable Payload Backoff = 0\n";
126 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800127 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800128 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800129}
130
131TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
132 OmahaResponse response;
133 response.payload_urls.push_back("http://multiple.url.test");
134 response.payload_urls.push_back("https://multiple.url.test");
135 response.size = 523456789;
136 response.hash = "rhash";
137 response.metadata_size = 558123;
138 response.metadata_signature = "metasign";
139 NiceMock<PrefsMock> prefs;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800140 EXPECT_CALL(prefs, SetInt64(kPrefsPayloadAttemptNumber, 0));
Jay Srinivasan08262882012-12-28 19:29:43 -0800141 EXPECT_CALL(prefs, SetInt64(kPrefsBackoffExpiryTime, 0));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800142 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlIndex, 0));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800143 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0));
David Zeuthen9a017f22013-04-11 16:10:26 -0700144 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateTimestampStart, _)).Times(AtLeast(1));
145 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateDurationUptime, _)).Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800146 PayloadState payload_state;
147 EXPECT_TRUE(payload_state.Initialize(&prefs));
148 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800149 string stored_response_sign = payload_state.GetResponseSignature();
150 string expected_response_sign = "NumURLs = 2\n"
151 "Url0 = http://multiple.url.test\n"
152 "Url1 = https://multiple.url.test\n"
153 "Payload Size = 523456789\n"
154 "Payload Sha256 Hash = rhash\n"
155 "Metadata Size = 558123\n"
156 "Metadata Signature = metasign\n"
157 "Is Delta Payload = 0\n"
158 "Max Failure Count Per Url = 0\n"
159 "Disable Payload Backoff = 0\n";
160 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800161 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800162 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800163}
164
165TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
166 OmahaResponse response;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800167 NiceMock<PrefsMock> prefs;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800168 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800169
170 // Payload attempt should start with 0 and then advance to 1.
171 EXPECT_CALL(prefs, SetInt64(kPrefsPayloadAttemptNumber, 0)).Times(1);
172 EXPECT_CALL(prefs, SetInt64(kPrefsPayloadAttemptNumber, 1)).Times(1);
Jay Srinivasan08262882012-12-28 19:29:43 -0800173 EXPECT_CALL(prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(2);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800174
David Zeuthen9a017f22013-04-11 16:10:26 -0700175 // Durations will be set
176 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateTimestampStart, _)).Times(AtLeast(1));
177 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateDurationUptime, _)).Times(AtLeast(1));
178
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800179 // Url index should go from 0 to 1 twice.
180 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(2);
181 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(2);
182
183 // Failure count should be called each times url index is set, so that's
184 // 4 times for this test.
185 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0)).Times(4);
186
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800187 EXPECT_TRUE(payload_state.Initialize(&prefs));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800188
189 // This does a SetResponse which causes all the states to be set to 0 for
190 // the first time.
191 SetupPayloadStateWith2Urls("Hash1235", &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800192 EXPECT_EQ(0, payload_state.GetUrlIndex());
193
194 // Verify that on the first error, the URL index advances to 1.
195 ActionExitCode error = kActionCodeDownloadMetadataSignatureMismatch;
196 payload_state.UpdateFailed(error);
197 EXPECT_EQ(1, payload_state.GetUrlIndex());
198
199 // Verify that on the next error, the URL index wraps around to 0.
200 payload_state.UpdateFailed(error);
201 EXPECT_EQ(0, payload_state.GetUrlIndex());
202
203 // Verify that on the next error, it again advances to 1.
204 payload_state.UpdateFailed(error);
205 EXPECT_EQ(1, payload_state.GetUrlIndex());
206}
207
208TEST(PayloadStateTest, NewResponseResetsPayloadState) {
209 OmahaResponse response;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800210 NiceMock<PrefsMock> prefs;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800211 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800212
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800213 EXPECT_TRUE(payload_state.Initialize(&prefs));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800214
215 // Set the first response.
216 SetupPayloadStateWith2Urls("Hash5823", &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800217
218 // Advance the URL index to 1 by faking an error.
219 ActionExitCode error = kActionCodeDownloadMetadataSignatureMismatch;
220 payload_state.UpdateFailed(error);
221 EXPECT_EQ(1, payload_state.GetUrlIndex());
222
223 // Now, slightly change the response and set it again.
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800224 SetupPayloadStateWith2Urls("Hash8225", &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800225
226 // Make sure the url index was reset to 0 because of the new response.
227 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800228 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800229}
230
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800231TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
232 OmahaResponse response;
233 PayloadState payload_state;
234 NiceMock<PrefsMock> prefs;
235
236 EXPECT_CALL(prefs, SetInt64(kPrefsPayloadAttemptNumber, 0)).Times(2);
237 EXPECT_CALL(prefs, SetInt64(kPrefsPayloadAttemptNumber, 1)).Times(1);
238 EXPECT_CALL(prefs, SetInt64(kPrefsPayloadAttemptNumber, 2)).Times(1);
239
Jay Srinivasan08262882012-12-28 19:29:43 -0800240 EXPECT_CALL(prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(4);
241
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800242 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(4);
243 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(2);
244
245 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0)).Times(7);
246 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1)).Times(2);
247 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2)).Times(1);
248
David Zeuthen9a017f22013-04-11 16:10:26 -0700249 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateTimestampStart, _)).Times(AtLeast(1));
250 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateDurationUptime, _)).Times(AtLeast(1));
251
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800252 EXPECT_TRUE(payload_state.Initialize(&prefs));
253
254 SetupPayloadStateWith2Urls("Hash5873", &payload_state, &response);
255
256 // This should advance the URL index.
257 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
258 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
259 EXPECT_EQ(1, payload_state.GetUrlIndex());
260 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
261
262 // This should advance the failure count only.
263 payload_state.UpdateFailed(kActionCodeDownloadTransferError);
264 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
265 EXPECT_EQ(1, payload_state.GetUrlIndex());
266 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
267
268 // This should advance the failure count only.
269 payload_state.UpdateFailed(kActionCodeDownloadTransferError);
270 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
271 EXPECT_EQ(1, payload_state.GetUrlIndex());
272 EXPECT_EQ(2, payload_state.GetUrlFailureCount());
273
274 // This should advance the URL index as we've reached the
275 // max failure count and reset the failure count for the new URL index.
276 // This should also wrap around the URL index and thus cause the payload
277 // attempt number to be incremented.
278 payload_state.UpdateFailed(kActionCodeDownloadTransferError);
279 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
280 EXPECT_EQ(0, payload_state.GetUrlIndex());
281 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800282 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800283
284 // This should advance the URL index.
285 payload_state.UpdateFailed(kActionCodePayloadHashMismatchError);
286 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
287 EXPECT_EQ(1, payload_state.GetUrlIndex());
288 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800289 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800290
291 // This should advance the URL index and payload attempt number due to
292 // wrap-around of URL index.
293 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMissingError);
294 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
295 EXPECT_EQ(0, payload_state.GetUrlIndex());
296 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800297 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800298
299 // This HTTP error code should only increase the failure count.
300 payload_state.UpdateFailed(static_cast<ActionExitCode>(
301 kActionCodeOmahaRequestHTTPResponseBase + 404));
302 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
303 EXPECT_EQ(0, payload_state.GetUrlIndex());
304 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800305 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800306
307 // And that failure count should be reset when we download some bytes
308 // afterwards.
309 payload_state.DownloadProgress(100);
310 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
311 EXPECT_EQ(0, payload_state.GetUrlIndex());
312 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800313 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800314
315 // Now, slightly change the response and set it again.
316 SetupPayloadStateWith2Urls("Hash8532", &payload_state, &response);
317
318 // Make sure the url index was reset to 0 because of the new response.
319 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
320 EXPECT_EQ(0, payload_state.GetUrlIndex());
321 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800322 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800323}
324
325TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDownload) {
326 OmahaResponse response;
327 PayloadState payload_state;
328 NiceMock<PrefsMock> prefs;
329
330 EXPECT_CALL(prefs, SetInt64(kPrefsPayloadAttemptNumber, 0)).Times(1);
331 EXPECT_CALL(prefs, SetInt64(kPrefsPayloadAttemptNumber, 1)).Times(1);
332
Jay Srinivasan08262882012-12-28 19:29:43 -0800333 EXPECT_CALL(prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(2);
334
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800335 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(1);
336 EXPECT_CALL(prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0)).Times(1);
337
David Zeuthen9a017f22013-04-11 16:10:26 -0700338 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateTimestampStart, _)).Times(AtLeast(1));
339 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateDurationUptime, _)).Times(AtLeast(1));
340
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800341 EXPECT_TRUE(payload_state.Initialize(&prefs));
342
343 SetupPayloadStateWith2Urls("Hash8593", &payload_state, &response);
344
345 // This should just advance the payload attempt number;
346 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
347 payload_state.DownloadComplete();
348 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
349 EXPECT_EQ(0, payload_state.GetUrlIndex());
350 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
351}
352
353TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
354 OmahaResponse response;
355 PayloadState payload_state;
356 NiceMock<PrefsMock> prefs;
357
358 EXPECT_TRUE(payload_state.Initialize(&prefs));
359 SetupPayloadStateWith2Urls("Hash4427", &payload_state, &response);
360
361 // Generate enough events to advance URL index, failure count and
362 // payload attempt number all to 1.
363 payload_state.DownloadComplete();
364 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
365 payload_state.UpdateFailed(kActionCodeDownloadTransferError);
366 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
367 EXPECT_EQ(1, payload_state.GetUrlIndex());
368 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
369
370 // Now, simulate a corrupted url index on persisted store which gets
371 // loaded when update_engine restarts. Using a different prefs object
372 // so as to not bother accounting for the uninteresting calls above.
373 NiceMock<PrefsMock> prefs2;
374 EXPECT_CALL(prefs2, Exists(_)).WillRepeatedly(Return(true));
375 EXPECT_CALL(prefs2, GetInt64(kPrefsPayloadAttemptNumber, _));
Jay Srinivasan08262882012-12-28 19:29:43 -0800376 EXPECT_CALL(prefs2, GetInt64(kPrefsBackoffExpiryTime, _));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800377 EXPECT_CALL(prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
378 .WillOnce(DoAll(SetArgumentPointee<1>(2), Return(true)));
379 EXPECT_CALL(prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _));
David Zeuthen9a017f22013-04-11 16:10:26 -0700380 EXPECT_CALL(prefs2, GetInt64(kPrefsUpdateTimestampStart, _));
381 EXPECT_CALL(prefs2, GetInt64(kPrefsUpdateDurationUptime, _));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800382
383 // Note: This will be a different payload object, but the response should
384 // have the same hash as before so as to not trivially reset because the
385 // response was different. We want to specifically test that even if the
386 // response is same, we should reset the state if we find it corrupted.
387 EXPECT_TRUE(payload_state.Initialize(&prefs2));
388 SetupPayloadStateWith2Urls("Hash4427", &payload_state, &response);
389
390 // Make sure all counters get reset to 0 because of the corrupted URL index
391 // we supplied above.
392 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
393 EXPECT_EQ(0, payload_state.GetUrlIndex());
394 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
395}
Jay Srinivasan08262882012-12-28 19:29:43 -0800396
397TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
398 OmahaResponse response;
399 response.is_delta_payload = true;
400 PayloadState payload_state;
401 NiceMock<PrefsMock> prefs;
402
403 EXPECT_TRUE(payload_state.Initialize(&prefs));
404 SetupPayloadStateWith2Urls("Hash6437", &payload_state, &response);
405
406 // Simulate a successful download and see that we're ready to download
407 // again without any backoff as this is a delta payload.
408 payload_state.DownloadComplete();
409 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
410 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
411
412 // Simulate two failures (enough to cause payload backoff) and check
413 // again that we're ready to re-download without any backoff as this is
414 // a delta payload.
415 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
416 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
417 EXPECT_EQ(0, payload_state.GetUrlIndex());
418 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
419 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
420}
421
422static void CheckPayloadBackoffState(PayloadState* payload_state,
423 int expected_attempt_number,
424 TimeDelta expected_days) {
425 payload_state->DownloadComplete();
426 EXPECT_EQ(expected_attempt_number, payload_state->GetPayloadAttemptNumber());
427 EXPECT_TRUE(payload_state->ShouldBackoffDownload());
428 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
429 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
430 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
431 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
432 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
433 EXPECT_LT(expected_min_time.ToInternalValue(),
434 backoff_expiry_time.ToInternalValue());
435 EXPECT_GT(expected_max_time.ToInternalValue(),
436 backoff_expiry_time.ToInternalValue());
437}
438
439TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
440 OmahaResponse response;
441 response.is_delta_payload = false;
442 PayloadState payload_state;
443 NiceMock<PrefsMock> prefs;
444
445 EXPECT_TRUE(payload_state.Initialize(&prefs));
446 SetupPayloadStateWith2Urls("Hash8939", &payload_state, &response);
447
448 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
449 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
450 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
451 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
452 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
453 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
454 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
455 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
456 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
457 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
458}
459
460TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
461 OmahaResponse response;
462 response.disable_payload_backoff = true;
463 PayloadState payload_state;
464 NiceMock<PrefsMock> prefs;
465
466 EXPECT_TRUE(payload_state.Initialize(&prefs));
467 SetupPayloadStateWith2Urls("Hash8939", &payload_state, &response);
468
469 // Simulate a successful download and see that we are ready to download
470 // again without any backoff.
471 payload_state.DownloadComplete();
472 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
473 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
474
475 // Test again, this time by simulating two errors that would cause
476 // the payload attempt number to increment due to wrap around. And
477 // check that we are still ready to re-download without any backoff.
478 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
479 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
480 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
481 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
482}
483
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800484}