1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "update_engine/payload_state.h"
18
19 #include <base/files/file_path.h>
20 #include <base/files/file_util.h>
21 #include <base/strings/stringprintf.h>
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24
25 #include "update_engine/common/constants.h"
26 #include "update_engine/common/fake_clock.h"
27 #include "update_engine/common/fake_hardware.h"
28 #include "update_engine/common/fake_prefs.h"
29 #include "update_engine/common/mock_prefs.h"
30 #include "update_engine/common/prefs.h"
31 #include "update_engine/common/test_utils.h"
32 #include "update_engine/common/utils.h"
33 #include "update_engine/fake_system_state.h"
34 #include "update_engine/metrics_reporter_interface.h"
35 #include "update_engine/omaha_request_action.h"
36
37 using base::Time;
38 using base::TimeDelta;
39 using std::string;
40 using testing::_;
41 using testing::AnyNumber;
42 using testing::AtLeast;
43 using testing::Mock;
44 using testing::NiceMock;
45 using testing::Return;
46 using testing::SetArgPointee;
47
48 namespace chromeos_update_engine {
49
50 const char* kCurrentBytesDownloadedFromHttps =
51 "current-bytes-downloaded-from-HttpsServer";
52 const char* kTotalBytesDownloadedFromHttps =
53 "total-bytes-downloaded-from-HttpsServer";
54 const char* kCurrentBytesDownloadedFromHttp =
55 "current-bytes-downloaded-from-HttpServer";
56 const char* kTotalBytesDownloadedFromHttp =
57 "total-bytes-downloaded-from-HttpServer";
58 const char* kCurrentBytesDownloadedFromHttpPeer =
59 "current-bytes-downloaded-from-HttpPeer";
60 const char* kTotalBytesDownloadedFromHttpPeer =
61 "total-bytes-downloaded-from-HttpPeer";
62
SetupPayloadStateWith2Urls(string hash,bool http_enabled,bool is_delta_payload,PayloadState * payload_state,OmahaResponse * response)63 static void SetupPayloadStateWith2Urls(string hash,
64 bool http_enabled,
65 bool is_delta_payload,
66 PayloadState* payload_state,
67 OmahaResponse* response) {
68 response->packages.clear();
69 response->packages.push_back({.payload_urls = {"http://test", "https://test"},
70 .size = 523456789,
71 .metadata_size = 558123,
72 .metadata_signature = "metasign",
73 .hash = hash,
74 .is_delta = is_delta_payload});
75 response->max_failure_count_per_url = 3;
76 payload_state->SetResponse(*response);
77 string stored_response_sign = payload_state->GetResponseSignature();
78
79 string expected_url_https_only =
80 " NumURLs = 1\n"
81 " Candidate Url0 = https://test\n";
82
83 string expected_urls_both =
84 " NumURLs = 2\n"
85 " Candidate Url0 = http://test\n"
86 " Candidate Url1 = https://test\n";
87
88 string expected_response_sign = base::StringPrintf(
89 "Payload 0:\n"
90 " Size = 523456789\n"
91 " Sha256 Hash = %s\n"
92 " Metadata Size = 558123\n"
93 " Metadata Signature = metasign\n"
94 " Is Delta = %d\n"
95 "%s"
96 "Max Failure Count Per Url = %d\n"
97 "Disable Payload Backoff = %d\n",
98 hash.c_str(),
99 response->packages[0].is_delta,
100 (http_enabled ? expected_urls_both : expected_url_https_only).c_str(),
101 response->max_failure_count_per_url,
102 response->disable_payload_backoff);
103 EXPECT_EQ(expected_response_sign, stored_response_sign);
104 }
105
106 class PayloadStateTest : public ::testing::Test {};
107
TEST(PayloadStateTest,SetResponseWorksWithEmptyResponse)108 TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
109 OmahaResponse response;
110 FakeSystemState fake_system_state;
111 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
112 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
113 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
114 .Times(AtLeast(1));
115 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
116 .Times(AtLeast(1));
117 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
118 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
119 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
120 .Times(AtLeast(1));
121 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
122 .Times(AtLeast(1));
123 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
124 .Times(AtLeast(1));
125 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
126 .Times(AtLeast(1));
127 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
128 .Times(AtLeast(1));
129 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
130 .Times(AtLeast(1));
131 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
132 PayloadState payload_state;
133 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
134 payload_state.SetResponse(response);
135 string stored_response_sign = payload_state.GetResponseSignature();
136 string expected_response_sign =
137 "Max Failure Count Per Url = 0\n"
138 "Disable Payload Backoff = 0\n";
139 EXPECT_EQ(expected_response_sign, stored_response_sign);
140 EXPECT_EQ("", payload_state.GetCurrentUrl());
141 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
142 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
143 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
144 }
145
TEST(PayloadStateTest,SetResponseWorksWithSingleUrl)146 TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
147 OmahaResponse response;
148 response.packages.push_back({.payload_urls = {"https://single.url.test"},
149 .size = 123456789,
150 .metadata_size = 58123,
151 .metadata_signature = "msign",
152 .hash = "hash"});
153 FakeSystemState fake_system_state;
154 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
155 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
156 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
157 .Times(AtLeast(1));
158 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
159 .Times(AtLeast(1));
160 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
161 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
162 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
163 .Times(AtLeast(1));
164 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
165 .Times(AtLeast(1));
166 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
167 .Times(AtLeast(1));
168 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
169 .Times(AtLeast(1));
170 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
171 .Times(AtLeast(1));
172 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
173 .Times(AtLeast(1));
174 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
175 PayloadState payload_state;
176 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
177 payload_state.SetResponse(response);
178 string stored_response_sign = payload_state.GetResponseSignature();
179 string expected_response_sign =
180 "Payload 0:\n"
181 " Size = 123456789\n"
182 " Sha256 Hash = hash\n"
183 " Metadata Size = 58123\n"
184 " Metadata Signature = msign\n"
185 " Is Delta = 0\n"
186 " NumURLs = 1\n"
187 " Candidate Url0 = https://single.url.test\n"
188 "Max Failure Count Per Url = 0\n"
189 "Disable Payload Backoff = 0\n";
190 EXPECT_EQ(expected_response_sign, stored_response_sign);
191 EXPECT_EQ("https://single.url.test", payload_state.GetCurrentUrl());
192 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
193 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
194 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
195 }
196
TEST(PayloadStateTest,SetResponseWorksWithMultipleUrls)197 TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
198 OmahaResponse response;
199 response.packages.push_back({.payload_urls = {"http://multiple.url.test",
200 "https://multiple.url.test"},
201 .size = 523456789,
202 .metadata_size = 558123,
203 .metadata_signature = "metasign",
204 .hash = "rhash"});
205 FakeSystemState fake_system_state;
206 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
207 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
208 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
209 .Times(AtLeast(1));
210 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
211 .Times(AtLeast(1));
212 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
213 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
214 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
215 .Times(AtLeast(1));
216 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
217 .Times(AtLeast(1));
218 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
219 .Times(AtLeast(1));
220 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
221 .Times(AtLeast(1));
222 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
223
224 PayloadState payload_state;
225 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
226 payload_state.SetResponse(response);
227 string stored_response_sign = payload_state.GetResponseSignature();
228 string expected_response_sign =
229 "Payload 0:\n"
230 " Size = 523456789\n"
231 " Sha256 Hash = rhash\n"
232 " Metadata Size = 558123\n"
233 " Metadata Signature = metasign\n"
234 " Is Delta = 0\n"
235 " NumURLs = 2\n"
236 " Candidate Url0 = http://multiple.url.test\n"
237 " Candidate Url1 = https://multiple.url.test\n"
238 "Max Failure Count Per Url = 0\n"
239 "Disable Payload Backoff = 0\n";
240 EXPECT_EQ(expected_response_sign, stored_response_sign);
241 EXPECT_EQ("http://multiple.url.test", payload_state.GetCurrentUrl());
242 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
243 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
244 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
245 }
246
TEST(PayloadStateTest,CanAdvanceUrlIndexCorrectly)247 TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
248 OmahaResponse response;
249 FakeSystemState fake_system_state;
250 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
251 PayloadState payload_state;
252
253 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
254 // Payload attempt should start with 0 and then advance to 1.
255 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
256 .Times(AtLeast(1));
257 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
258 .Times(AtLeast(1));
259 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
260 .Times(AtLeast(1));
261 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
262 .Times(AtLeast(1));
263 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
264
265 // Reboots will be set
266 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1));
267
268 // Url index should go from 0 to 1 twice.
269 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
270 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
271
272 // Failure count should be called each times url index is set, so that's
273 // 4 times for this test.
274 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
275 .Times(AtLeast(4));
276
277 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
278
279 // This does a SetResponse which causes all the states to be set to 0 for
280 // the first time.
281 SetupPayloadStateWith2Urls(
282 "Hash1235", true, false, &payload_state, &response);
283 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
284
285 // Verify that on the first error, the URL index advances to 1.
286 ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
287 payload_state.UpdateFailed(error);
288 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
289
290 // Verify that on the next error, the URL index wraps around to 0.
291 payload_state.UpdateFailed(error);
292 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
293
294 // Verify that on the next error, it again advances to 1.
295 payload_state.UpdateFailed(error);
296 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
297
298 // Verify that we switched URLs three times
299 EXPECT_EQ(3U, payload_state.GetUrlSwitchCount());
300 }
301
TEST(PayloadStateTest,NewResponseResetsPayloadState)302 TEST(PayloadStateTest, NewResponseResetsPayloadState) {
303 OmahaResponse response;
304 FakeSystemState fake_system_state;
305 PayloadState payload_state;
306
307 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
308
309 // Set the first response.
310 SetupPayloadStateWith2Urls(
311 "Hash5823", true, false, &payload_state, &response);
312 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
313
314 // Advance the URL index to 1 by faking an error.
315 ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
316 payload_state.UpdateFailed(error);
317 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
318 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
319
320 // Now, slightly change the response and set it again.
321 SetupPayloadStateWith2Urls(
322 "Hash8225", true, false, &payload_state, &response);
323 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
324
325 // Fake an error again.
326 payload_state.UpdateFailed(error);
327 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
328 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
329
330 // Return a third different response.
331 SetupPayloadStateWith2Urls(
332 "Hash9999", true, false, &payload_state, &response);
333 EXPECT_EQ(3, payload_state.GetNumResponsesSeen());
334
335 // Make sure the url index was reset to 0 because of the new response.
336 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
337 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
338 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
339 EXPECT_EQ(0U,
340 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
341 EXPECT_EQ(0U,
342 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
343 EXPECT_EQ(
344 0U, payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
345 EXPECT_EQ(0U,
346 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
347 }
348
TEST(PayloadStateTest,AllCountersGetUpdatedProperlyOnErrorCodesAndEvents)349 TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
350 OmahaResponse response;
351 PayloadState payload_state;
352 FakeSystemState fake_system_state;
353 int progress_bytes = 100;
354 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
355
356 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
357 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
358 .Times(AtLeast(2));
359 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
360 .Times(AtLeast(1));
361 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
362 .Times(AtLeast(1));
363
364 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
365 .Times(AtLeast(2));
366 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
367 .Times(AtLeast(1));
368 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 2))
369 .Times(AtLeast(1));
370
371 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
372
373 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
374 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
375
376 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
377 .Times(AtLeast(7));
378 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
379 .Times(AtLeast(2));
380 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
381 .Times(AtLeast(1));
382
383 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
384 .Times(AtLeast(1));
385 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
386 .Times(AtLeast(1));
387
388 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
389 .Times(AtLeast(1));
390 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
391 .Times(AtLeast(1));
392 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
393 .Times(AtLeast(1));
394 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
395 .Times(AtLeast(1));
396 EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
397 .Times(AtLeast(1));
398 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
399
400 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
401
402 SetupPayloadStateWith2Urls(
403 "Hash5873", true, false, &payload_state, &response);
404 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
405
406 // This should advance the URL index.
407 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
408 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
409 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
410 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
411 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
412 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
413
414 // This should advance the failure count only.
415 payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
416 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
417 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
418 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
419 EXPECT_EQ(1U, payload_state.GetUrlFailureCount());
420 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
421
422 // This should advance the failure count only.
423 payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
424 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
425 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
426 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
427 EXPECT_EQ(2U, payload_state.GetUrlFailureCount());
428 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
429
430 // This should advance the URL index as we've reached the
431 // max failure count and reset the failure count for the new URL index.
432 // This should also wrap around the URL index and thus cause the payload
433 // attempt number to be incremented.
434 payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
435 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
436 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
437 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
438 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
439 EXPECT_EQ(2U, payload_state.GetUrlSwitchCount());
440 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
441
442 // This should advance the URL index.
443 payload_state.UpdateFailed(ErrorCode::kPayloadHashMismatchError);
444 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
445 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
446 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
447 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
448 EXPECT_EQ(3U, payload_state.GetUrlSwitchCount());
449 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
450
451 // This should advance the URL index and payload attempt number due to
452 // wrap-around of URL index.
453 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMissingError);
454 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
455 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
456 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
457 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
458 EXPECT_EQ(4U, payload_state.GetUrlSwitchCount());
459 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
460
461 // This HTTP error code should only increase the failure count.
462 payload_state.UpdateFailed(static_cast<ErrorCode>(
463 static_cast<int>(ErrorCode::kOmahaRequestHTTPResponseBase) + 404));
464 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
465 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
466 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
467 EXPECT_EQ(1U, payload_state.GetUrlFailureCount());
468 EXPECT_EQ(4U, payload_state.GetUrlSwitchCount());
469 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
470
471 // And that failure count should be reset when we download some bytes
472 // afterwards.
473 payload_state.DownloadProgress(progress_bytes);
474 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
475 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
476 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
477 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
478 EXPECT_EQ(4U, payload_state.GetUrlSwitchCount());
479 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
480
481 // Now, slightly change the response and set it again.
482 SetupPayloadStateWith2Urls(
483 "Hash8532", true, false, &payload_state, &response);
484 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
485
486 // Make sure the url index was reset to 0 because of the new response.
487 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
488 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
489 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
490 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
491 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
492 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
493 }
494
TEST(PayloadStateTest,PayloadAttemptNumberIncreasesOnSuccessfulFullDownload)495 TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulFullDownload) {
496 OmahaResponse response;
497 PayloadState payload_state;
498 FakeSystemState fake_system_state;
499 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
500
501 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
502 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
503 .Times(AtLeast(1));
504 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
505 .Times(AtLeast(1));
506
507 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
508 .Times(AtLeast(1));
509 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
510 .Times(AtLeast(1));
511
512 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
513
514 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
515 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
516 .Times(AtLeast(1));
517
518 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
519
520 SetupPayloadStateWith2Urls(
521 "Hash8593", true, false, &payload_state, &response);
522
523 // This should just advance the payload attempt number;
524 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
525 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
526 payload_state.DownloadComplete();
527 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
528 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
529 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
530 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
531 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
532 }
533
TEST(PayloadStateTest,PayloadAttemptNumberIncreasesOnSuccessfulDeltaDownload)534 TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDeltaDownload) {
535 OmahaResponse response;
536 PayloadState payload_state;
537 FakeSystemState fake_system_state;
538 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
539
540 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
541 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
542 .Times(AtLeast(1));
543 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
544 .Times(AtLeast(1));
545
546 // kPrefsFullPayloadAttemptNumber is not incremented for delta payloads.
547 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
548 .Times(AtLeast(1));
549
550 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(1);
551
552 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
553 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
554 .Times(AtLeast(1));
555
556 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
557
558 SetupPayloadStateWith2Urls("Hash8593", true, true, &payload_state, &response);
559
560 // This should just advance the payload attempt number;
561 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
562 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
563 payload_state.DownloadComplete();
564 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
565 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
566 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
567 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
568 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
569 }
570
TEST(PayloadStateTest,SetResponseResetsInvalidUrlIndex)571 TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
572 OmahaResponse response;
573 PayloadState payload_state;
574 FakeSystemState fake_system_state;
575
576 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
577 SetupPayloadStateWith2Urls(
578 "Hash4427", true, false, &payload_state, &response);
579
580 // Generate enough events to advance URL index, failure count and
581 // payload attempt number all to 1.
582 payload_state.DownloadComplete();
583 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
584 payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
585 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
586 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
587 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
588 EXPECT_EQ(1U, payload_state.GetUrlFailureCount());
589 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
590
591 // Now, simulate a corrupted url index on persisted store which gets
592 // loaded when update_engine restarts. Using a different prefs object
593 // so as to not bother accounting for the uninteresting calls above.
594 FakeSystemState fake_system_state2;
595 NiceMock<MockPrefs>* prefs2 = fake_system_state2.mock_prefs();
596 EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
597 EXPECT_CALL(*prefs2, GetInt64(_, _)).Times(AtLeast(1));
598 EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
599 .Times(AtLeast(1));
600 EXPECT_CALL(*prefs2, GetInt64(kPrefsFullPayloadAttemptNumber, _))
601 .Times(AtLeast(1));
602 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
603 .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(true)));
604 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
605 .Times(AtLeast(1));
606 EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _)).Times(AtLeast(1));
607
608 // Note: This will be a different payload object, but the response should
609 // have the same hash as before so as to not trivially reset because the
610 // response was different. We want to specifically test that even if the
611 // response is same, we should reset the state if we find it corrupted.
612 EXPECT_TRUE(payload_state.Initialize(&fake_system_state2));
613 SetupPayloadStateWith2Urls(
614 "Hash4427", true, false, &payload_state, &response);
615
616 // Make sure all counters get reset to 0 because of the corrupted URL index
617 // we supplied above.
618 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
619 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
620 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
621 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
622 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
623 }
624
TEST(PayloadStateTest,NoBackoffInteractiveChecks)625 TEST(PayloadStateTest, NoBackoffInteractiveChecks) {
626 OmahaResponse response;
627 PayloadState payload_state;
628 FakeSystemState fake_system_state;
629 OmahaRequestParams params(&fake_system_state);
630 params.Init("", "", true); // interactive = True.
631 fake_system_state.set_request_params(¶ms);
632
633 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
634 SetupPayloadStateWith2Urls(
635 "Hash6437", true, false, &payload_state, &response);
636
637 // Simulate two failures (enough to cause payload backoff) and check
638 // again that we're ready to re-download without any backoff as this is
639 // an interactive check.
640 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
641 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
642 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
643 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
644 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
645 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
646 }
647
TEST(PayloadStateTest,NoBackoffForP2PUpdates)648 TEST(PayloadStateTest, NoBackoffForP2PUpdates) {
649 OmahaResponse response;
650 PayloadState payload_state;
651 FakeSystemState fake_system_state;
652 OmahaRequestParams params(&fake_system_state);
653 params.Init("", "", false); // interactive = False.
654 fake_system_state.set_request_params(¶ms);
655
656 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
657 SetupPayloadStateWith2Urls(
658 "Hash6437", true, false, &payload_state, &response);
659
660 // Simulate two failures (enough to cause payload backoff) and check
661 // again that we're ready to re-download without any backoff as this is
662 // an interactive check.
663 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
664 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
665 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
666 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
667 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
668 // Set p2p url.
669 payload_state.SetUsingP2PForDownloading(true);
670 payload_state.SetP2PUrl("http://mypeer:52909/path/to/file");
671 // Should not backoff for p2p updates.
672 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
673
674 payload_state.SetP2PUrl("");
675 // No actual p2p update if no url is provided.
676 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
677 }
678
TEST(PayloadStateTest,NoBackoffForDeltaPayloads)679 TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
680 OmahaResponse response;
681 PayloadState payload_state;
682 FakeSystemState fake_system_state;
683
684 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
685 SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response);
686
687 // Simulate a successful download and see that we're ready to download
688 // again without any backoff as this is a delta payload.
689 payload_state.DownloadComplete();
690 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
691 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
692 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
693
694 // Simulate two failures (enough to cause payload backoff) and check
695 // again that we're ready to re-download without any backoff as this is
696 // a delta payload.
697 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
698 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
699 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
700 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
701 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
702 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
703 }
704
CheckPayloadBackoffState(PayloadState * payload_state,int expected_attempt_number,TimeDelta expected_days)705 static void CheckPayloadBackoffState(PayloadState* payload_state,
706 int expected_attempt_number,
707 TimeDelta expected_days) {
708 payload_state->DownloadComplete();
709 EXPECT_EQ(expected_attempt_number,
710 payload_state->GetFullPayloadAttemptNumber());
711 EXPECT_TRUE(payload_state->ShouldBackoffDownload());
712 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
713 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
714 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
715 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
716 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
717 EXPECT_LT(expected_min_time.ToInternalValue(),
718 backoff_expiry_time.ToInternalValue());
719 EXPECT_GT(expected_max_time.ToInternalValue(),
720 backoff_expiry_time.ToInternalValue());
721 }
722
TEST(PayloadStateTest,BackoffPeriodsAreInCorrectRange)723 TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
724 OmahaResponse response;
725 PayloadState payload_state;
726 FakeSystemState fake_system_state;
727
728 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
729 SetupPayloadStateWith2Urls(
730 "Hash8939", true, false, &payload_state, &response);
731
732 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
733 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
734 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
735 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
736 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
737 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
738 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
739 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
740 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
741 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
742 }
743
TEST(PayloadStateTest,BackoffLogicCanBeDisabled)744 TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
745 OmahaResponse response;
746 response.disable_payload_backoff = true;
747 PayloadState payload_state;
748 FakeSystemState fake_system_state;
749
750 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
751 SetupPayloadStateWith2Urls(
752 "Hash8939", true, false, &payload_state, &response);
753
754 // Simulate a successful download and see that we are ready to download
755 // again without any backoff.
756 payload_state.DownloadComplete();
757 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
758 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
759 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
760
761 // Test again, this time by simulating two errors that would cause
762 // the payload attempt number to increment due to wrap around. And
763 // check that we are still ready to re-download without any backoff.
764 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
765 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
766 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
767 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
768 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
769 }
770
TEST(PayloadStateTest,BytesDownloadedMetricsGetAddedToCorrectSources)771 TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
772 OmahaResponse response;
773 response.disable_payload_backoff = true;
774 PayloadState payload_state;
775 FakeSystemState fake_system_state;
776 uint64_t https_total = 0;
777 uint64_t http_total = 0;
778
779 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
780 SetupPayloadStateWith2Urls(
781 "Hash3286", true, false, &payload_state, &response);
782 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
783
784 // Simulate a previous attempt with in order to set an initial non-zero value
785 // for the total bytes downloaded for HTTP.
786 uint64_t prev_chunk = 323456789;
787 http_total += prev_chunk;
788 payload_state.DownloadProgress(prev_chunk);
789
790 // Ensure that the initial values for HTTP reflect this attempt.
791 EXPECT_EQ(prev_chunk,
792 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
793 EXPECT_EQ(http_total,
794 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
795
796 // Change the response hash so as to simulate a new response which will
797 // reset the current bytes downloaded, but not the total bytes downloaded.
798 SetupPayloadStateWith2Urls(
799 "Hash9904", true, false, &payload_state, &response);
800 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
801
802 // First, simulate successful download of a few bytes over HTTP.
803 uint64_t first_chunk = 5000000;
804 http_total += first_chunk;
805 payload_state.DownloadProgress(first_chunk);
806 // Test that first all progress is made on HTTP and none on HTTPS.
807 EXPECT_EQ(first_chunk,
808 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
809 EXPECT_EQ(http_total,
810 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
811 EXPECT_EQ(
812 0U, payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
813 EXPECT_EQ(https_total,
814 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
815
816 // Simulate an error that'll cause the url index to point to https.
817 ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
818 payload_state.UpdateFailed(error);
819
820 // Test that no new progress is made on HTTP and new progress is on HTTPS.
821 uint64_t second_chunk = 23456789;
822 https_total += second_chunk;
823 payload_state.DownloadProgress(second_chunk);
824 EXPECT_EQ(first_chunk,
825 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
826 EXPECT_EQ(http_total,
827 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
828 EXPECT_EQ(
829 second_chunk,
830 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
831 EXPECT_EQ(https_total,
832 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
833
834 // Simulate error to go back to http.
835 payload_state.UpdateFailed(error);
836 uint64_t third_chunk = 32345678;
837 uint64_t http_chunk = first_chunk + third_chunk;
838 http_total += third_chunk;
839 payload_state.DownloadProgress(third_chunk);
840
841 // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
842 EXPECT_EQ(http_chunk,
843 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
844 EXPECT_EQ(http_total,
845 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
846 EXPECT_EQ(
847 second_chunk,
848 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
849 EXPECT_EQ(https_total,
850 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
851
852 // Simulate error (will cause URL switch), set p2p is to be used and
853 // then do 42MB worth of progress
854 payload_state.UpdateFailed(error);
855 payload_state.SetUsingP2PForDownloading(true);
856 uint64_t p2p_total = 42 * 1000 * 1000;
857 payload_state.DownloadProgress(p2p_total);
858
859 EXPECT_EQ(p2p_total,
860 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpPeer));
861
862 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
863 ReportSuccessfulUpdateMetrics(
864 1, _, kPayloadTypeFull, _, _, 314, _, _, _, 3));
865
866 payload_state.UpdateSucceeded();
867
868 // Make sure the metrics are reset after a successful update.
869 EXPECT_EQ(0U,
870 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
871 EXPECT_EQ(0U,
872 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
873 EXPECT_EQ(
874 0U, payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
875 EXPECT_EQ(0U,
876 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
877 EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
878 }
879
TEST(PayloadStateTest,DownloadSourcesUsedIsCorrect)880 TEST(PayloadStateTest, DownloadSourcesUsedIsCorrect) {
881 OmahaResponse response;
882 PayloadState payload_state;
883 FakeSystemState fake_system_state;
884
885 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
886 SetupPayloadStateWith2Urls(
887 "Hash3286", true, false, &payload_state, &response);
888
889 // Simulate progress in order to mark HTTP as one of the sources used.
890 uint64_t num_bytes = 42 * 1000 * 1000;
891 payload_state.DownloadProgress(num_bytes);
892
893 // Check that this was done via HTTP.
894 EXPECT_EQ(num_bytes,
895 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
896 EXPECT_EQ(num_bytes,
897 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
898
899 // Check that only HTTP is reported as a download source.
900 int64_t total_bytes[kNumDownloadSources] = {};
901 total_bytes[kDownloadSourceHttpServer] = num_bytes;
902
903 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
904 ReportSuccessfulUpdateMetrics(
905 _,
906 _,
907 _,
908 _,
909 test_utils::DownloadSourceMatcher(total_bytes),
910 _,
911 _,
912 _,
913 _,
914 _))
915 .Times(1);
916
917 payload_state.UpdateSucceeded();
918 }
919
TEST(PayloadStateTest,RestartingUpdateResetsMetrics)920 TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
921 OmahaResponse response;
922 FakeSystemState fake_system_state;
923 PayloadState payload_state;
924
925 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
926
927 // Set the first response.
928 SetupPayloadStateWith2Urls(
929 "Hash5823", true, false, &payload_state, &response);
930
931 uint64_t num_bytes = 10000;
932 payload_state.DownloadProgress(num_bytes);
933 EXPECT_EQ(num_bytes,
934 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
935 EXPECT_EQ(num_bytes,
936 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
937 EXPECT_EQ(
938 0U, payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
939 EXPECT_EQ(0U,
940 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
941
942 payload_state.UpdateRestarted();
943 // Make sure the current bytes downloaded is reset, but not the total bytes.
944 EXPECT_EQ(0U,
945 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
946 EXPECT_EQ(num_bytes,
947 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
948 }
949
TEST(PayloadStateTest,NumRebootsIncrementsCorrectly)950 TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
951 FakeSystemState fake_system_state;
952 PayloadState payload_state;
953
954 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
955 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AtLeast(0));
956 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
957
958 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
959
960 payload_state.UpdateRestarted();
961 EXPECT_EQ(0U, payload_state.GetNumReboots());
962
963 fake_system_state.set_system_rebooted(true);
964 payload_state.UpdateResumed();
965 // Num reboots should be incremented because system rebooted detected.
966 EXPECT_EQ(1U, payload_state.GetNumReboots());
967
968 fake_system_state.set_system_rebooted(false);
969 payload_state.UpdateResumed();
970 // Num reboots should now be 1 as reboot was not detected.
971 EXPECT_EQ(1U, payload_state.GetNumReboots());
972
973 // Restart the update again to verify we set the num of reboots back to 0.
974 payload_state.UpdateRestarted();
975 EXPECT_EQ(0U, payload_state.GetNumReboots());
976 }
977
TEST(PayloadStateTest,RollbackHappened)978 TEST(PayloadStateTest, RollbackHappened) {
979 FakeSystemState fake_system_state;
980 PayloadState payload_state;
981
982 NiceMock<MockPrefs>* mock_powerwash_safe_prefs =
983 fake_system_state.mock_powerwash_safe_prefs();
984 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
985
986 // Verify pre-conditions are good.
987 EXPECT_FALSE(payload_state.GetRollbackHappened());
988
989 // Set to true.
990 EXPECT_CALL(*mock_powerwash_safe_prefs,
991 SetBoolean(kPrefsRollbackHappened, true));
992 payload_state.SetRollbackHappened(true);
993 EXPECT_TRUE(payload_state.GetRollbackHappened());
994
995 // Set to false.
996 EXPECT_CALL(*mock_powerwash_safe_prefs, Delete(kPrefsRollbackHappened));
997 payload_state.SetRollbackHappened(false);
998 EXPECT_FALSE(payload_state.GetRollbackHappened());
999
1000 // Let's verify we can reload it correctly.
1001 EXPECT_CALL(*mock_powerwash_safe_prefs, GetBoolean(kPrefsRollbackHappened, _))
1002 .WillOnce(DoAll(SetArgPointee<1>(true), Return(true)));
1003 EXPECT_CALL(*mock_powerwash_safe_prefs,
1004 SetBoolean(kPrefsRollbackHappened, true));
1005 payload_state.LoadRollbackHappened();
1006 EXPECT_TRUE(payload_state.GetRollbackHappened());
1007 }
1008
TEST(PayloadStateTest,RollbackVersion)1009 TEST(PayloadStateTest, RollbackVersion) {
1010 FakeSystemState fake_system_state;
1011 PayloadState payload_state;
1012
1013 NiceMock<MockPrefs>* mock_powerwash_safe_prefs =
1014 fake_system_state.mock_powerwash_safe_prefs();
1015 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1016
1017 // Verify pre-conditions are good.
1018 EXPECT_TRUE(payload_state.GetRollbackVersion().empty());
1019
1020 // Mock out the os version and make sure it's blacklisted correctly.
1021 string rollback_version = "2345.0.0";
1022 OmahaRequestParams params(&fake_system_state);
1023 params.Init(rollback_version, "", false);
1024 fake_system_state.set_request_params(¶ms);
1025
1026 EXPECT_CALL(*mock_powerwash_safe_prefs,
1027 SetString(kPrefsRollbackVersion, rollback_version));
1028 payload_state.Rollback();
1029
1030 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
1031
1032 // Change it up a little and verify we load it correctly.
1033 rollback_version = "2345.0.1";
1034 // Let's verify we can reload it correctly.
1035 EXPECT_CALL(*mock_powerwash_safe_prefs, GetString(kPrefsRollbackVersion, _))
1036 .WillOnce(DoAll(SetArgPointee<1>(rollback_version), Return(true)));
1037 EXPECT_CALL(*mock_powerwash_safe_prefs,
1038 SetString(kPrefsRollbackVersion, rollback_version));
1039 payload_state.LoadRollbackVersion();
1040 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
1041
1042 // Check that we report only UpdateEngine.Rollback.* metrics in
1043 // UpdateSucceeded().
1044 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1045 ReportRollbackMetrics(metrics::RollbackResult::kSuccess))
1046 .Times(1);
1047
1048 payload_state.UpdateSucceeded();
1049 }
1050
TEST(PayloadStateTest,DurationsAreCorrect)1051 TEST(PayloadStateTest, DurationsAreCorrect) {
1052 OmahaResponse response;
1053 response.packages.resize(1);
1054 PayloadState payload_state;
1055 FakeSystemState fake_system_state;
1056 FakeClock fake_clock;
1057 FakePrefs fake_prefs;
1058
1059 // Set the clock to a well-known time - 1 second on the wall-clock
1060 // and 2 seconds on the monotonic clock
1061 fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
1062 fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
1063
1064 fake_system_state.set_clock(&fake_clock);
1065 fake_system_state.set_prefs(&fake_prefs);
1066 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1067
1068 // Check that durations are correct for a successful update where
1069 // time has advanced 7 seconds on the wall clock and 4 seconds on
1070 // the monotonic clock.
1071 SetupPayloadStateWith2Urls(
1072 "Hash8593", true, false, &payload_state, &response);
1073 fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
1074 fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
1075 payload_state.UpdateSucceeded();
1076 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
1077 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
1078
1079 // Check that durations are reset when a new response comes in.
1080 SetupPayloadStateWith2Urls(
1081 "Hash8594", true, false, &payload_state, &response);
1082 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
1083 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
1084
1085 // Advance time a bit (10 secs), simulate download progress and
1086 // check that durations are updated.
1087 fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
1088 fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
1089 payload_state.DownloadProgress(10);
1090 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
1091 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
1092
1093 // Now simulate a reboot by resetting monotonic time (to 5000) and
1094 // creating a new PayloadState object and check that we load the
1095 // durations correctly (e.g. they are the same as before).
1096 fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
1097 PayloadState payload_state2;
1098 EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
1099 payload_state2.SetResponse(response);
1100 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
1101 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),
1102 10000000);
1103
1104 // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
1105 // and check that the durations are increased accordingly.
1106 fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
1107 fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
1108 payload_state2.UpdateSucceeded();
1109 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
1110 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),
1111 16000000);
1112 }
1113
TEST(PayloadStateTest,RebootAfterSuccessfulUpdateTest)1114 TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
1115 OmahaResponse response;
1116 PayloadState payload_state;
1117 FakeSystemState fake_system_state;
1118 FakeClock fake_clock;
1119 FakePrefs fake_prefs;
1120
1121 // Set the clock to a well-known time (t = 30 seconds).
1122 fake_clock.SetMonotonicTime(
1123 Time::FromInternalValue(30 * Time::kMicrosecondsPerSecond));
1124
1125 fake_system_state.set_clock(&fake_clock);
1126 fake_system_state.set_prefs(&fake_prefs);
1127 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1128
1129 // Make the update succeed.
1130 SetupPayloadStateWith2Urls(
1131 "Hash8593", true, false, &payload_state, &response);
1132 payload_state.UpdateSucceeded();
1133
1134 // Check that the marker was written.
1135 EXPECT_TRUE(fake_prefs.Exists(kPrefsSystemUpdatedMarker));
1136
1137 // Now simulate a reboot and set the wallclock time to a later point
1138 // (t = 500 seconds). We do this by using a new PayloadState object
1139 // and checking that it emits the right UMA metric with the right
1140 // value.
1141 fake_clock.SetMonotonicTime(
1142 Time::FromInternalValue(500 * Time::kMicrosecondsPerSecond));
1143 PayloadState payload_state2;
1144 EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
1145
1146 // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
1147 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1148 ReportTimeToReboot(7));
1149 fake_system_state.set_system_rebooted(true);
1150
1151 payload_state2.UpdateEngineStarted();
1152
1153 // Check that the marker was nuked.
1154 EXPECT_FALSE(fake_prefs.Exists(kPrefsSystemUpdatedMarker));
1155 }
1156
TEST(PayloadStateTest,RestartAfterCrash)1157 TEST(PayloadStateTest, RestartAfterCrash) {
1158 PayloadState payload_state;
1159 FakeSystemState fake_system_state;
1160 testing::StrictMock<MockMetricsReporter> mock_metrics_reporter;
1161 fake_system_state.set_metrics_reporter(&mock_metrics_reporter);
1162 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
1163
1164 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1165
1166 // Only the |kPrefsAttemptInProgress| state variable should be read.
1167 EXPECT_CALL(*prefs, Exists(_)).Times(0);
1168 EXPECT_CALL(*prefs, SetString(_, _)).Times(0);
1169 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(0);
1170 EXPECT_CALL(*prefs, SetBoolean(_, _)).Times(0);
1171 EXPECT_CALL(*prefs, GetString(_, _)).Times(0);
1172 EXPECT_CALL(*prefs, GetInt64(_, _)).Times(0);
1173 EXPECT_CALL(*prefs, GetBoolean(_, _)).Times(0);
1174 EXPECT_CALL(*prefs, GetBoolean(kPrefsAttemptInProgress, _));
1175
1176 // Simulate an update_engine restart without a reboot.
1177 fake_system_state.set_system_rebooted(false);
1178
1179 payload_state.UpdateEngineStarted();
1180 }
1181
TEST(PayloadStateTest,AbnormalTerminationAttemptMetricsNoReporting)1182 TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsNoReporting) {
1183 PayloadState payload_state;
1184 FakeSystemState fake_system_state;
1185
1186 // If there's no marker at startup, ensure we don't report a metric.
1187 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1188 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1189 ReportAbnormallyTerminatedUpdateAttemptMetrics())
1190 .Times(0);
1191 payload_state.UpdateEngineStarted();
1192 }
1193
TEST(PayloadStateTest,AbnormalTerminationAttemptMetricsReported)1194 TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsReported) {
1195 PayloadState payload_state;
1196 FakeSystemState fake_system_state;
1197 FakePrefs fake_prefs;
1198
1199 // If we have a marker at startup, ensure it's reported and the
1200 // marker is then cleared.
1201 fake_system_state.set_prefs(&fake_prefs);
1202 fake_prefs.SetBoolean(kPrefsAttemptInProgress, true);
1203
1204 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1205
1206 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1207 ReportAbnormallyTerminatedUpdateAttemptMetrics())
1208 .Times(1);
1209 payload_state.UpdateEngineStarted();
1210
1211 EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
1212 }
1213
TEST(PayloadStateTest,AbnormalTerminationAttemptMetricsClearedOnSucceess)1214 TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsClearedOnSucceess) {
1215 PayloadState payload_state;
1216 FakeSystemState fake_system_state;
1217 FakePrefs fake_prefs;
1218
1219 // Make sure the marker is written and cleared during an attempt and
1220 // also that we DO NOT emit the metric (since the attempt didn't end
1221 // abnormally).
1222 fake_system_state.set_prefs(&fake_prefs);
1223 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1224 OmahaResponse response;
1225 response.packages.resize(1);
1226 payload_state.SetResponse(response);
1227
1228 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1229 ReportAbnormallyTerminatedUpdateAttemptMetrics())
1230 .Times(0);
1231
1232 // Attempt not in progress, should be clear.
1233 EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
1234
1235 payload_state.UpdateRestarted();
1236
1237 // Attempt not in progress, should be set.
1238 EXPECT_TRUE(fake_prefs.Exists(kPrefsAttemptInProgress));
1239
1240 payload_state.UpdateSucceeded();
1241
1242 // Attempt not in progress, should be clear.
1243 EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
1244 }
1245
TEST(PayloadStateTest,CandidateUrlsComputedCorrectly)1246 TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
1247 OmahaResponse response;
1248 FakeSystemState fake_system_state;
1249 PayloadState payload_state;
1250
1251 policy::MockDevicePolicy disable_http_policy;
1252 fake_system_state.set_device_policy(&disable_http_policy);
1253 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1254
1255 // Test with no device policy. Should default to allowing http.
1256 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1257 .WillRepeatedly(Return(false));
1258
1259 // Set the first response.
1260 SetupPayloadStateWith2Urls(
1261 "Hash8433", true, false, &payload_state, &response);
1262
1263 // Check that we use the HTTP URL since there is no value set for allowing
1264 // http.
1265 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1266
1267 // Test with device policy not allowing http updates.
1268 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1269 .WillRepeatedly(DoAll(SetArgPointee<0>(false), Return(true)));
1270
1271 // Reset state and set again.
1272 SetupPayloadStateWith2Urls(
1273 "Hash8433", false, false, &payload_state, &response);
1274
1275 // Check that we skip the HTTP URL and use only the HTTPS url.
1276 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1277
1278 // Advance the URL index to 1 by faking an error.
1279 ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
1280 payload_state.UpdateFailed(error);
1281
1282 // Check that we still skip the HTTP URL and use only the HTTPS url.
1283 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1284 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
1285
1286 // Now, slightly change the response and set it again.
1287 SetupPayloadStateWith2Urls(
1288 "Hash2399", false, false, &payload_state, &response);
1289
1290 // Check that we still skip the HTTP URL and use only the HTTPS url.
1291 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1292
1293 // Now, pretend that the HTTP policy is turned on. We want to make sure
1294 // the new policy is honored.
1295 policy::MockDevicePolicy enable_http_policy;
1296 fake_system_state.set_device_policy(&enable_http_policy);
1297 EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
1298 .WillRepeatedly(DoAll(SetArgPointee<0>(true), Return(true)));
1299
1300 // Now, set the same response using the same hash
1301 // so that we can test that the state is reset not because of the
1302 // hash but because of the policy change which results in candidate url
1303 // list change.
1304 SetupPayloadStateWith2Urls(
1305 "Hash2399", true, false, &payload_state, &response);
1306
1307 // Check that we use the HTTP URL now and the failure count is reset.
1308 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1309 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
1310
1311 // Fake a failure and see if we're moving over to the HTTPS url and update
1312 // the URL switch count properly.
1313 payload_state.UpdateFailed(error);
1314 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1315 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
1316 EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
1317 }
1318
TEST(PayloadStateTest,PayloadTypeMetricWhenTypeIsDelta)1319 TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
1320 OmahaResponse response;
1321 PayloadState payload_state;
1322 FakeSystemState fake_system_state;
1323
1324 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1325 SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response);
1326
1327 // Simulate a successful download and update.
1328 payload_state.DownloadComplete();
1329 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1330 ReportSuccessfulUpdateMetrics(
1331 _, _, kPayloadTypeDelta, _, _, _, _, _, _, _));
1332 payload_state.UpdateSucceeded();
1333
1334 // Mock the request to a request where the delta was disabled but Omaha sends
1335 // a delta anyway and test again.
1336 OmahaRequestParams params(&fake_system_state);
1337 params.set_delta_okay(false);
1338 fake_system_state.set_request_params(¶ms);
1339
1340 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1341 SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response);
1342
1343 payload_state.DownloadComplete();
1344
1345 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1346 ReportSuccessfulUpdateMetrics(
1347 _, _, kPayloadTypeDelta, _, _, _, _, _, _, _));
1348 payload_state.UpdateSucceeded();
1349 }
1350
TEST(PayloadStateTest,PayloadTypeMetricWhenTypeIsForcedFull)1351 TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
1352 OmahaResponse response;
1353 PayloadState payload_state;
1354 FakeSystemState fake_system_state;
1355
1356 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1357 SetupPayloadStateWith2Urls(
1358 "Hash6437", true, false, &payload_state, &response);
1359
1360 // Mock the request to a request where the delta was disabled.
1361 OmahaRequestParams params(&fake_system_state);
1362 params.set_delta_okay(false);
1363 fake_system_state.set_request_params(¶ms);
1364
1365 // Simulate a successful download and update.
1366 payload_state.DownloadComplete();
1367
1368 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1369 ReportSuccessfulUpdateMetrics(
1370 _, _, kPayloadTypeForcedFull, _, _, _, _, _, _, _));
1371 payload_state.UpdateSucceeded();
1372 }
1373
TEST(PayloadStateTest,PayloadTypeMetricWhenTypeIsFull)1374 TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
1375 OmahaResponse response;
1376 PayloadState payload_state;
1377 FakeSystemState fake_system_state;
1378
1379 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1380 SetupPayloadStateWith2Urls(
1381 "Hash6437", true, false, &payload_state, &response);
1382
1383 // Mock the request to a request where the delta is enabled, although the
1384 // result is full.
1385 OmahaRequestParams params(&fake_system_state);
1386 params.set_delta_okay(true);
1387 fake_system_state.set_request_params(¶ms);
1388
1389 // Simulate a successful download and update.
1390 payload_state.DownloadComplete();
1391
1392 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1393 ReportSuccessfulUpdateMetrics(
1394 _, _, kPayloadTypeFull, _, _, _, _, _, _, _));
1395 payload_state.UpdateSucceeded();
1396 }
1397
TEST(PayloadStateTest,RebootAfterUpdateFailedMetric)1398 TEST(PayloadStateTest, RebootAfterUpdateFailedMetric) {
1399 FakeSystemState fake_system_state;
1400 OmahaResponse response;
1401 PayloadState payload_state;
1402 FakePrefs fake_prefs;
1403 fake_system_state.set_prefs(&fake_prefs);
1404
1405 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1406 SetupPayloadStateWith2Urls(
1407 "Hash3141", true, false, &payload_state, &response);
1408
1409 // Simulate a successful download and update.
1410 payload_state.DownloadComplete();
1411 payload_state.UpdateSucceeded();
1412 payload_state.ExpectRebootInNewVersion("Version:12345678");
1413
1414 // Reboot into the same environment to get an UMA metric with a value of 1.
1415 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1416 ReportFailedUpdateCount(1));
1417 payload_state.ReportFailedBootIfNeeded();
1418 Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter());
1419
1420 // Simulate a second update and reboot into the same environment, this should
1421 // send a value of 2.
1422 payload_state.ExpectRebootInNewVersion("Version:12345678");
1423
1424 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1425 ReportFailedUpdateCount(2));
1426 payload_state.ReportFailedBootIfNeeded();
1427 Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter());
1428
1429 // Simulate a third failed reboot to new version, but this time for a
1430 // different payload. This should send a value of 1 this time.
1431 payload_state.ExpectRebootInNewVersion("Version:3141592");
1432 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1433 ReportFailedUpdateCount(1));
1434 payload_state.ReportFailedBootIfNeeded();
1435 Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter());
1436 }
1437
TEST(PayloadStateTest,RebootAfterUpdateSucceed)1438 TEST(PayloadStateTest, RebootAfterUpdateSucceed) {
1439 FakeSystemState fake_system_state;
1440 OmahaResponse response;
1441 PayloadState payload_state;
1442 FakePrefs fake_prefs;
1443 fake_system_state.set_prefs(&fake_prefs);
1444
1445 FakeBootControl* fake_boot_control = fake_system_state.fake_boot_control();
1446 fake_boot_control->SetCurrentSlot(0);
1447
1448 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1449 SetupPayloadStateWith2Urls(
1450 "Hash3141", true, false, &payload_state, &response);
1451
1452 // Simulate a successful download and update.
1453 payload_state.DownloadComplete();
1454 payload_state.UpdateSucceeded();
1455 payload_state.ExpectRebootInNewVersion("Version:12345678");
1456
1457 // Change the BootDevice to a different one, no metric should be sent.
1458 fake_boot_control->SetCurrentSlot(1);
1459
1460 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1461 ReportFailedUpdateCount(_))
1462 .Times(0);
1463 payload_state.ReportFailedBootIfNeeded();
1464
1465 // A second reboot in either partition should not send a metric.
1466 payload_state.ReportFailedBootIfNeeded();
1467 fake_boot_control->SetCurrentSlot(0);
1468 payload_state.ReportFailedBootIfNeeded();
1469 }
1470
TEST(PayloadStateTest,RebootAfterCanceledUpdate)1471 TEST(PayloadStateTest, RebootAfterCanceledUpdate) {
1472 FakeSystemState fake_system_state;
1473 OmahaResponse response;
1474 PayloadState payload_state;
1475 FakePrefs fake_prefs;
1476
1477 fake_system_state.set_prefs(&fake_prefs);
1478 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1479 SetupPayloadStateWith2Urls(
1480 "Hash3141", true, false, &payload_state, &response);
1481
1482 // Simulate a successful download and update.
1483 payload_state.DownloadComplete();
1484 payload_state.UpdateSucceeded();
1485 payload_state.ExpectRebootInNewVersion("Version:12345678");
1486
1487 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1488 ReportFailedUpdateCount(_))
1489 .Times(0);
1490
1491 // Cancel the applied update.
1492 payload_state.ResetUpdateStatus();
1493
1494 // Simulate a reboot.
1495 payload_state.ReportFailedBootIfNeeded();
1496 }
1497
TEST(PayloadStateTest,UpdateSuccessWithWipedPrefs)1498 TEST(PayloadStateTest, UpdateSuccessWithWipedPrefs) {
1499 FakeSystemState fake_system_state;
1500 PayloadState payload_state;
1501 FakePrefs fake_prefs;
1502
1503 fake_system_state.set_prefs(&fake_prefs);
1504 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1505
1506 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
1507 ReportFailedUpdateCount(_))
1508 .Times(0);
1509
1510 // Simulate a reboot in this environment.
1511 payload_state.ReportFailedBootIfNeeded();
1512 }
1513
TEST(PayloadStateTest,DisallowP2PAfterTooManyAttempts)1514 TEST(PayloadStateTest, DisallowP2PAfterTooManyAttempts) {
1515 OmahaResponse response;
1516 PayloadState payload_state;
1517 FakeSystemState fake_system_state;
1518 FakePrefs fake_prefs;
1519 fake_system_state.set_prefs(&fake_prefs);
1520
1521 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1522 SetupPayloadStateWith2Urls(
1523 "Hash8593", true, false, &payload_state, &response);
1524
1525 // Should allow exactly kMaxP2PAttempts...
1526 for (int n = 0; n < kMaxP2PAttempts; n++) {
1527 payload_state.P2PNewAttempt();
1528 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1529 }
1530 // ... but not more than that.
1531 payload_state.P2PNewAttempt();
1532 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1533 }
1534
TEST(PayloadStateTest,DisallowP2PAfterDeadline)1535 TEST(PayloadStateTest, DisallowP2PAfterDeadline) {
1536 OmahaResponse response;
1537 PayloadState payload_state;
1538 FakeSystemState fake_system_state;
1539 FakeClock fake_clock;
1540 FakePrefs fake_prefs;
1541
1542 fake_system_state.set_clock(&fake_clock);
1543 fake_system_state.set_prefs(&fake_prefs);
1544 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1545 SetupPayloadStateWith2Urls(
1546 "Hash8593", true, false, &payload_state, &response);
1547
1548 // Set the clock to 1 second.
1549 Time epoch = Time::FromInternalValue(1000000);
1550 fake_clock.SetWallclockTime(epoch);
1551
1552 // Do an attempt - this will set the timestamp.
1553 payload_state.P2PNewAttempt();
1554
1555 // Check that the timestamp equals what we just set.
1556 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1557
1558 // Time hasn't advanced - this should work.
1559 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1560
1561 // Set clock to half the deadline - this should work.
1562 fake_clock.SetWallclockTime(
1563 epoch + TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds) / 2);
1564 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1565
1566 // Check that the first attempt timestamp hasn't changed just
1567 // because the wall-clock time changed.
1568 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1569
1570 // Set clock to _just_ before the deadline - this should work.
1571 fake_clock.SetWallclockTime(
1572 epoch + TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds - 1));
1573 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1574
1575 // Set clock to _just_ after the deadline - this should not work.
1576 fake_clock.SetWallclockTime(
1577 epoch + TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds + 1));
1578 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1579 }
1580
TEST(PayloadStateTest,P2PStateVarsInitialValue)1581 TEST(PayloadStateTest, P2PStateVarsInitialValue) {
1582 OmahaResponse response;
1583 PayloadState payload_state;
1584 FakeSystemState fake_system_state;
1585 FakePrefs fake_prefs;
1586
1587 fake_system_state.set_prefs(&fake_prefs);
1588 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1589 SetupPayloadStateWith2Urls(
1590 "Hash8593", true, false, &payload_state, &response);
1591
1592 Time null_time = Time();
1593 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1594 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1595 }
1596
TEST(PayloadStateTest,P2PStateVarsArePersisted)1597 TEST(PayloadStateTest, P2PStateVarsArePersisted) {
1598 OmahaResponse response;
1599 PayloadState payload_state;
1600 FakeSystemState fake_system_state;
1601 FakeClock fake_clock;
1602 FakePrefs fake_prefs;
1603 fake_system_state.set_clock(&fake_clock);
1604 fake_system_state.set_prefs(&fake_prefs);
1605 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1606 SetupPayloadStateWith2Urls(
1607 "Hash8593", true, false, &payload_state, &response);
1608
1609 // Set the clock to something known.
1610 Time time = Time::FromInternalValue(12345);
1611 fake_clock.SetWallclockTime(time);
1612
1613 // New p2p attempt - as a side-effect this will update the p2p state vars.
1614 payload_state.P2PNewAttempt();
1615 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1616 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1617
1618 // Now create a new PayloadState and check that it loads the state
1619 // vars correctly.
1620 PayloadState payload_state2;
1621 EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
1622 EXPECT_EQ(1, payload_state2.GetP2PNumAttempts());
1623 EXPECT_EQ(time, payload_state2.GetP2PFirstAttemptTimestamp());
1624 }
1625
TEST(PayloadStateTest,P2PStateVarsAreClearedOnNewResponse)1626 TEST(PayloadStateTest, P2PStateVarsAreClearedOnNewResponse) {
1627 OmahaResponse response;
1628 PayloadState payload_state;
1629 FakeSystemState fake_system_state;
1630 FakeClock fake_clock;
1631 FakePrefs fake_prefs;
1632 fake_system_state.set_clock(&fake_clock);
1633 fake_system_state.set_prefs(&fake_prefs);
1634
1635 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1636 SetupPayloadStateWith2Urls(
1637 "Hash8593", true, false, &payload_state, &response);
1638
1639 // Set the clock to something known.
1640 Time time = Time::FromInternalValue(12345);
1641 fake_clock.SetWallclockTime(time);
1642
1643 // New p2p attempt - as a side-effect this will update the p2p state vars.
1644 payload_state.P2PNewAttempt();
1645 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1646 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1647
1648 // Set a new response...
1649 SetupPayloadStateWith2Urls(
1650 "Hash9904", true, false, &payload_state, &response);
1651
1652 // ... and check that it clears the P2P state vars.
1653 Time null_time = Time();
1654 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1655 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1656 }
1657
1658 } // namespace chromeos_update_engine
1659