blob: a0f5a420f49e102c3e1944c7f65790a045803085 [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());
David Zeuthencc6f9962013-04-18 11:57:24 -0700117 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800118}
119
120TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
121 OmahaResponse response;
122 response.payload_urls.push_back("http://single.url.test");
123 response.size = 123456789;
124 response.hash = "hash";
125 response.metadata_size = 58123;
126 response.metadata_signature = "msign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700127 MockSystemState mock_system_state;
128 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
129 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
130 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
131 .Times(AtLeast(1));
132 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
133 .Times(AtLeast(1));
134 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
135 .Times(AtLeast(1));
136 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
137 .Times(AtLeast(1));
138 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
139 .Times(AtLeast(1));
140 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
141 .Times(AtLeast(1));
142 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
143 .Times(AtLeast(1));
144 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
145 .Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800146 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700147 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800148 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 = 1\n"
151 "Url0 = http://single.url.test\n"
152 "Payload Size = 123456789\n"
153 "Payload Sha256 Hash = hash\n"
154 "Metadata Size = 58123\n"
155 "Metadata Signature = msign\n"
156 "Is Delta Payload = 0\n"
157 "Max Failure Count Per Url = 0\n"
158 "Disable Payload Backoff = 0\n";
159 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800160 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800161 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700162 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800163}
164
165TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
166 OmahaResponse response;
167 response.payload_urls.push_back("http://multiple.url.test");
168 response.payload_urls.push_back("https://multiple.url.test");
169 response.size = 523456789;
170 response.hash = "rhash";
171 response.metadata_size = 558123;
172 response.metadata_signature = "metasign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700173 MockSystemState mock_system_state;
174 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
175 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
176 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
177 .Times(AtLeast(1));
178 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
179 .Times(AtLeast(1));
180 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
181 .Times(AtLeast(1));
182 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
183 .Times(AtLeast(1));
184 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
185 .Times(AtLeast(1));
186 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
187 .Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800188 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700189 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800190 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800191 string stored_response_sign = payload_state.GetResponseSignature();
192 string expected_response_sign = "NumURLs = 2\n"
193 "Url0 = http://multiple.url.test\n"
194 "Url1 = https://multiple.url.test\n"
195 "Payload Size = 523456789\n"
196 "Payload Sha256 Hash = rhash\n"
197 "Metadata Size = 558123\n"
198 "Metadata Signature = metasign\n"
199 "Is Delta Payload = 0\n"
200 "Max Failure Count Per Url = 0\n"
201 "Disable Payload Backoff = 0\n";
202 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800203 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800204 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700205 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800206}
207
208TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
209 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700210 MockSystemState mock_system_state;
211 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800212 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800213
Jay Srinivasan19409b72013-04-12 19:23:36 -0700214 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800215 // Payload attempt should start with 0 and then advance to 1.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700216 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
217 .Times(AtLeast(1));
218 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
219 .Times(AtLeast(1));
220 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
David Zeuthen9a017f22013-04-11 16:10:26 -0700221
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800222 // Url index should go from 0 to 1 twice.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700223 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
224 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800225
226 // Failure count should be called each times url index is set, so that's
227 // 4 times for this test.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700228 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
229 .Times(AtLeast(4));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800230
Jay Srinivasan19409b72013-04-12 19:23:36 -0700231 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800232
233 // This does a SetResponse which causes all the states to be set to 0 for
234 // the first time.
235 SetupPayloadStateWith2Urls("Hash1235", &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800236 EXPECT_EQ(0, payload_state.GetUrlIndex());
237
238 // Verify that on the first error, the URL index advances to 1.
239 ActionExitCode error = kActionCodeDownloadMetadataSignatureMismatch;
240 payload_state.UpdateFailed(error);
241 EXPECT_EQ(1, payload_state.GetUrlIndex());
242
243 // Verify that on the next error, the URL index wraps around to 0.
244 payload_state.UpdateFailed(error);
245 EXPECT_EQ(0, payload_state.GetUrlIndex());
246
247 // Verify that on the next error, it again advances to 1.
248 payload_state.UpdateFailed(error);
249 EXPECT_EQ(1, payload_state.GetUrlIndex());
David Zeuthencc6f9962013-04-18 11:57:24 -0700250
251 // Verify that we switched URLs three times
252 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800253}
254
255TEST(PayloadStateTest, NewResponseResetsPayloadState) {
256 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700257 MockSystemState mock_system_state;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800258 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800259
Jay Srinivasan19409b72013-04-12 19:23:36 -0700260 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800261
262 // Set the first response.
263 SetupPayloadStateWith2Urls("Hash5823", &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800264
265 // Advance the URL index to 1 by faking an error.
266 ActionExitCode error = kActionCodeDownloadMetadataSignatureMismatch;
267 payload_state.UpdateFailed(error);
268 EXPECT_EQ(1, payload_state.GetUrlIndex());
David Zeuthencc6f9962013-04-18 11:57:24 -0700269 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800270
271 // Now, slightly change the response and set it again.
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800272 SetupPayloadStateWith2Urls("Hash8225", &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800273
274 // Make sure the url index was reset to 0 because of the new response.
275 EXPECT_EQ(0, payload_state.GetUrlIndex());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800276 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700277 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700278 EXPECT_EQ(0,
279 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
280 EXPECT_EQ(0,
281 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
282 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
283 kDownloadSourceHttpsServer));
284 EXPECT_EQ(0,
285 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800286}
287
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800288TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
289 OmahaResponse response;
290 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700291 MockSystemState mock_system_state;
292 int progress_bytes = 100;
293 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800294
Jay Srinivasan19409b72013-04-12 19:23:36 -0700295 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
296 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
297 .Times(AtLeast(2));
298 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
299 .Times(AtLeast(1));
300 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
301 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800302
Jay Srinivasan19409b72013-04-12 19:23:36 -0700303 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
Jay Srinivasan08262882012-12-28 19:29:43 -0800304
Jay Srinivasan19409b72013-04-12 19:23:36 -0700305 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
306 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800307
Jay Srinivasan19409b72013-04-12 19:23:36 -0700308 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
309 .Times(AtLeast(7));
310 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
311 .Times(AtLeast(2));
312 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
313 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800314
Jay Srinivasan19409b72013-04-12 19:23:36 -0700315 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
316 .Times(AtLeast(1));
317 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
318 .Times(AtLeast(1));
David Zeuthen9a017f22013-04-11 16:10:26 -0700319
Jay Srinivasan19409b72013-04-12 19:23:36 -0700320 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
321 .Times(AtLeast(1));
322 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
323 .Times(AtLeast(1));
324 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
325 .Times(AtLeast(1));
326 EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
327 .Times(AtLeast(1));
328
329 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800330
331 SetupPayloadStateWith2Urls("Hash5873", &payload_state, &response);
332
333 // This should advance the URL index.
334 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
335 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
336 EXPECT_EQ(1, payload_state.GetUrlIndex());
337 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700338 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800339
340 // This should advance the failure count only.
341 payload_state.UpdateFailed(kActionCodeDownloadTransferError);
342 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
343 EXPECT_EQ(1, payload_state.GetUrlIndex());
344 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700345 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800346
347 // This should advance the failure count only.
348 payload_state.UpdateFailed(kActionCodeDownloadTransferError);
349 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
350 EXPECT_EQ(1, payload_state.GetUrlIndex());
351 EXPECT_EQ(2, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700352 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800353
354 // This should advance the URL index as we've reached the
355 // max failure count and reset the failure count for the new URL index.
356 // This should also wrap around the URL index and thus cause the payload
357 // attempt number to be incremented.
358 payload_state.UpdateFailed(kActionCodeDownloadTransferError);
359 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
360 EXPECT_EQ(0, payload_state.GetUrlIndex());
361 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700362 EXPECT_EQ(2, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800363 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800364
365 // This should advance the URL index.
366 payload_state.UpdateFailed(kActionCodePayloadHashMismatchError);
367 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
368 EXPECT_EQ(1, payload_state.GetUrlIndex());
369 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700370 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800371 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800372
373 // This should advance the URL index and payload attempt number due to
374 // wrap-around of URL index.
375 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMissingError);
376 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
377 EXPECT_EQ(0, payload_state.GetUrlIndex());
378 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700379 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800380 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800381
382 // This HTTP error code should only increase the failure count.
383 payload_state.UpdateFailed(static_cast<ActionExitCode>(
384 kActionCodeOmahaRequestHTTPResponseBase + 404));
385 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
386 EXPECT_EQ(0, payload_state.GetUrlIndex());
387 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700388 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800389 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800390
391 // And that failure count should be reset when we download some bytes
392 // afterwards.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700393 payload_state.DownloadProgress(progress_bytes);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800394 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
395 EXPECT_EQ(0, payload_state.GetUrlIndex());
396 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700397 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800398 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800399
400 // Now, slightly change the response and set it again.
401 SetupPayloadStateWith2Urls("Hash8532", &payload_state, &response);
402
403 // Make sure the url index was reset to 0 because of the new response.
404 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
405 EXPECT_EQ(0, payload_state.GetUrlIndex());
406 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700407 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800408 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800409}
410
411TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDownload) {
412 OmahaResponse response;
413 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700414 MockSystemState mock_system_state;
415 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800416
Jay Srinivasan19409b72013-04-12 19:23:36 -0700417 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
418 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
419 .Times(AtLeast(1));
420 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
421 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800422
Jay Srinivasan19409b72013-04-12 19:23:36 -0700423 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
424 .Times(AtLeast(2));
Jay Srinivasan08262882012-12-28 19:29:43 -0800425
Jay Srinivasan19409b72013-04-12 19:23:36 -0700426 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
427 .Times(AtLeast(1));
428 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
429 .Times(AtLeast(1));
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
433 SetupPayloadStateWith2Urls("Hash8593", &payload_state, &response);
434
435 // This should just advance the payload attempt number;
436 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
437 payload_state.DownloadComplete();
438 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
439 EXPECT_EQ(0, payload_state.GetUrlIndex());
440 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700441 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800442}
443
444TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
445 OmahaResponse response;
446 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700447 MockSystemState mock_system_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800448
Jay Srinivasan19409b72013-04-12 19:23:36 -0700449 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800450 SetupPayloadStateWith2Urls("Hash4427", &payload_state, &response);
451
452 // Generate enough events to advance URL index, failure count and
453 // payload attempt number all to 1.
454 payload_state.DownloadComplete();
455 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
456 payload_state.UpdateFailed(kActionCodeDownloadTransferError);
457 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
458 EXPECT_EQ(1, payload_state.GetUrlIndex());
459 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700460 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800461
462 // Now, simulate a corrupted url index on persisted store which gets
463 // loaded when update_engine restarts. Using a different prefs object
464 // so as to not bother accounting for the uninteresting calls above.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700465 MockSystemState mock_system_state2;
466 NiceMock<PrefsMock>* prefs2 = mock_system_state2.mock_prefs();
467 EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
468 EXPECT_CALL(*prefs2, GetInt64(_,_)).Times(AtLeast(1));
469 EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
470 .Times(AtLeast(1));
471 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
472 .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
473 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
474 .Times(AtLeast(1));
David Zeuthencc6f9962013-04-18 11:57:24 -0700475 EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _))
476 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800477
478 // Note: This will be a different payload object, but the response should
479 // have the same hash as before so as to not trivially reset because the
480 // response was different. We want to specifically test that even if the
481 // response is same, we should reset the state if we find it corrupted.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700482 EXPECT_TRUE(payload_state.Initialize(&mock_system_state2));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800483 SetupPayloadStateWith2Urls("Hash4427", &payload_state, &response);
484
485 // Make sure all counters get reset to 0 because of the corrupted URL index
486 // we supplied above.
487 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
488 EXPECT_EQ(0, payload_state.GetUrlIndex());
489 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700490 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800491}
Jay Srinivasan08262882012-12-28 19:29:43 -0800492
493TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
494 OmahaResponse response;
495 response.is_delta_payload = true;
496 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700497 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800498
Jay Srinivasan19409b72013-04-12 19:23:36 -0700499 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan08262882012-12-28 19:29:43 -0800500 SetupPayloadStateWith2Urls("Hash6437", &payload_state, &response);
501
502 // Simulate a successful download and see that we're ready to download
503 // again without any backoff as this is a delta payload.
504 payload_state.DownloadComplete();
505 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
506 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
507
508 // Simulate two failures (enough to cause payload backoff) and check
509 // again that we're ready to re-download without any backoff as this is
510 // a delta payload.
511 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
512 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
513 EXPECT_EQ(0, payload_state.GetUrlIndex());
514 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
515 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
516}
517
518static void CheckPayloadBackoffState(PayloadState* payload_state,
519 int expected_attempt_number,
520 TimeDelta expected_days) {
521 payload_state->DownloadComplete();
522 EXPECT_EQ(expected_attempt_number, payload_state->GetPayloadAttemptNumber());
523 EXPECT_TRUE(payload_state->ShouldBackoffDownload());
524 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
525 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
526 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
527 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
528 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
529 EXPECT_LT(expected_min_time.ToInternalValue(),
530 backoff_expiry_time.ToInternalValue());
531 EXPECT_GT(expected_max_time.ToInternalValue(),
532 backoff_expiry_time.ToInternalValue());
533}
534
535TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
536 OmahaResponse response;
537 response.is_delta_payload = false;
538 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700539 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800540
Jay Srinivasan19409b72013-04-12 19:23:36 -0700541 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan08262882012-12-28 19:29:43 -0800542 SetupPayloadStateWith2Urls("Hash8939", &payload_state, &response);
543
544 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
545 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
546 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
547 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
548 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
549 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
550 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
551 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
552 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
553 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
554}
555
556TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
557 OmahaResponse response;
558 response.disable_payload_backoff = true;
559 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700560 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800561
Jay Srinivasan19409b72013-04-12 19:23:36 -0700562 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan08262882012-12-28 19:29:43 -0800563 SetupPayloadStateWith2Urls("Hash8939", &payload_state, &response);
564
565 // Simulate a successful download and see that we are ready to download
566 // again without any backoff.
567 payload_state.DownloadComplete();
568 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
569 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
570
571 // Test again, this time by simulating two errors that would cause
572 // the payload attempt number to increment due to wrap around. And
573 // check that we are still ready to re-download without any backoff.
574 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
575 payload_state.UpdateFailed(kActionCodeDownloadMetadataSignatureMismatch);
576 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
577 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
578}
579
Jay Srinivasan19409b72013-04-12 19:23:36 -0700580TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
581 OmahaResponse response;
582 response.disable_payload_backoff = true;
583 PayloadState payload_state;
584 MockSystemState mock_system_state;
585 int https_total = 0;
586 int http_total = 0;
587
588 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
589 SetupPayloadStateWith2Urls("Hash3286", &payload_state, &response);
590
591 // Simulate a successful download and see that we are ready to download
592 // again without any backoff.
593 int first_chunk = 5000000;
594 http_total += first_chunk;
595 payload_state.DownloadProgress(first_chunk);
596 // Test that first all progress is made on HTTP and none on HTTPs.
597 EXPECT_EQ(first_chunk,
598 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
599 EXPECT_EQ(http_total,
600 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
601 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
602 kDownloadSourceHttpsServer));
603 EXPECT_EQ(https_total,
604 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
605
606 // Simulate an error that'll cause the url index to point to https.
607 ActionExitCode error = kActionCodeDownloadMetadataSignatureMismatch;
608 payload_state.UpdateFailed(error);
609
610 // Test that no new progress is made on HTTP and new progress is on HTTPs.
611 int second_chunk = 23456789;
612 https_total += second_chunk;
613 payload_state.DownloadProgress(second_chunk);
614 EXPECT_EQ(first_chunk,
615 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
616 EXPECT_EQ(http_total,
617 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
618 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
619 kDownloadSourceHttpsServer));
620 EXPECT_EQ(https_total,
621 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
622
623 // Simulate error to go back to http.
624 payload_state.UpdateFailed(error);
625 int third_chunk = 32345678;
626 int http_chunk = first_chunk + third_chunk;
627 http_total += third_chunk;
628 int https_chunk = second_chunk;
629 payload_state.DownloadProgress(third_chunk);
630
631 // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
632 EXPECT_EQ(http_chunk,
633 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
634 EXPECT_EQ(http_chunk,
635 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
636 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
637 kDownloadSourceHttpsServer));
638 EXPECT_EQ(https_total,
639 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
640
641 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
642 "Installer.SuccessfulMBsDownloadedFromHttpServer",
643 http_chunk / kNumBytesInOneMiB, _, _, _));
644 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
645 "Installer.TotalMBsDownloadedFromHttpServer",
646 http_total / kNumBytesInOneMiB, _, _, _));
647 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
648 "Installer.SuccessfulMBsDownloadedFromHttpsServer",
649 https_chunk / kNumBytesInOneMiB, _, _, _));
650 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
651 "Installer.TotalMBsDownloadedFromHttpsServer",
652 https_total / kNumBytesInOneMiB, _, _, _));
David Zeuthencc6f9962013-04-18 11:57:24 -0700653 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
654 "Installer.UpdateURLSwitches",
655 2, _, _, _));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700656
657 payload_state.UpdateSucceeded();
658
659 // Make sure the metrics are reset after a successful update.
660 EXPECT_EQ(0,
661 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
662 EXPECT_EQ(0,
663 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
664 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
665 kDownloadSourceHttpsServer));
666 EXPECT_EQ(0,
667 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
668}
669
670TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
671 OmahaResponse response;
672 MockSystemState mock_system_state;
673 PayloadState payload_state;
674
675 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
676
677 // Set the first response.
678 SetupPayloadStateWith2Urls("Hash5823", &payload_state, &response);
679
680 int num_bytes = 10000;
681 payload_state.DownloadProgress(num_bytes);
682 EXPECT_EQ(num_bytes,
683 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
684 EXPECT_EQ(num_bytes,
685 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
686 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
687 kDownloadSourceHttpsServer));
688 EXPECT_EQ(0,
689 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
690
691 payload_state.UpdateRestarted();
692 // Make sure the current bytes downloaded is reset, but not the total bytes.
693 EXPECT_EQ(0,
694 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
695 EXPECT_EQ(num_bytes,
696 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
697}
698
699
700
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800701}