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