blob: 3071a6b4bba99483da7c385cd3eda3aafcedcd5e [file] [log] [blame]
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <glib.h>
6
Alex Vakulenko75039d72014-03-25 12:36:28 -07007#include <base/files/file_path.h>
Chris Sosabe45bef2013-04-09 18:25:12 -07008#include "base/file_util.h"
Alex Vakulenko75039d72014-03-25 12:36:28 -07009#include <base/strings/stringprintf.h>
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080010#include "gmock/gmock.h"
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080011#include "gtest/gtest.h"
12
Jay Srinivasand29695d2013-04-08 15:08:05 -070013#include "update_engine/constants.h"
David Zeuthenf413fe52013-04-22 14:04:39 -070014#include "update_engine/fake_clock.h"
Alex Deymo42432912013-07-12 20:21:15 -070015#include "update_engine/fake_hardware.h"
David Zeuthen4e1d1492014-04-25 13:12:27 -070016#include "update_engine/fake_prefs.h"
Gilad Arnold5bb4c902014-04-10 12:32:13 -070017#include "update_engine/fake_system_state.h"
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080018#include "update_engine/omaha_request_action.h"
19#include "update_engine/payload_state.h"
David Zeuthenf413fe52013-04-22 14:04:39 -070020#include "update_engine/prefs.h"
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080021#include "update_engine/prefs_mock.h"
22#include "update_engine/test_utils.h"
23#include "update_engine/utils.h"
24
Jay Srinivasan08262882012-12-28 19:29:43 -080025using base::Time;
26using base::TimeDelta;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080027using std::string;
28using testing::_;
Alex Deymo42432912013-07-12 20:21:15 -070029using testing::AnyNumber;
30using testing::AtLeast;
31using testing::Mock;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080032using testing::NiceMock;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080033using testing::Return;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080034using testing::SetArgumentPointee;
35
36namespace chromeos_update_engine {
37
Jay Srinivasan19409b72013-04-12 19:23:36 -070038const char* kCurrentBytesDownloadedFromHttps =
39 "current-bytes-downloaded-from-HttpsServer";
40const char* kTotalBytesDownloadedFromHttps =
41 "total-bytes-downloaded-from-HttpsServer";
42const char* kCurrentBytesDownloadedFromHttp =
43 "current-bytes-downloaded-from-HttpServer";
44const char* kTotalBytesDownloadedFromHttp =
45 "total-bytes-downloaded-from-HttpServer";
David Zeuthenbb8bdc72013-09-03 13:43:48 -070046const char* kCurrentBytesDownloadedFromHttpPeer =
47 "current-bytes-downloaded-from-HttpPeer";
48const char* kTotalBytesDownloadedFromHttpPeer =
49 "total-bytes-downloaded-from-HttpPeer";
Jay Srinivasan19409b72013-04-12 19:23:36 -070050
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080051static void SetupPayloadStateWith2Urls(string hash,
Jay Srinivasan53173b92013-05-17 17:13:01 -070052 bool http_enabled,
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080053 PayloadState* payload_state,
54 OmahaResponse* response) {
55 response->payload_urls.clear();
56 response->payload_urls.push_back("http://test");
57 response->payload_urls.push_back("https://test");
58 response->size = 523456789;
59 response->hash = hash;
60 response->metadata_size = 558123;
61 response->metadata_signature = "metasign";
62 response->max_failure_count_per_url = 3;
63 payload_state->SetResponse(*response);
Jay Srinivasan08262882012-12-28 19:29:43 -080064 string stored_response_sign = payload_state->GetResponseSignature();
Jay Srinivasan53173b92013-05-17 17:13:01 -070065
66 string expected_url_https_only =
67 "NumURLs = 1\n"
68 "Candidate Url0 = https://test\n";
69
70 string expected_urls_both =
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080071 "NumURLs = 2\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -070072 "Candidate Url0 = http://test\n"
73 "Candidate Url1 = https://test\n";
74
75 string expected_response_sign =
76 (http_enabled ? expected_urls_both : expected_url_https_only) +
Alex Vakulenko75039d72014-03-25 12:36:28 -070077 base::StringPrintf("Payload Size = 523456789\n"
78 "Payload Sha256 Hash = %s\n"
79 "Metadata Size = 558123\n"
80 "Metadata Signature = metasign\n"
81 "Is Delta Payload = %d\n"
82 "Max Failure Count Per Url = %d\n"
83 "Disable Payload Backoff = %d\n",
84 hash.c_str(),
85 response->is_delta_payload,
86 response->max_failure_count_per_url,
87 response->disable_payload_backoff);
Jay Srinivasan08262882012-12-28 19:29:43 -080088 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080089}
90
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080091class PayloadStateTest : public ::testing::Test { };
92
David Zeuthena99981f2013-04-29 13:42:47 -070093TEST(PayloadStateTest, DidYouAddANewErrorCode) {
Don Garrett4d039442013-10-28 18:40:06 -070094 if (kErrorCodeUmaReportedMax != 46) {
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080095 LOG(ERROR) << "The following failure is intentional. If you added a new "
David Zeuthena99981f2013-04-29 13:42:47 -070096 << "ErrorCode enum value, make sure to add it to the "
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080097 << "PayloadState::UpdateFailed method and then update this test "
David Zeuthena99981f2013-04-29 13:42:47 -070098 << "to the new value of kErrorCodeUmaReportedMax, which is "
99 << kErrorCodeUmaReportedMax;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800100 EXPECT_FALSE("Please see the log line above");
101 }
102}
103
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800104TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
105 OmahaResponse response;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700106 FakeSystemState fake_system_state;
107 NiceMock<PrefsMock>* prefs = fake_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700108 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700109 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
110 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700111 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
112 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700113 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));
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700125 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
126 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700127 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800128 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700129 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800130 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800131 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);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700141 EXPECT_EQ("", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800142 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700143 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700144 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800145}
146
147TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
148 OmahaResponse response;
Jay Srinivasan53173b92013-05-17 17:13:01 -0700149 response.payload_urls.push_back("https://single.url.test");
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800150 response.size = 123456789;
151 response.hash = "hash";
152 response.metadata_size = 58123;
153 response.metadata_signature = "msign";
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700154 FakeSystemState fake_system_state;
155 NiceMock<PrefsMock>* prefs = fake_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700156 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700157 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
158 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700159 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
160 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700161 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));
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700175 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
176 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700177 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
178 .Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800179 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700180 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800181 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800182 string stored_response_sign = payload_state.GetResponseSignature();
183 string expected_response_sign = "NumURLs = 1\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -0700184 "Candidate Url0 = https://single.url.test\n"
Jay Srinivasan08262882012-12-28 19:29:43 -0800185 "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);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700193 EXPECT_EQ("https://single.url.test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800194 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700195 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700196 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800197}
198
199TEST(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";
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700207 FakeSystemState fake_system_state;
208 NiceMock<PrefsMock>* prefs = fake_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700209 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700210 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
211 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700212 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
213 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700214 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));
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700224 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
225 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700226 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
227 .Times(AtLeast(1));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700228
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800229 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700230 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800231 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800232 string stored_response_sign = payload_state.GetResponseSignature();
233 string expected_response_sign = "NumURLs = 2\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -0700234 "Candidate Url0 = http://multiple.url.test\n"
235 "Candidate Url1 = https://multiple.url.test\n"
Jay Srinivasan08262882012-12-28 19:29:43 -0800236 "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);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700244 EXPECT_EQ("http://multiple.url.test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800245 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700246 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700247 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800248}
249
250TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
251 OmahaResponse response;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700252 FakeSystemState fake_system_state;
253 NiceMock<PrefsMock>* prefs = fake_system_state.mock_prefs();
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800254 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800255
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700256 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800257 // Payload attempt should start with 0 and then advance to 1.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700258 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
259 .Times(AtLeast(1));
260 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
261 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700262 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
263 .Times(AtLeast(1));
264 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
265 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700266 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
David Zeuthen9a017f22013-04-11 16:10:26 -0700267
Chris Sosabe45bef2013-04-09 18:25:12 -0700268 // Reboots will be set
269 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1));
270
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800271 // Url index should go from 0 to 1 twice.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700272 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
273 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800274
275 // Failure count should be called each times url index is set, so that's
276 // 4 times for this test.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700277 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
278 .Times(AtLeast(4));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800279
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700280 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800281
282 // This does a SetResponse which causes all the states to be set to 0 for
283 // the first time.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700284 SetupPayloadStateWith2Urls("Hash1235", true, &payload_state, &response);
285 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800286
287 // Verify that on the first error, the URL index advances to 1.
David Zeuthena99981f2013-04-29 13:42:47 -0700288 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800289 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700290 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800291
292 // Verify that on the next error, the URL index wraps around to 0.
293 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700294 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800295
296 // Verify that on the next error, it again advances to 1.
297 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700298 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
David Zeuthencc6f9962013-04-18 11:57:24 -0700299
300 // Verify that we switched URLs three times
301 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800302}
303
304TEST(PayloadStateTest, NewResponseResetsPayloadState) {
305 OmahaResponse response;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700306 FakeSystemState fake_system_state;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800307 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800308
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700309 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800310
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700311 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
David Zeuthen33bae492014-02-25 16:16:18 -0800312 .Times(AnyNumber());
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700313 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
David Zeuthen33bae492014-02-25 16:16:18 -0800314 .Times(AnyNumber());
315
Alex Deymob33b0f02013-08-08 21:10:02 -0700316 // The first response doesn't send an abandoned event.
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700317 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymob33b0f02013-08-08 21:10:02 -0700318 "Installer.UpdatesAbandonedEventCount", 0, _, _, _)).Times(0);
319
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800320 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700321 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700322 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800323
324 // Advance the URL index to 1 by faking an error.
David Zeuthena99981f2013-04-29 13:42:47 -0700325 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800326 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700327 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
David Zeuthencc6f9962013-04-18 11:57:24 -0700328 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800329
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700330 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymob33b0f02013-08-08 21:10:02 -0700331 "Installer.UpdatesAbandonedEventCount", 1, _, _, _));
332
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800333 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700334 SetupPayloadStateWith2Urls("Hash8225", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700335 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800336
Alex Deymob33b0f02013-08-08 21:10:02 -0700337 // Fake an error again.
338 payload_state.UpdateFailed(error);
339 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
340 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
341
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700342 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymob33b0f02013-08-08 21:10:02 -0700343 "Installer.UpdatesAbandonedEventCount", 2, _, _, _));
344
345 // Return a third different response.
346 SetupPayloadStateWith2Urls("Hash9999", true, &payload_state, &response);
347 EXPECT_EQ(3, payload_state.GetNumResponsesSeen());
348
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800349 // Make sure the url index was reset to 0 because of the new response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700350 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800351 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700352 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700353 EXPECT_EQ(0,
354 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
355 EXPECT_EQ(0,
356 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
357 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
358 kDownloadSourceHttpsServer));
359 EXPECT_EQ(0,
360 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800361}
362
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800363TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
364 OmahaResponse response;
365 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700366 FakeSystemState fake_system_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700367 int progress_bytes = 100;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700368 NiceMock<PrefsMock>* prefs = fake_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800369
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700370 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700371 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
372 .Times(AtLeast(2));
373 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
374 .Times(AtLeast(1));
375 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
376 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800377
Alex Deymo820cc702013-06-28 15:43:46 -0700378 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
379 .Times(AtLeast(2));
380 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
381 .Times(AtLeast(1));
382 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 2))
383 .Times(AtLeast(1));
384
Jay Srinivasan19409b72013-04-12 19:23:36 -0700385 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
Jay Srinivasan08262882012-12-28 19:29:43 -0800386
Jay Srinivasan19409b72013-04-12 19:23:36 -0700387 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
388 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800389
Jay Srinivasan19409b72013-04-12 19:23:36 -0700390 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
391 .Times(AtLeast(7));
392 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
393 .Times(AtLeast(2));
394 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
395 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800396
Jay Srinivasan19409b72013-04-12 19:23:36 -0700397 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
398 .Times(AtLeast(1));
399 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
400 .Times(AtLeast(1));
David Zeuthen9a017f22013-04-11 16:10:26 -0700401
Jay Srinivasan19409b72013-04-12 19:23:36 -0700402 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
403 .Times(AtLeast(1));
404 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
405 .Times(AtLeast(1));
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700406 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
407 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700408 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
409 .Times(AtLeast(1));
410 EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
411 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700412 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
413 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700414
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700415 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800416
Jay Srinivasan53173b92013-05-17 17:13:01 -0700417 SetupPayloadStateWith2Urls("Hash5873", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700418 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800419
420 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700421 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800422 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700423 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700424 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800425 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700426 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800427
428 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700429 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800430 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700431 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700432 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800433 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700434 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800435
436 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700437 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800438 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700439 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700440 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800441 EXPECT_EQ(2, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700442 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800443
444 // This should advance the URL index as we've reached the
445 // max failure count and reset the failure count for the new URL index.
446 // This should also wrap around the URL index and thus cause the payload
447 // attempt number to be incremented.
David Zeuthena99981f2013-04-29 13:42:47 -0700448 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800449 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700450 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700451 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800452 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700453 EXPECT_EQ(2, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800454 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800455
456 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700457 payload_state.UpdateFailed(kErrorCodePayloadHashMismatchError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800458 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700459 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700460 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800461 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700462 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800463 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800464
465 // This should advance the URL index and payload attempt number due to
466 // wrap-around of URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700467 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMissingError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800468 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700469 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700470 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800471 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700472 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800473 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800474
475 // This HTTP error code should only increase the failure count.
David Zeuthena99981f2013-04-29 13:42:47 -0700476 payload_state.UpdateFailed(static_cast<ErrorCode>(
477 kErrorCodeOmahaRequestHTTPResponseBase + 404));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800478 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700479 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700480 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800481 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700482 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800483 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800484
485 // And that failure count should be reset when we download some bytes
486 // afterwards.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700487 payload_state.DownloadProgress(progress_bytes);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800488 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700489 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700490 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800491 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700492 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800493 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800494
495 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700496 SetupPayloadStateWith2Urls("Hash8532", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700497 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800498
499 // Make sure the url index was reset to 0 because of the new response.
500 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700501 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700502 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800503 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700504 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800505 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800506}
507
Alex Deymo820cc702013-06-28 15:43:46 -0700508TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulFullDownload) {
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800509 OmahaResponse response;
Alex Deymo820cc702013-06-28 15:43:46 -0700510 response.is_delta_payload = false;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800511 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700512 FakeSystemState fake_system_state;
513 NiceMock<PrefsMock>* prefs = fake_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800514
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700515 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700516 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
517 .Times(AtLeast(1));
518 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
519 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800520
Alex Deymo820cc702013-06-28 15:43:46 -0700521 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
522 .Times(AtLeast(1));
523 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
524 .Times(AtLeast(1));
525
Jay Srinivasan19409b72013-04-12 19:23:36 -0700526 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
527 .Times(AtLeast(2));
Jay Srinivasan08262882012-12-28 19:29:43 -0800528
Jay Srinivasan19409b72013-04-12 19:23:36 -0700529 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
530 .Times(AtLeast(1));
531 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
532 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800533
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700534 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800535
Jay Srinivasan53173b92013-05-17 17:13:01 -0700536 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800537
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700538 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo29b51d92013-07-09 15:26:24 -0700539 "Installer.PayloadAttemptNumber", 1, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700540 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo29b51d92013-07-09 15:26:24 -0700541 "Installer.FullPayloadAttemptNumber", 1, _, _, _));
542
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800543 // This should just advance the payload attempt number;
544 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700545 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800546 payload_state.DownloadComplete();
547 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700548 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
549 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
550 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
551 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
552}
553
554TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDeltaDownload) {
555 OmahaResponse response;
556 response.is_delta_payload = true;
557 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700558 FakeSystemState fake_system_state;
559 NiceMock<PrefsMock>* prefs = fake_system_state.mock_prefs();
Alex Deymo820cc702013-06-28 15:43:46 -0700560
561 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
562 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
563 .Times(AtLeast(1));
564 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
565 .Times(AtLeast(1));
566
567 // kPrefsFullPayloadAttemptNumber is not incremented for delta payloads.
568 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
569 .Times(AtLeast(1));
570
571 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
572 .Times(1);
573
574 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
575 .Times(AtLeast(1));
576 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
577 .Times(AtLeast(1));
578
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700579 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo820cc702013-06-28 15:43:46 -0700580
581 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
582
Alex Deymo29b51d92013-07-09 15:26:24 -0700583 // Metrics for Full payload attempt number is not sent with Delta payloads.
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700584 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo29b51d92013-07-09 15:26:24 -0700585 "Installer.PayloadAttemptNumber", 1, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700586 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo29b51d92013-07-09 15:26:24 -0700587 "Installer.FullPayloadAttemptNumber", _, _, _, _))
588 .Times(0);
589
Alex Deymo820cc702013-06-28 15:43:46 -0700590 // This should just advance the payload attempt number;
591 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
592 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
593 payload_state.DownloadComplete();
594 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
595 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700596 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800597 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700598 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800599}
600
601TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
602 OmahaResponse response;
603 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700604 FakeSystemState fake_system_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800605
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700606 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700607 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800608
609 // Generate enough events to advance URL index, failure count and
610 // payload attempt number all to 1.
611 payload_state.DownloadComplete();
David Zeuthena99981f2013-04-29 13:42:47 -0700612 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
613 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800614 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700615 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700616 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800617 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700618 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800619
620 // Now, simulate a corrupted url index on persisted store which gets
621 // loaded when update_engine restarts. Using a different prefs object
622 // so as to not bother accounting for the uninteresting calls above.
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700623 FakeSystemState fake_system_state2;
624 NiceMock<PrefsMock>* prefs2 = fake_system_state2.mock_prefs();
Jay Srinivasan19409b72013-04-12 19:23:36 -0700625 EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
626 EXPECT_CALL(*prefs2, GetInt64(_,_)).Times(AtLeast(1));
627 EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
628 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700629 EXPECT_CALL(*prefs2, GetInt64(kPrefsFullPayloadAttemptNumber, _))
630 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700631 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
632 .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
633 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
634 .Times(AtLeast(1));
David Zeuthencc6f9962013-04-18 11:57:24 -0700635 EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _))
636 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800637
638 // Note: This will be a different payload object, but the response should
639 // have the same hash as before so as to not trivially reset because the
640 // response was different. We want to specifically test that even if the
641 // response is same, we should reset the state if we find it corrupted.
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700642 EXPECT_TRUE(payload_state.Initialize(&fake_system_state2));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700643 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800644
645 // Make sure all counters get reset to 0 because of the corrupted URL index
646 // we supplied above.
647 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700648 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700649 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800650 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700651 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800652}
Jay Srinivasan08262882012-12-28 19:29:43 -0800653
Chris Sosa20f005c2013-09-05 13:53:08 -0700654TEST(PayloadStateTest, NoBackoffInteractiveChecks) {
655 OmahaResponse response;
656 response.is_delta_payload = false;
657 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700658 FakeSystemState fake_system_state;
659 OmahaRequestParams params(&fake_system_state);
Chris Sosa20f005c2013-09-05 13:53:08 -0700660 params.Init("", "", true); // is_interactive = True.
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700661 fake_system_state.set_request_params(&params);
Chris Sosa20f005c2013-09-05 13:53:08 -0700662
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700663 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Chris Sosa20f005c2013-09-05 13:53:08 -0700664 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
665
666 // Simulate two failures (enough to cause payload backoff) and check
667 // again that we're ready to re-download without any backoff as this is
668 // an interactive check.
669 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
670 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
671 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
672 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
673 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
674 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
675}
676
677TEST(PayloadStateTest, NoBackoffForP2PUpdates) {
678 OmahaResponse response;
679 response.is_delta_payload = false;
680 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700681 FakeSystemState fake_system_state;
682 OmahaRequestParams params(&fake_system_state);
Chris Sosa20f005c2013-09-05 13:53:08 -0700683 params.Init("", "", false); // is_interactive = False.
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700684 fake_system_state.set_request_params(&params);
Chris Sosa20f005c2013-09-05 13:53:08 -0700685
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700686 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Chris Sosa20f005c2013-09-05 13:53:08 -0700687 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
688
689 // Simulate two failures (enough to cause payload backoff) and check
690 // again that we're ready to re-download without any backoff as this is
691 // an interactive check.
692 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
693 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
694 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
695 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
696 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
697 // Set p2p url.
698 params.set_use_p2p_for_downloading(true);
699 params.set_p2p_url("http://mypeer:52909/path/to/file");
700 // Should not backoff for p2p updates.
701 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
702
703 params.set_p2p_url("");
704 // No actual p2p update if no url is provided.
705 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
706}
707
Jay Srinivasan08262882012-12-28 19:29:43 -0800708TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
709 OmahaResponse response;
710 response.is_delta_payload = true;
711 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700712 FakeSystemState fake_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800713
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700714 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700715 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800716
717 // Simulate a successful download and see that we're ready to download
718 // again without any backoff as this is a delta payload.
719 payload_state.DownloadComplete();
Alex Deymo820cc702013-06-28 15:43:46 -0700720 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
721 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800722 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
723
724 // Simulate two failures (enough to cause payload backoff) and check
725 // again that we're ready to re-download without any backoff as this is
726 // a delta payload.
David Zeuthena99981f2013-04-29 13:42:47 -0700727 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
728 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700729 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Alex Deymo820cc702013-06-28 15:43:46 -0700730 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
731 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800732 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
733}
734
735static void CheckPayloadBackoffState(PayloadState* payload_state,
736 int expected_attempt_number,
737 TimeDelta expected_days) {
738 payload_state->DownloadComplete();
Alex Deymo820cc702013-06-28 15:43:46 -0700739 EXPECT_EQ(expected_attempt_number,
740 payload_state->GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800741 EXPECT_TRUE(payload_state->ShouldBackoffDownload());
742 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
743 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
744 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
745 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
746 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
747 EXPECT_LT(expected_min_time.ToInternalValue(),
748 backoff_expiry_time.ToInternalValue());
749 EXPECT_GT(expected_max_time.ToInternalValue(),
750 backoff_expiry_time.ToInternalValue());
751}
752
753TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
754 OmahaResponse response;
755 response.is_delta_payload = false;
756 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700757 FakeSystemState fake_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800758
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700759 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700760 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800761
762 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
763 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
764 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
765 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
766 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
767 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
768 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
769 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
770 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
771 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
772}
773
774TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
775 OmahaResponse response;
776 response.disable_payload_backoff = true;
777 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700778 FakeSystemState fake_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800779
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700780 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700781 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800782
783 // Simulate a successful download and see that we are ready to download
784 // again without any backoff.
785 payload_state.DownloadComplete();
786 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700787 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800788 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
789
790 // Test again, this time by simulating two errors that would cause
791 // the payload attempt number to increment due to wrap around. And
792 // check that we are still ready to re-download without any backoff.
David Zeuthena99981f2013-04-29 13:42:47 -0700793 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
794 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan08262882012-12-28 19:29:43 -0800795 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700796 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800797 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
798}
799
Jay Srinivasan19409b72013-04-12 19:23:36 -0700800TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
801 OmahaResponse response;
802 response.disable_payload_backoff = true;
803 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700804 FakeSystemState fake_system_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700805 int https_total = 0;
806 int http_total = 0;
807
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700808 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700809 SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700810 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700811
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700812 // Simulate a previous attempt with in order to set an initial non-zero value
813 // for the total bytes downloaded for HTTP.
814 int prev_chunk = 323456789;
815 http_total += prev_chunk;
816 payload_state.DownloadProgress(prev_chunk);
817
818 // Ensure that the initial values for HTTP reflect this attempt.
819 EXPECT_EQ(prev_chunk,
820 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
821 EXPECT_EQ(http_total,
822 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
823
824 // Change the response hash so as to simulate a new response which will
825 // reset the current bytes downloaded, but not the total bytes downloaded.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700826 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700827 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700828
829 // First, simulate successful download of a few bytes over HTTP.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700830 int first_chunk = 5000000;
831 http_total += first_chunk;
832 payload_state.DownloadProgress(first_chunk);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700833 // Test that first all progress is made on HTTP and none on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700834 EXPECT_EQ(first_chunk,
835 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
836 EXPECT_EQ(http_total,
837 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
838 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
839 kDownloadSourceHttpsServer));
840 EXPECT_EQ(https_total,
841 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
842
843 // Simulate an error that'll cause the url index to point to https.
David Zeuthena99981f2013-04-29 13:42:47 -0700844 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700845 payload_state.UpdateFailed(error);
846
Jay Srinivasan53173b92013-05-17 17:13:01 -0700847 // Test that no new progress is made on HTTP and new progress is on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700848 int second_chunk = 23456789;
849 https_total += second_chunk;
850 payload_state.DownloadProgress(second_chunk);
851 EXPECT_EQ(first_chunk,
852 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
853 EXPECT_EQ(http_total,
854 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
855 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
856 kDownloadSourceHttpsServer));
857 EXPECT_EQ(https_total,
858 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
859
860 // Simulate error to go back to http.
861 payload_state.UpdateFailed(error);
862 int third_chunk = 32345678;
863 int http_chunk = first_chunk + third_chunk;
864 http_total += third_chunk;
865 int https_chunk = second_chunk;
866 payload_state.DownloadProgress(third_chunk);
867
868 // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
869 EXPECT_EQ(http_chunk,
870 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700871 EXPECT_EQ(http_total,
Jay Srinivasan19409b72013-04-12 19:23:36 -0700872 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
873 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
874 kDownloadSourceHttpsServer));
875 EXPECT_EQ(https_total,
876 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
877
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700878 // Simulate error (will cause URL switch), set p2p is to be used and
879 // then do 42MB worth of progress
880 payload_state.UpdateFailed(error);
881 payload_state.SetUsingP2PForDownloading(true);
882 int p2p_total = 42 * 1000 * 1000;
883 payload_state.DownloadProgress(p2p_total);
884
885 EXPECT_EQ(p2p_total,
886 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpPeer));
887
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700888 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700889 .Times(AnyNumber());
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700890 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
David Zeuthen33bae492014-02-25 16:16:18 -0800891 .Times(AnyNumber());
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700892 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Jay Srinivasan19409b72013-04-12 19:23:36 -0700893 "Installer.SuccessfulMBsDownloadedFromHttpServer",
894 http_chunk / kNumBytesInOneMiB, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700895 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Jay Srinivasan19409b72013-04-12 19:23:36 -0700896 "Installer.TotalMBsDownloadedFromHttpServer",
897 http_total / kNumBytesInOneMiB, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700898 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Jay Srinivasan19409b72013-04-12 19:23:36 -0700899 "Installer.SuccessfulMBsDownloadedFromHttpsServer",
900 https_chunk / kNumBytesInOneMiB, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700901 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Jay Srinivasan19409b72013-04-12 19:23:36 -0700902 "Installer.TotalMBsDownloadedFromHttpsServer",
903 https_total / kNumBytesInOneMiB, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700904 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700905 "Installer.SuccessfulMBsDownloadedFromHttpPeer",
906 p2p_total / kNumBytesInOneMiB, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700907 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700908 "Installer.TotalMBsDownloadedFromHttpPeer",
909 p2p_total / kNumBytesInOneMiB, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700910 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthencc6f9962013-04-18 11:57:24 -0700911 "Installer.UpdateURLSwitches",
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700912 3, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700913 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -0800914 metrics::kMetricSuccessfulUpdateUrlSwitchCount,
915 3, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700916 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen674c3182013-04-18 14:05:20 -0700917 "Installer.UpdateDurationMinutes",
918 _, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700919 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -0800920 metrics::kMetricSuccessfulUpdateTotalDurationMinutes,
921 _, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700922 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen674c3182013-04-18 14:05:20 -0700923 "Installer.UpdateDurationUptimeMinutes",
924 _, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700925 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700926 "Installer.DownloadSourcesUsed",
927 (1 << kDownloadSourceHttpsServer) | (1 << kDownloadSourceHttpServer) |
928 (1 << kDownloadSourceHttpPeer),
929 _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700930 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700931 "Installer.DownloadOverheadPercentage", 318, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700932 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -0800933 metrics::kMetricSuccessfulUpdateDownloadOverheadPercentage,
934 314, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700935 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
Alex Deymo1c656c42013-06-28 11:02:14 -0700936 "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700937 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -0800938 metrics::kMetricAttemptPayloadType, kPayloadTypeFull, kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700939 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -0800940 metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeFull,
941 kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700942 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo820cc702013-06-28 15:43:46 -0700943 "Installer.AttemptsCount.Total", 1, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700944 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -0800945 metrics::kMetricSuccessfulUpdateAttemptCount, 1, _, _, _));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700946
947 payload_state.UpdateSucceeded();
948
949 // Make sure the metrics are reset after a successful update.
950 EXPECT_EQ(0,
951 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
952 EXPECT_EQ(0,
953 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
954 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
955 kDownloadSourceHttpsServer));
956 EXPECT_EQ(0,
957 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
David Zeuthena573d6f2013-06-14 16:13:36 -0700958 EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700959}
960
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700961TEST(PayloadStateTest, DownloadSourcesUsedIsCorrect) {
962 OmahaResponse response;
963 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700964 FakeSystemState fake_system_state;
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700965
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700966 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700967 SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
968
969 // Simulate progress in order to mark HTTP as one of the sources used.
970 int num_bytes = 42 * 1000 * 1000;
971 payload_state.DownloadProgress(num_bytes);
972
973 // Check that this was done via HTTP.
974 EXPECT_EQ(num_bytes,
975 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
976 EXPECT_EQ(num_bytes,
977 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
978
979 // Check that only HTTP is reported as a download source.
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700980 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700981 .Times(AnyNumber());
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700982 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700983 "Installer.DownloadSourcesUsed",
984 (1 << kDownloadSourceHttpServer),
985 _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700986 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -0800987 metrics::kMetricSuccessfulUpdateDownloadSourcesUsed,
988 (1 << kDownloadSourceHttpServer),
989 _, _, _));
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700990
991 payload_state.UpdateSucceeded();
992}
993
Jay Srinivasan19409b72013-04-12 19:23:36 -0700994TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
995 OmahaResponse response;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700996 FakeSystemState fake_system_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700997 PayloadState payload_state;
998
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700999 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Jay Srinivasan19409b72013-04-12 19:23:36 -07001000
1001 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001002 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
Jay Srinivasan19409b72013-04-12 19:23:36 -07001003
1004 int num_bytes = 10000;
1005 payload_state.DownloadProgress(num_bytes);
1006 EXPECT_EQ(num_bytes,
1007 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
1008 EXPECT_EQ(num_bytes,
1009 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
1010 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
1011 kDownloadSourceHttpsServer));
1012 EXPECT_EQ(0,
1013 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
1014
1015 payload_state.UpdateRestarted();
1016 // Make sure the current bytes downloaded is reset, but not the total bytes.
1017 EXPECT_EQ(0,
1018 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
1019 EXPECT_EQ(num_bytes,
1020 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
1021}
1022
Chris Sosabe45bef2013-04-09 18:25:12 -07001023TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001024 FakeSystemState fake_system_state;
Chris Sosabe45bef2013-04-09 18:25:12 -07001025 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -07001026
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001027 NiceMock<PrefsMock>* prefs = fake_system_state.mock_prefs();
Chris Sosabe45bef2013-04-09 18:25:12 -07001028 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
1029 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
1030
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001031 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Chris Sosabe45bef2013-04-09 18:25:12 -07001032
1033 payload_state.UpdateRestarted();
1034 EXPECT_EQ(0, payload_state.GetNumReboots());
1035
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001036 fake_system_state.set_system_rebooted(true);
Chris Sosabe45bef2013-04-09 18:25:12 -07001037 payload_state.UpdateResumed();
1038 // Num reboots should be incremented because system rebooted detected.
1039 EXPECT_EQ(1, payload_state.GetNumReboots());
1040
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001041 fake_system_state.set_system_rebooted(false);
Chris Sosabe45bef2013-04-09 18:25:12 -07001042 payload_state.UpdateResumed();
1043 // Num reboots should now be 1 as reboot was not detected.
1044 EXPECT_EQ(1, payload_state.GetNumReboots());
1045
1046 // Restart the update again to verify we set the num of reboots back to 0.
1047 payload_state.UpdateRestarted();
1048 EXPECT_EQ(0, payload_state.GetNumReboots());
1049}
Jay Srinivasan19409b72013-04-12 19:23:36 -07001050
Chris Sosaaa18e162013-06-20 13:20:30 -07001051TEST(PayloadStateTest, RollbackVersion) {
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001052 FakeSystemState fake_system_state;
Chris Sosaaa18e162013-06-20 13:20:30 -07001053 PayloadState payload_state;
1054
1055 NiceMock<PrefsMock>* mock_powerwash_safe_prefs =
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001056 fake_system_state.mock_powerwash_safe_prefs();
1057 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Chris Sosaaa18e162013-06-20 13:20:30 -07001058
1059 // Verify pre-conditions are good.
1060 EXPECT_TRUE(payload_state.GetRollbackVersion().empty());
1061
1062 // Mock out the os version and make sure it's blacklisted correctly.
1063 string rollback_version = "2345.0.0";
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001064 OmahaRequestParams params(&fake_system_state);
Chris Sosaaa18e162013-06-20 13:20:30 -07001065 params.Init(rollback_version, "", false);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001066 fake_system_state.set_request_params(&params);
Chris Sosaaa18e162013-06-20 13:20:30 -07001067
1068 EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion,
1069 rollback_version));
1070 payload_state.Rollback();
1071
1072 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
Chris Sosab3dcdb32013-09-04 15:22:12 -07001073
1074 // Change it up a little and verify we load it correctly.
1075 rollback_version = "2345.0.1";
1076 // Let's verify we can reload it correctly.
1077 EXPECT_CALL(*mock_powerwash_safe_prefs, GetString(
1078 kPrefsRollbackVersion, _)).WillOnce(DoAll(
1079 SetArgumentPointee<1>(rollback_version), Return(true)));
1080 EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion,
1081 rollback_version));
1082 payload_state.LoadRollbackVersion();
1083 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
David Zeuthenafed4a12014-04-09 15:28:44 -07001084
David Zeuthen96197df2014-04-16 12:22:39 -07001085 // Check that we report only UpdateEngine.Rollback.* metrics in
1086 // UpdateSucceeded().
David Zeuthenafed4a12014-04-09 15:28:44 -07001087 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
1088 .Times(0);
1089 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
1090 .Times(0);
David Zeuthen96197df2014-04-16 12:22:39 -07001091 EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
1092 SendEnumToUMA(
1093 metrics::kMetricRollbackResult,
1094 static_cast<int>(metrics::RollbackResult::kSuccess),
1095 static_cast<int>(metrics::RollbackResult::kNumConstants)));
David Zeuthenafed4a12014-04-09 15:28:44 -07001096 payload_state.UpdateSucceeded();
Chris Sosaaa18e162013-06-20 13:20:30 -07001097}
1098
David Zeuthenf413fe52013-04-22 14:04:39 -07001099TEST(PayloadStateTest, DurationsAreCorrect) {
1100 OmahaResponse response;
1101 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001102 FakeSystemState fake_system_state;
David Zeuthenf413fe52013-04-22 14:04:39 -07001103 FakeClock fake_clock;
1104 Prefs prefs;
1105 string temp_dir;
1106
1107 // Set the clock to a well-known time - 1 second on the wall-clock
1108 // and 2 seconds on the monotonic clock
1109 fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
1110 fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
1111
1112 // We need persistent preferences for this test
Gilad Arnolda6742b32014-01-11 00:18:34 -08001113 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateDurationTests.XXXXXX",
David Zeuthenf413fe52013-04-22 14:04:39 -07001114 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001115 prefs.Init(base::FilePath(temp_dir));
David Zeuthenf413fe52013-04-22 14:04:39 -07001116
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001117 fake_system_state.set_clock(&fake_clock);
1118 fake_system_state.set_prefs(&prefs);
1119 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthenf413fe52013-04-22 14:04:39 -07001120
1121 // Check that durations are correct for a successful update where
1122 // time has advanced 7 seconds on the wall clock and 4 seconds on
1123 // the monotonic clock.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001124 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -07001125 fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
1126 fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
1127 payload_state.UpdateSucceeded();
1128 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
1129 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
1130
1131 // Check that durations are reset when a new response comes in.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001132 SetupPayloadStateWith2Urls("Hash8594", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -07001133 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
1134 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
1135
1136 // Advance time a bit (10 secs), simulate download progress and
1137 // check that durations are updated.
1138 fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
1139 fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
1140 payload_state.DownloadProgress(10);
1141 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
1142 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
1143
1144 // Now simulate a reboot by resetting monotonic time (to 5000) and
1145 // creating a new PayloadState object and check that we load the
1146 // durations correctly (e.g. they are the same as before).
1147 fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
1148 PayloadState payload_state2;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001149 EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
David Zeuthenf413fe52013-04-22 14:04:39 -07001150 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
1151 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),10000000);
1152
1153 // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
1154 // and check that the durations are increased accordingly.
1155 fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
1156 fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
1157 payload_state2.UpdateSucceeded();
1158 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
1159 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),16000000);
1160
1161 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1162}
1163
David Zeuthene4c58bf2013-06-18 17:26:50 -07001164TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
1165 OmahaResponse response;
1166 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001167 FakeSystemState fake_system_state;
David Zeuthene4c58bf2013-06-18 17:26:50 -07001168 FakeClock fake_clock;
1169 Prefs prefs;
1170 string temp_dir;
1171
1172 // Set the clock to a well-known time (t = 30 seconds).
1173 fake_clock.SetWallclockTime(Time::FromInternalValue(
1174 30 * Time::kMicrosecondsPerSecond));
1175
1176 // We need persistent preferences for this test
1177 EXPECT_TRUE(utils::MakeTempDirectory(
Gilad Arnolda6742b32014-01-11 00:18:34 -08001178 "RebootAfterSuccessfulUpdateTest.XXXXXX", &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001179 prefs.Init(base::FilePath(temp_dir));
David Zeuthene4c58bf2013-06-18 17:26:50 -07001180
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001181 fake_system_state.set_clock(&fake_clock);
1182 fake_system_state.set_prefs(&prefs);
1183 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthene4c58bf2013-06-18 17:26:50 -07001184
1185 // Make the update succeed.
1186 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1187 payload_state.UpdateSucceeded();
1188
1189 // Check that the marker was written.
1190 EXPECT_TRUE(prefs.Exists(kPrefsSystemUpdatedMarker));
1191
1192 // Now simulate a reboot and set the wallclock time to a later point
1193 // (t = 500 seconds). We do this by using a new PayloadState object
1194 // and checking that it emits the right UMA metric with the right
1195 // value.
1196 fake_clock.SetWallclockTime(Time::FromInternalValue(
1197 500 * Time::kMicrosecondsPerSecond));
1198 PayloadState payload_state2;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001199 EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
David Zeuthene4c58bf2013-06-18 17:26:50 -07001200
1201 // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001202 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthene4c58bf2013-06-18 17:26:50 -07001203 "Installer.TimeToRebootMinutes",
1204 7, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001205 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001206 metrics::kMetricTimeToRebootMinutes,
1207 7, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001208 fake_system_state.set_system_rebooted(true);
David Zeuthene4c58bf2013-06-18 17:26:50 -07001209
1210 payload_state2.UpdateEngineStarted();
1211
1212 // Check that the marker was nuked.
1213 EXPECT_FALSE(prefs.Exists(kPrefsSystemUpdatedMarker));
1214
1215 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1216}
1217
Alex Deymo569c4242013-07-24 12:01:01 -07001218TEST(PayloadStateTest, RestartAfterCrash) {
1219 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001220 FakeSystemState fake_system_state;
1221 NiceMock<PrefsMock>* prefs = fake_system_state.mock_prefs();
Alex Deymo569c4242013-07-24 12:01:01 -07001222
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001223 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo569c4242013-07-24 12:01:01 -07001224
David Zeuthen4e1d1492014-04-25 13:12:27 -07001225 // Only the |kPrefsAttemptInProgress| state variable should be read.
Alex Deymo569c4242013-07-24 12:01:01 -07001226 EXPECT_CALL(*prefs, Exists(_)).Times(0);
1227 EXPECT_CALL(*prefs, SetString(_, _)).Times(0);
1228 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(0);
1229 EXPECT_CALL(*prefs, SetBoolean(_, _)).Times(0);
1230 EXPECT_CALL(*prefs, GetString(_, _)).Times(0);
1231 EXPECT_CALL(*prefs, GetInt64(_, _)).Times(0);
1232 EXPECT_CALL(*prefs, GetBoolean(_, _)).Times(0);
David Zeuthen4e1d1492014-04-25 13:12:27 -07001233 EXPECT_CALL(*prefs, GetBoolean(kPrefsAttemptInProgress, _));
Alex Deymo569c4242013-07-24 12:01:01 -07001234
1235 // No metrics are reported after a crash.
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001236 EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
Alex Deymo569c4242013-07-24 12:01:01 -07001237 SendToUMA(_, _, _, _, _)).Times(0);
1238
1239 // Simulate an update_engine restart without a reboot.
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001240 fake_system_state.set_system_rebooted(false);
Alex Deymo569c4242013-07-24 12:01:01 -07001241
1242 payload_state.UpdateEngineStarted();
1243}
1244
David Zeuthen4e1d1492014-04-25 13:12:27 -07001245TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsNoReporting) {
1246 PayloadState payload_state;
1247 FakeSystemState fake_system_state;
1248
1249 // If there's no marker at startup, ensure we don't report a metric.
1250 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1251 EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
1252 SendEnumToUMA(
1253 metrics::kMetricAttemptResult,
1254 static_cast<int>(metrics::AttemptResult::kAbnormalTermination),
1255 _)).Times(0);
1256 payload_state.UpdateEngineStarted();
1257}
1258
1259TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsReported) {
1260 PayloadState payload_state;
1261 FakeSystemState fake_system_state;
1262 FakePrefs prefs;
1263
1264 // If we have a marker at startup, ensure it's reported and the
1265 // marker is then cleared.
1266 fake_system_state.set_prefs(&prefs);
1267 prefs.SetBoolean(kPrefsAttemptInProgress, true);
1268
1269 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1270
1271 EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
1272 SendEnumToUMA(
1273 metrics::kMetricAttemptResult,
1274 static_cast<int>(metrics::AttemptResult::kAbnormalTermination),
1275 _)).Times(1);
1276 payload_state.UpdateEngineStarted();
1277
1278 EXPECT_FALSE(prefs.Exists(kPrefsAttemptInProgress));
1279}
1280
1281TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsClearedOnSucceess) {
1282 PayloadState payload_state;
1283 FakeSystemState fake_system_state;
1284 FakePrefs prefs;
1285
1286 // Make sure the marker is written and cleared during an attempt and
1287 // also that we DO NOT emit the metric (since the attempt didn't end
1288 // abnormally).
1289 fake_system_state.set_prefs(&prefs);
1290 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1291
1292 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
1293 .Times(AnyNumber());
1294 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
1295 .Times(AnyNumber());
1296 EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
1297 SendEnumToUMA(
1298 metrics::kMetricAttemptResult,
1299 static_cast<int>(metrics::AttemptResult::kAbnormalTermination),
1300 _)).Times(0);
1301
1302 // Attempt not in progress, should be clear.
1303 EXPECT_FALSE(prefs.Exists(kPrefsAttemptInProgress));
1304
1305 payload_state.UpdateRestarted();
1306
1307 // Attempt not in progress, should be set.
1308 EXPECT_TRUE(prefs.Exists(kPrefsAttemptInProgress));
1309
1310 payload_state.UpdateSucceeded();
1311
1312 // Attempt not in progress, should be clear.
1313 EXPECT_FALSE(prefs.Exists(kPrefsAttemptInProgress));
1314}
1315
Jay Srinivasan53173b92013-05-17 17:13:01 -07001316TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
1317 OmahaResponse response;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001318 FakeSystemState fake_system_state;
Jay Srinivasan53173b92013-05-17 17:13:01 -07001319 PayloadState payload_state;
1320
Jay Srinivasan53173b92013-05-17 17:13:01 -07001321 policy::MockDevicePolicy disable_http_policy;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001322 fake_system_state.set_device_policy(&disable_http_policy);
1323 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Chris Sosaf7d80042013-08-22 16:45:17 -07001324
1325 // Test with no device policy. Should default to allowing http.
1326 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1327 .WillRepeatedly(Return(false));
1328
1329 // Set the first response.
1330 SetupPayloadStateWith2Urls("Hash8433", true, &payload_state, &response);
1331
1332 // Check that we use the HTTP URL since there is no value set for allowing
1333 // http.
1334 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1335
1336 // Test with device policy not allowing http updates.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001337 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1338 .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
1339
Chris Sosaf7d80042013-08-22 16:45:17 -07001340 // Reset state and set again.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001341 SetupPayloadStateWith2Urls("Hash8433", false, &payload_state, &response);
1342
1343 // Check that we skip the HTTP URL and use only the HTTPS url.
1344 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1345
1346 // Advance the URL index to 1 by faking an error.
1347 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
1348 payload_state.UpdateFailed(error);
1349
1350 // Check that we still skip the HTTP URL and use only the HTTPS url.
1351 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1352 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
1353
1354 // Now, slightly change the response and set it again.
1355 SetupPayloadStateWith2Urls("Hash2399", false, &payload_state, &response);
1356
1357 // Check that we still skip the HTTP URL and use only the HTTPS url.
1358 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1359
1360 // Now, pretend that the HTTP policy is turned on. We want to make sure
1361 // the new policy is honored.
1362 policy::MockDevicePolicy enable_http_policy;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001363 fake_system_state.set_device_policy(&enable_http_policy);
Jay Srinivasan53173b92013-05-17 17:13:01 -07001364 EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
1365 .WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
1366
1367 // Now, set the same response using the same hash
1368 // so that we can test that the state is reset not because of the
1369 // hash but because of the policy change which results in candidate url
1370 // list change.
1371 SetupPayloadStateWith2Urls("Hash2399", true, &payload_state, &response);
1372
1373 // Check that we use the HTTP URL now and the failure count is reset.
1374 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1375 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1376
1377 // Fake a failure and see if we're moving over to the HTTPS url and update
1378 // the URL switch count properly.
1379 payload_state.UpdateFailed(error);
1380 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1381 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
1382 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1383}
1384
Alex Deymo1c656c42013-06-28 11:02:14 -07001385TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
1386 OmahaResponse response;
1387 response.is_delta_payload = true;
1388 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001389 FakeSystemState fake_system_state;
Alex Deymo1c656c42013-06-28 11:02:14 -07001390
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001391 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo1c656c42013-06-28 11:02:14 -07001392 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1393
1394 // Simulate a successful download and update.
1395 payload_state.DownloadComplete();
1396
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001397 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
David Zeuthen33bae492014-02-25 16:16:18 -08001398 .Times(AnyNumber());
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001399 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
Alex Deymo1c656c42013-06-28 11:02:14 -07001400 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001401 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001402 metrics::kMetricAttemptPayloadType, kPayloadTypeDelta, kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001403 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001404 metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeDelta,
1405 kNumPayloadTypes));
Alex Deymo1c656c42013-06-28 11:02:14 -07001406 payload_state.UpdateSucceeded();
1407
1408 // Mock the request to a request where the delta was disabled but Omaha sends
1409 // a delta anyway and test again.
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001410 OmahaRequestParams params(&fake_system_state);
Alex Deymo1c656c42013-06-28 11:02:14 -07001411 params.set_delta_okay(false);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001412 fake_system_state.set_request_params(&params);
Alex Deymo1c656c42013-06-28 11:02:14 -07001413
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001414 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo1c656c42013-06-28 11:02:14 -07001415 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1416
1417 payload_state.DownloadComplete();
1418
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001419 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
Alex Deymo1c656c42013-06-28 11:02:14 -07001420 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001421 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001422 metrics::kMetricAttemptPayloadType, kPayloadTypeDelta,
1423 kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001424 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001425 metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeDelta,
1426 kNumPayloadTypes));
Alex Deymo1c656c42013-06-28 11:02:14 -07001427 payload_state.UpdateSucceeded();
1428}
1429
1430TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
1431 OmahaResponse response;
1432 response.is_delta_payload = false;
1433 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001434 FakeSystemState fake_system_state;
Alex Deymo1c656c42013-06-28 11:02:14 -07001435
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001436 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo1c656c42013-06-28 11:02:14 -07001437 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1438
1439 // Mock the request to a request where the delta was disabled.
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001440 OmahaRequestParams params(&fake_system_state);
Alex Deymo1c656c42013-06-28 11:02:14 -07001441 params.set_delta_okay(false);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001442 fake_system_state.set_request_params(&params);
Alex Deymo1c656c42013-06-28 11:02:14 -07001443
1444 // Simulate a successful download and update.
1445 payload_state.DownloadComplete();
1446
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001447 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
David Zeuthen33bae492014-02-25 16:16:18 -08001448 .Times(AnyNumber());
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001449 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
Alex Deymo1c656c42013-06-28 11:02:14 -07001450 "Installer.PayloadFormat", kPayloadTypeForcedFull, kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001451 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001452 metrics::kMetricAttemptPayloadType, kPayloadTypeForcedFull,
1453 kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001454 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001455 metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeForcedFull,
1456 kNumPayloadTypes));
Alex Deymo1c656c42013-06-28 11:02:14 -07001457 payload_state.UpdateSucceeded();
1458}
1459
1460TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
1461 OmahaResponse response;
1462 response.is_delta_payload = false;
1463 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001464 FakeSystemState fake_system_state;
Alex Deymo1c656c42013-06-28 11:02:14 -07001465
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001466 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo1c656c42013-06-28 11:02:14 -07001467 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1468
Alex Deymo820cc702013-06-28 15:43:46 -07001469 // Mock the request to a request where the delta is enabled, although the
1470 // result is full.
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001471 OmahaRequestParams params(&fake_system_state);
Alex Deymo1c656c42013-06-28 11:02:14 -07001472 params.set_delta_okay(true);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001473 fake_system_state.set_request_params(&params);
Alex Deymo1c656c42013-06-28 11:02:14 -07001474
1475 // Simulate a successful download and update.
1476 payload_state.DownloadComplete();
1477
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001478 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
David Zeuthen33bae492014-02-25 16:16:18 -08001479 .Times(AnyNumber());
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001480 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
Alex Deymo1c656c42013-06-28 11:02:14 -07001481 "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001482 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001483 metrics::kMetricAttemptPayloadType, kPayloadTypeFull,
1484 kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001485 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001486 metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeFull,
1487 kNumPayloadTypes));
Alex Deymo1c656c42013-06-28 11:02:14 -07001488 payload_state.UpdateSucceeded();
1489}
1490
Alex Deymo42432912013-07-12 20:21:15 -07001491TEST(PayloadStateTest, RebootAfterUpdateFailedMetric) {
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001492 FakeSystemState fake_system_state;
Alex Deymo42432912013-07-12 20:21:15 -07001493 OmahaResponse response;
1494 PayloadState payload_state;
1495 Prefs prefs;
1496 string temp_dir;
1497
1498 // Setup an environment with persistent prefs across simulated reboots.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001499 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateReboot.XXXXXX",
Alex Deymo42432912013-07-12 20:21:15 -07001500 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001501 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001502 fake_system_state.set_prefs(&prefs);
Alex Deymo42432912013-07-12 20:21:15 -07001503
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001504 FakeHardware* fake_hardware = fake_system_state.fake_hardware();
Don Garrett6646b442013-11-13 15:29:11 -08001505 fake_hardware->SetBootDevice("/dev/sda3");
Alex Deymo42432912013-07-12 20:21:15 -07001506
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001507 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo42432912013-07-12 20:21:15 -07001508 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1509
1510 // Simulate a successful download and update.
1511 payload_state.DownloadComplete();
1512 payload_state.UpdateSucceeded();
1513 payload_state.ExpectRebootInNewVersion("Version:12345678");
1514
1515 // Reboot into the same environment to get an UMA metric with a value of 1.
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001516 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo42432912013-07-12 20:21:15 -07001517 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001518 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001519 metrics::kMetricFailedUpdateCount, 1, _, _, _));
Alex Deymo42432912013-07-12 20:21:15 -07001520 payload_state.ReportFailedBootIfNeeded();
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001521 Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_lib());
Alex Deymo42432912013-07-12 20:21:15 -07001522
1523 // Simulate a second update and reboot into the same environment, this should
1524 // send a value of 2.
1525 payload_state.ExpectRebootInNewVersion("Version:12345678");
1526
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001527 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo42432912013-07-12 20:21:15 -07001528 "Installer.RebootToNewPartitionAttempt", 2, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001529 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001530 metrics::kMetricFailedUpdateCount, 2, _, _, _));
Alex Deymo42432912013-07-12 20:21:15 -07001531 payload_state.ReportFailedBootIfNeeded();
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001532 Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_lib());
Alex Deymo42432912013-07-12 20:21:15 -07001533
1534 // Simulate a third failed reboot to new version, but this time for a
1535 // different payload. This should send a value of 1 this time.
1536 payload_state.ExpectRebootInNewVersion("Version:3141592");
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001537 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo42432912013-07-12 20:21:15 -07001538 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001539 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001540 metrics::kMetricFailedUpdateCount, 1, _, _, _));
Alex Deymo42432912013-07-12 20:21:15 -07001541 payload_state.ReportFailedBootIfNeeded();
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001542 Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_lib());
Alex Deymo42432912013-07-12 20:21:15 -07001543
1544 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1545}
1546
1547TEST(PayloadStateTest, RebootAfterUpdateSucceed) {
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001548 FakeSystemState fake_system_state;
Alex Deymo42432912013-07-12 20:21:15 -07001549 OmahaResponse response;
1550 PayloadState payload_state;
1551 Prefs prefs;
1552 string temp_dir;
1553
1554 // Setup an environment with persistent prefs across simulated reboots.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001555 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateReboot.XXXXXX",
Alex Deymo42432912013-07-12 20:21:15 -07001556 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001557 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001558 fake_system_state.set_prefs(&prefs);
Alex Deymo42432912013-07-12 20:21:15 -07001559
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001560 FakeHardware* fake_hardware = fake_system_state.fake_hardware();
Don Garrett6646b442013-11-13 15:29:11 -08001561 fake_hardware->SetBootDevice("/dev/sda3");
Alex Deymo42432912013-07-12 20:21:15 -07001562
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001563 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo42432912013-07-12 20:21:15 -07001564 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1565
1566 // Simulate a successful download and update.
1567 payload_state.DownloadComplete();
1568 payload_state.UpdateSucceeded();
1569 payload_state.ExpectRebootInNewVersion("Version:12345678");
1570
1571 // Change the BootDevice to a different one, no metric should be sent.
Don Garrett6646b442013-11-13 15:29:11 -08001572 fake_hardware->SetBootDevice("/dev/sda5");
Alex Deymo42432912013-07-12 20:21:15 -07001573
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001574 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo42432912013-07-12 20:21:15 -07001575 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1576 .Times(0);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001577 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001578 metrics::kMetricFailedUpdateCount, _, _, _, _))
1579 .Times(0);
Alex Deymo42432912013-07-12 20:21:15 -07001580 payload_state.ReportFailedBootIfNeeded();
1581
1582 // A second reboot in eiher partition should not send a metric.
1583 payload_state.ReportFailedBootIfNeeded();
Don Garrett6646b442013-11-13 15:29:11 -08001584 fake_hardware->SetBootDevice("/dev/sda3");
Alex Deymo42432912013-07-12 20:21:15 -07001585 payload_state.ReportFailedBootIfNeeded();
1586
1587 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1588}
1589
1590TEST(PayloadStateTest, RebootAfterCanceledUpdate) {
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001591 FakeSystemState fake_system_state;
Alex Deymo42432912013-07-12 20:21:15 -07001592 OmahaResponse response;
1593 PayloadState payload_state;
1594 Prefs prefs;
1595 string temp_dir;
1596
1597 // Setup an environment with persistent prefs across simulated reboots.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001598 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateReboot.XXXXXX",
Alex Deymo42432912013-07-12 20:21:15 -07001599 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001600 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001601 fake_system_state.set_prefs(&prefs);
Alex Deymo42432912013-07-12 20:21:15 -07001602
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001603 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo42432912013-07-12 20:21:15 -07001604 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1605
1606 // Simulate a successful download and update.
1607 payload_state.DownloadComplete();
1608 payload_state.UpdateSucceeded();
1609 payload_state.ExpectRebootInNewVersion("Version:12345678");
1610
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001611 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo42432912013-07-12 20:21:15 -07001612 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1613 .Times(0);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001614 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001615 metrics::kMetricFailedUpdateCount, _, _, _, _))
1616 .Times(0);
Alex Deymo42432912013-07-12 20:21:15 -07001617
1618 // Cancel the applied update.
1619 payload_state.ResetUpdateStatus();
1620
1621 // Simulate a reboot.
1622 payload_state.ReportFailedBootIfNeeded();
1623
1624 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1625}
1626
1627TEST(PayloadStateTest, UpdateSuccessWithWipedPrefs) {
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001628 FakeSystemState fake_system_state;
Alex Deymo42432912013-07-12 20:21:15 -07001629 PayloadState payload_state;
1630 Prefs prefs;
1631 string temp_dir;
1632
1633 // Setup an environment with persistent but initially empty prefs.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001634 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateReboot.XXXXXX",
Alex Deymo42432912013-07-12 20:21:15 -07001635 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001636 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001637 fake_system_state.set_prefs(&prefs);
Alex Deymo42432912013-07-12 20:21:15 -07001638
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001639 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo42432912013-07-12 20:21:15 -07001640
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001641 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo42432912013-07-12 20:21:15 -07001642 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1643 .Times(0);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001644 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001645 metrics::kMetricFailedUpdateCount, _, _, _, _))
1646 .Times(0);
Alex Deymo42432912013-07-12 20:21:15 -07001647
1648 // Simulate a reboot in this environment.
1649 payload_state.ReportFailedBootIfNeeded();
1650
1651 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1652}
1653
David Zeuthendcba8092013-08-06 12:16:35 -07001654TEST(PayloadStateTest, DisallowP2PAfterTooManyAttempts) {
1655 OmahaResponse response;
1656 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001657 FakeSystemState fake_system_state;
David Zeuthendcba8092013-08-06 12:16:35 -07001658 Prefs prefs;
1659 string temp_dir;
1660
1661 // We need persistent preferences for this test.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001662 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001663 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001664 prefs.Init(base::FilePath(temp_dir));
David Zeuthendcba8092013-08-06 12:16:35 -07001665
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001666 fake_system_state.set_prefs(&prefs);
1667 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthendcba8092013-08-06 12:16:35 -07001668 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1669
1670 // Should allow exactly kMaxP2PAttempts...
1671 for (int n = 0; n < kMaxP2PAttempts; n++) {
1672 payload_state.P2PNewAttempt();
1673 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1674 }
1675 // ... but not more than that.
1676 payload_state.P2PNewAttempt();
1677 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1678
1679 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1680}
1681
1682TEST(PayloadStateTest, DisallowP2PAfterDeadline) {
1683 OmahaResponse response;
1684 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001685 FakeSystemState fake_system_state;
David Zeuthendcba8092013-08-06 12:16:35 -07001686 FakeClock fake_clock;
1687 Prefs prefs;
1688 string temp_dir;
1689
1690 // We need persistent preferences for this test.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001691 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001692 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001693 prefs.Init(base::FilePath(temp_dir));
David Zeuthendcba8092013-08-06 12:16:35 -07001694
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001695 fake_system_state.set_clock(&fake_clock);
1696 fake_system_state.set_prefs(&prefs);
1697 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthendcba8092013-08-06 12:16:35 -07001698 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1699
1700 // Set the clock to 1 second.
1701 Time epoch = Time::FromInternalValue(1000000);
1702 fake_clock.SetWallclockTime(epoch);
1703
1704 // Do an attempt - this will set the timestamp.
1705 payload_state.P2PNewAttempt();
1706
1707 // Check that the timestamp equals what we just set.
1708 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1709
1710 // Time hasn't advanced - this should work.
1711 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1712
1713 // Set clock to half the deadline - this should work.
1714 fake_clock.SetWallclockTime(epoch +
1715 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds) / 2);
1716 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1717
1718 // Check that the first attempt timestamp hasn't changed just
1719 // because the wall-clock time changed.
1720 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1721
1722 // Set clock to _just_ before the deadline - this should work.
1723 fake_clock.SetWallclockTime(epoch +
1724 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds - 1));
1725 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1726
1727 // Set clock to _just_ after the deadline - this should not work.
1728 fake_clock.SetWallclockTime(epoch +
1729 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds + 1));
1730 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1731
1732 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1733}
1734
1735TEST(PayloadStateTest, P2PStateVarsInitialValue) {
1736 OmahaResponse response;
1737 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001738 FakeSystemState fake_system_state;
David Zeuthendcba8092013-08-06 12:16:35 -07001739 Prefs prefs;
1740 string temp_dir;
1741
Gilad Arnolda6742b32014-01-11 00:18:34 -08001742 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001743 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001744 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001745 fake_system_state.set_prefs(&prefs);
1746 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthendcba8092013-08-06 12:16:35 -07001747 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1748
1749 Time null_time = Time();
1750 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1751 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1752
1753 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1754}
1755
1756TEST(PayloadStateTest, P2PStateVarsArePersisted) {
1757 OmahaResponse response;
1758 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001759 FakeSystemState fake_system_state;
David Zeuthendcba8092013-08-06 12:16:35 -07001760 FakeClock fake_clock;
1761 Prefs prefs;
1762 string temp_dir;
1763
Gilad Arnolda6742b32014-01-11 00:18:34 -08001764 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001765 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001766 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001767 fake_system_state.set_clock(&fake_clock);
1768 fake_system_state.set_prefs(&prefs);
1769 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthendcba8092013-08-06 12:16:35 -07001770 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1771
1772 // Set the clock to something known.
1773 Time time = Time::FromInternalValue(12345);
1774 fake_clock.SetWallclockTime(time);
1775
1776 // New p2p attempt - as a side-effect this will update the p2p state vars.
1777 payload_state.P2PNewAttempt();
1778 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1779 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1780
1781 // Now create a new PayloadState and check that it loads the state
1782 // vars correctly.
1783 PayloadState payload_state2;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001784 EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
David Zeuthendcba8092013-08-06 12:16:35 -07001785 EXPECT_EQ(1, payload_state2.GetP2PNumAttempts());
1786 EXPECT_EQ(time, payload_state2.GetP2PFirstAttemptTimestamp());
1787
1788 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1789}
1790
1791TEST(PayloadStateTest, P2PStateVarsAreClearedOnNewResponse) {
1792 OmahaResponse response;
1793 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001794 FakeSystemState fake_system_state;
David Zeuthendcba8092013-08-06 12:16:35 -07001795 FakeClock fake_clock;
1796 Prefs prefs;
1797 string temp_dir;
1798
Gilad Arnolda6742b32014-01-11 00:18:34 -08001799 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001800 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001801 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001802 fake_system_state.set_clock(&fake_clock);
1803 fake_system_state.set_prefs(&prefs);
1804 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthendcba8092013-08-06 12:16:35 -07001805 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1806
1807 // Set the clock to something known.
1808 Time time = Time::FromInternalValue(12345);
1809 fake_clock.SetWallclockTime(time);
1810
1811 // New p2p attempt - as a side-effect this will update the p2p state vars.
1812 payload_state.P2PNewAttempt();
1813 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1814 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1815
1816 // Set a new response...
1817 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
1818
1819 // ... and check that it clears the P2P state vars.
1820 Time null_time = Time();
1821 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1822 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1823
1824 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1825}
1826
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001827}