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