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