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