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