blob: 9d732009d8dff6051cf3c35c2f1ce2167953a759 [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>
Ben Chan06c76a42014-09-05 08:21:06 -07008#include "base/files/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;
Alex Deymo42432912013-07-12 20:21:15 -070028using testing::AnyNumber;
29using testing::AtLeast;
30using testing::Mock;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080031using testing::NiceMock;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080032using testing::Return;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080033using testing::SetArgumentPointee;
Alex Deymof329b932014-10-30 01:37:48 -070034using testing::_;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080035
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) {
David Zeuthenf3e28012014-08-26 18:23:52 -040094 if (static_cast<int>(ErrorCode::kUmaReportedMax) != 47) {
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 "
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -070098 << "to the new value of ErrorCode::kUmaReportedMax, which is "
99 << ErrorCode::kUmaReportedMax;
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();
Alex Vakulenkod2779df2014-06-16 13:19:00 -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();
Alex Vakulenkod2779df2014-06-16 13:19:00 -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();
Alex Vakulenkod2779df2014-06-16 13:19:00 -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
Alex Vakulenkod2779df2014-06-16 13:19:00 -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.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700288 ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
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.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700325 ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
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
Alex Vakulenkod2779df2014-06-16 13:19:00 -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.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700421 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
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.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700429 payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
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.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700437 payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
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.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700448 payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
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.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700457 payload_state.UpdateFailed(ErrorCode::kPayloadHashMismatchError);
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.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700467 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMissingError);
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>(
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700477 static_cast<int>(ErrorCode::kOmahaRequestHTTPResponseBase) + 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
Alex Vakulenkod2779df2014-06-16 13:19:00 -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
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700561 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700562 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();
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700612 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
613 payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
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));
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700626 EXPECT_CALL(*prefs2, GetInt64(_, _)).Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700627 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);
Alex Vakulenkod2779df2014-06-16 13:19:00 -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.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700669 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
670 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
Chris Sosa20f005c2013-09-05 13:53:08 -0700671 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);
Alex Vakulenkod2779df2014-06-16 13:19:00 -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.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700692 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
693 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
Chris Sosa20f005c2013-09-05 13:53:08 -0700694 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.
Gilad Arnold74b5f552014-10-07 08:17:16 -0700698 payload_state.SetUsingP2PForDownloading(true);
699 payload_state.SetP2PUrl("http://mypeer:52909/path/to/file");
Chris Sosa20f005c2013-09-05 13:53:08 -0700700 // Should not backoff for p2p updates.
701 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
702
Gilad Arnold74b5f552014-10-07 08:17:16 -0700703 payload_state.SetP2PUrl("");
Chris Sosa20f005c2013-09-05 13:53:08 -0700704 // 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.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700727 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
728 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
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.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700793 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
794 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
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.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700844 ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
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();
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001028 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AtLeast(0));
Chris Sosabe45bef2013-04-09 18:25:12 -07001029 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);
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001151 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),
1152 10000000);
David Zeuthenf413fe52013-04-22 14:04:39 -07001153
1154 // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
1155 // and check that the durations are increased accordingly.
1156 fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
1157 fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
1158 payload_state2.UpdateSucceeded();
1159 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001160 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),
1161 16000000);
David Zeuthenf413fe52013-04-22 14:04:39 -07001162
1163 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1164}
1165
David Zeuthene4c58bf2013-06-18 17:26:50 -07001166TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
1167 OmahaResponse response;
1168 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001169 FakeSystemState fake_system_state;
David Zeuthene4c58bf2013-06-18 17:26:50 -07001170 FakeClock fake_clock;
1171 Prefs prefs;
1172 string temp_dir;
1173
1174 // Set the clock to a well-known time (t = 30 seconds).
1175 fake_clock.SetWallclockTime(Time::FromInternalValue(
1176 30 * Time::kMicrosecondsPerSecond));
1177
1178 // We need persistent preferences for this test
1179 EXPECT_TRUE(utils::MakeTempDirectory(
Gilad Arnolda6742b32014-01-11 00:18:34 -08001180 "RebootAfterSuccessfulUpdateTest.XXXXXX", &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001181 prefs.Init(base::FilePath(temp_dir));
David Zeuthene4c58bf2013-06-18 17:26:50 -07001182
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001183 fake_system_state.set_clock(&fake_clock);
1184 fake_system_state.set_prefs(&prefs);
1185 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthene4c58bf2013-06-18 17:26:50 -07001186
1187 // Make the update succeed.
1188 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1189 payload_state.UpdateSucceeded();
1190
1191 // Check that the marker was written.
1192 EXPECT_TRUE(prefs.Exists(kPrefsSystemUpdatedMarker));
1193
1194 // Now simulate a reboot and set the wallclock time to a later point
1195 // (t = 500 seconds). We do this by using a new PayloadState object
1196 // and checking that it emits the right UMA metric with the right
1197 // value.
1198 fake_clock.SetWallclockTime(Time::FromInternalValue(
1199 500 * Time::kMicrosecondsPerSecond));
1200 PayloadState payload_state2;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001201 EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
David Zeuthene4c58bf2013-06-18 17:26:50 -07001202
1203 // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001204 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthene4c58bf2013-06-18 17:26:50 -07001205 "Installer.TimeToRebootMinutes",
1206 7, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001207 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001208 metrics::kMetricTimeToRebootMinutes,
1209 7, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001210 fake_system_state.set_system_rebooted(true);
David Zeuthene4c58bf2013-06-18 17:26:50 -07001211
1212 payload_state2.UpdateEngineStarted();
1213
1214 // Check that the marker was nuked.
1215 EXPECT_FALSE(prefs.Exists(kPrefsSystemUpdatedMarker));
1216
1217 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1218}
1219
Alex Deymo569c4242013-07-24 12:01:01 -07001220TEST(PayloadStateTest, RestartAfterCrash) {
1221 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001222 FakeSystemState fake_system_state;
1223 NiceMock<PrefsMock>* prefs = fake_system_state.mock_prefs();
Alex Deymo569c4242013-07-24 12:01:01 -07001224
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001225 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo569c4242013-07-24 12:01:01 -07001226
David Zeuthen4e1d1492014-04-25 13:12:27 -07001227 // Only the |kPrefsAttemptInProgress| state variable should be read.
Alex Deymo569c4242013-07-24 12:01:01 -07001228 EXPECT_CALL(*prefs, Exists(_)).Times(0);
1229 EXPECT_CALL(*prefs, SetString(_, _)).Times(0);
1230 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(0);
1231 EXPECT_CALL(*prefs, SetBoolean(_, _)).Times(0);
1232 EXPECT_CALL(*prefs, GetString(_, _)).Times(0);
1233 EXPECT_CALL(*prefs, GetInt64(_, _)).Times(0);
1234 EXPECT_CALL(*prefs, GetBoolean(_, _)).Times(0);
David Zeuthen4e1d1492014-04-25 13:12:27 -07001235 EXPECT_CALL(*prefs, GetBoolean(kPrefsAttemptInProgress, _));
Alex Deymo569c4242013-07-24 12:01:01 -07001236
1237 // No metrics are reported after a crash.
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001238 EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
Alex Deymo569c4242013-07-24 12:01:01 -07001239 SendToUMA(_, _, _, _, _)).Times(0);
1240
1241 // Simulate an update_engine restart without a reboot.
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001242 fake_system_state.set_system_rebooted(false);
Alex Deymo569c4242013-07-24 12:01:01 -07001243
1244 payload_state.UpdateEngineStarted();
1245}
1246
David Zeuthen4e1d1492014-04-25 13:12:27 -07001247TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsNoReporting) {
1248 PayloadState payload_state;
1249 FakeSystemState fake_system_state;
1250
1251 // If there's no marker at startup, ensure we don't report a metric.
1252 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1253 EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
1254 SendEnumToUMA(
1255 metrics::kMetricAttemptResult,
1256 static_cast<int>(metrics::AttemptResult::kAbnormalTermination),
1257 _)).Times(0);
1258 payload_state.UpdateEngineStarted();
1259}
1260
1261TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsReported) {
1262 PayloadState payload_state;
1263 FakeSystemState fake_system_state;
1264 FakePrefs prefs;
1265
1266 // If we have a marker at startup, ensure it's reported and the
1267 // marker is then cleared.
1268 fake_system_state.set_prefs(&prefs);
1269 prefs.SetBoolean(kPrefsAttemptInProgress, true);
1270
1271 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1272
1273 EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
1274 SendEnumToUMA(
1275 metrics::kMetricAttemptResult,
1276 static_cast<int>(metrics::AttemptResult::kAbnormalTermination),
1277 _)).Times(1);
1278 payload_state.UpdateEngineStarted();
1279
1280 EXPECT_FALSE(prefs.Exists(kPrefsAttemptInProgress));
1281}
1282
1283TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsClearedOnSucceess) {
1284 PayloadState payload_state;
1285 FakeSystemState fake_system_state;
1286 FakePrefs prefs;
1287
1288 // Make sure the marker is written and cleared during an attempt and
1289 // also that we DO NOT emit the metric (since the attempt didn't end
1290 // abnormally).
1291 fake_system_state.set_prefs(&prefs);
1292 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
1293
1294 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
1295 .Times(AnyNumber());
1296 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
1297 .Times(AnyNumber());
1298 EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
1299 SendEnumToUMA(
1300 metrics::kMetricAttemptResult,
1301 static_cast<int>(metrics::AttemptResult::kAbnormalTermination),
1302 _)).Times(0);
1303
1304 // Attempt not in progress, should be clear.
1305 EXPECT_FALSE(prefs.Exists(kPrefsAttemptInProgress));
1306
1307 payload_state.UpdateRestarted();
1308
1309 // Attempt not in progress, should be set.
1310 EXPECT_TRUE(prefs.Exists(kPrefsAttemptInProgress));
1311
1312 payload_state.UpdateSucceeded();
1313
1314 // Attempt not in progress, should be clear.
1315 EXPECT_FALSE(prefs.Exists(kPrefsAttemptInProgress));
1316}
1317
Jay Srinivasan53173b92013-05-17 17:13:01 -07001318TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
1319 OmahaResponse response;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001320 FakeSystemState fake_system_state;
Jay Srinivasan53173b92013-05-17 17:13:01 -07001321 PayloadState payload_state;
1322
Jay Srinivasan53173b92013-05-17 17:13:01 -07001323 policy::MockDevicePolicy disable_http_policy;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001324 fake_system_state.set_device_policy(&disable_http_policy);
1325 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Chris Sosaf7d80042013-08-22 16:45:17 -07001326
1327 // Test with no device policy. Should default to allowing http.
1328 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1329 .WillRepeatedly(Return(false));
1330
1331 // Set the first response.
1332 SetupPayloadStateWith2Urls("Hash8433", true, &payload_state, &response);
1333
1334 // Check that we use the HTTP URL since there is no value set for allowing
1335 // http.
1336 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1337
1338 // Test with device policy not allowing http updates.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001339 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1340 .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
1341
Chris Sosaf7d80042013-08-22 16:45:17 -07001342 // Reset state and set again.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001343 SetupPayloadStateWith2Urls("Hash8433", false, &payload_state, &response);
1344
1345 // Check that we skip the HTTP URL and use only the HTTPS url.
1346 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1347
1348 // Advance the URL index to 1 by faking an error.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001349 ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
Jay Srinivasan53173b92013-05-17 17:13:01 -07001350 payload_state.UpdateFailed(error);
1351
1352 // Check that we still skip the HTTP URL and use only the HTTPS url.
1353 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1354 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
1355
1356 // Now, slightly change the response and set it again.
1357 SetupPayloadStateWith2Urls("Hash2399", false, &payload_state, &response);
1358
1359 // Check that we still skip the HTTP URL and use only the HTTPS url.
1360 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1361
1362 // Now, pretend that the HTTP policy is turned on. We want to make sure
1363 // the new policy is honored.
1364 policy::MockDevicePolicy enable_http_policy;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001365 fake_system_state.set_device_policy(&enable_http_policy);
Jay Srinivasan53173b92013-05-17 17:13:01 -07001366 EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
1367 .WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
1368
1369 // Now, set the same response using the same hash
1370 // so that we can test that the state is reset not because of the
1371 // hash but because of the policy change which results in candidate url
1372 // list change.
1373 SetupPayloadStateWith2Urls("Hash2399", true, &payload_state, &response);
1374
1375 // Check that we use the HTTP URL now and the failure count is reset.
1376 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1377 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1378
1379 // Fake a failure and see if we're moving over to the HTTPS url and update
1380 // the URL switch count properly.
1381 payload_state.UpdateFailed(error);
1382 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1383 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
1384 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1385}
1386
Alex Deymo1c656c42013-06-28 11:02:14 -07001387TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
1388 OmahaResponse response;
1389 response.is_delta_payload = true;
1390 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001391 FakeSystemState fake_system_state;
Alex Deymo1c656c42013-06-28 11:02:14 -07001392
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001393 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo1c656c42013-06-28 11:02:14 -07001394 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1395
1396 // Simulate a successful download and update.
1397 payload_state.DownloadComplete();
1398
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001399 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
David Zeuthen33bae492014-02-25 16:16:18 -08001400 .Times(AnyNumber());
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001401 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
Alex Deymo1c656c42013-06-28 11:02:14 -07001402 "Installer.PayloadFormat", 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::kMetricAttemptPayloadType, kPayloadTypeDelta, kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001405 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001406 metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeDelta,
1407 kNumPayloadTypes));
Alex Deymo1c656c42013-06-28 11:02:14 -07001408 payload_state.UpdateSucceeded();
1409
1410 // Mock the request to a request where the delta was disabled but Omaha sends
1411 // a delta anyway and test again.
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001412 OmahaRequestParams params(&fake_system_state);
Alex Deymo1c656c42013-06-28 11:02:14 -07001413 params.set_delta_okay(false);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001414 fake_system_state.set_request_params(&params);
Alex Deymo1c656c42013-06-28 11:02:14 -07001415
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001416 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo1c656c42013-06-28 11:02:14 -07001417 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1418
1419 payload_state.DownloadComplete();
1420
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001421 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
Alex Deymo1c656c42013-06-28 11:02:14 -07001422 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001423 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001424 metrics::kMetricAttemptPayloadType, kPayloadTypeDelta,
1425 kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001426 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001427 metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeDelta,
1428 kNumPayloadTypes));
Alex Deymo1c656c42013-06-28 11:02:14 -07001429 payload_state.UpdateSucceeded();
1430}
1431
1432TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
1433 OmahaResponse response;
1434 response.is_delta_payload = false;
1435 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001436 FakeSystemState fake_system_state;
Alex Deymo1c656c42013-06-28 11:02:14 -07001437
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001438 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo1c656c42013-06-28 11:02:14 -07001439 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1440
1441 // Mock the request to a request where the delta was disabled.
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001442 OmahaRequestParams params(&fake_system_state);
Alex Deymo1c656c42013-06-28 11:02:14 -07001443 params.set_delta_okay(false);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001444 fake_system_state.set_request_params(&params);
Alex Deymo1c656c42013-06-28 11:02:14 -07001445
1446 // Simulate a successful download and update.
1447 payload_state.DownloadComplete();
1448
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001449 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
David Zeuthen33bae492014-02-25 16:16:18 -08001450 .Times(AnyNumber());
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001451 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
Alex Deymo1c656c42013-06-28 11:02:14 -07001452 "Installer.PayloadFormat", kPayloadTypeForcedFull, kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001453 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001454 metrics::kMetricAttemptPayloadType, kPayloadTypeForcedFull,
1455 kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001456 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001457 metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeForcedFull,
1458 kNumPayloadTypes));
Alex Deymo1c656c42013-06-28 11:02:14 -07001459 payload_state.UpdateSucceeded();
1460}
1461
1462TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
1463 OmahaResponse response;
1464 response.is_delta_payload = false;
1465 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001466 FakeSystemState fake_system_state;
Alex Deymo1c656c42013-06-28 11:02:14 -07001467
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001468 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo1c656c42013-06-28 11:02:14 -07001469 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1470
Alex Deymo820cc702013-06-28 15:43:46 -07001471 // Mock the request to a request where the delta is enabled, although the
1472 // result is full.
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001473 OmahaRequestParams params(&fake_system_state);
Alex Deymo1c656c42013-06-28 11:02:14 -07001474 params.set_delta_okay(true);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001475 fake_system_state.set_request_params(&params);
Alex Deymo1c656c42013-06-28 11:02:14 -07001476
1477 // Simulate a successful download and update.
1478 payload_state.DownloadComplete();
1479
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001480 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
David Zeuthen33bae492014-02-25 16:16:18 -08001481 .Times(AnyNumber());
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001482 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
Alex Deymo1c656c42013-06-28 11:02:14 -07001483 "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001484 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001485 metrics::kMetricAttemptPayloadType, kPayloadTypeFull,
1486 kNumPayloadTypes));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001487 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001488 metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeFull,
1489 kNumPayloadTypes));
Alex Deymo1c656c42013-06-28 11:02:14 -07001490 payload_state.UpdateSucceeded();
1491}
1492
Alex Deymo42432912013-07-12 20:21:15 -07001493TEST(PayloadStateTest, RebootAfterUpdateFailedMetric) {
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001494 FakeSystemState fake_system_state;
Alex Deymo42432912013-07-12 20:21:15 -07001495 OmahaResponse response;
1496 PayloadState payload_state;
1497 Prefs prefs;
1498 string temp_dir;
1499
1500 // Setup an environment with persistent prefs across simulated reboots.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001501 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateReboot.XXXXXX",
Alex Deymo42432912013-07-12 20:21:15 -07001502 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001503 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001504 fake_system_state.set_prefs(&prefs);
Alex Deymo42432912013-07-12 20:21:15 -07001505
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001506 FakeHardware* fake_hardware = fake_system_state.fake_hardware();
Don Garrett6646b442013-11-13 15:29:11 -08001507 fake_hardware->SetBootDevice("/dev/sda3");
Alex Deymo42432912013-07-12 20:21:15 -07001508
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001509 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo42432912013-07-12 20:21:15 -07001510 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1511
1512 // Simulate a successful download and update.
1513 payload_state.DownloadComplete();
1514 payload_state.UpdateSucceeded();
1515 payload_state.ExpectRebootInNewVersion("Version:12345678");
1516
1517 // Reboot into the same environment to get an UMA metric with a value of 1.
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001518 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo42432912013-07-12 20:21:15 -07001519 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001520 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001521 metrics::kMetricFailedUpdateCount, 1, _, _, _));
Alex Deymo42432912013-07-12 20:21:15 -07001522 payload_state.ReportFailedBootIfNeeded();
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001523 Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_lib());
Alex Deymo42432912013-07-12 20:21:15 -07001524
1525 // Simulate a second update and reboot into the same environment, this should
1526 // send a value of 2.
1527 payload_state.ExpectRebootInNewVersion("Version:12345678");
1528
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001529 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo42432912013-07-12 20:21:15 -07001530 "Installer.RebootToNewPartitionAttempt", 2, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001531 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001532 metrics::kMetricFailedUpdateCount, 2, _, _, _));
Alex Deymo42432912013-07-12 20:21:15 -07001533 payload_state.ReportFailedBootIfNeeded();
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001534 Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_lib());
Alex Deymo42432912013-07-12 20:21:15 -07001535
1536 // Simulate a third failed reboot to new version, but this time for a
1537 // different payload. This should send a value of 1 this time.
1538 payload_state.ExpectRebootInNewVersion("Version:3141592");
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001539 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo42432912013-07-12 20:21:15 -07001540 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001541 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001542 metrics::kMetricFailedUpdateCount, 1, _, _, _));
Alex Deymo42432912013-07-12 20:21:15 -07001543 payload_state.ReportFailedBootIfNeeded();
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001544 Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_lib());
Alex Deymo42432912013-07-12 20:21:15 -07001545
1546 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1547}
1548
1549TEST(PayloadStateTest, RebootAfterUpdateSucceed) {
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001550 FakeSystemState fake_system_state;
Alex Deymo42432912013-07-12 20:21:15 -07001551 OmahaResponse response;
1552 PayloadState payload_state;
1553 Prefs prefs;
1554 string temp_dir;
1555
1556 // Setup an environment with persistent prefs across simulated reboots.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001557 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateReboot.XXXXXX",
Alex Deymo42432912013-07-12 20:21:15 -07001558 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001559 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001560 fake_system_state.set_prefs(&prefs);
Alex Deymo42432912013-07-12 20:21:15 -07001561
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001562 FakeHardware* fake_hardware = fake_system_state.fake_hardware();
Don Garrett6646b442013-11-13 15:29:11 -08001563 fake_hardware->SetBootDevice("/dev/sda3");
Alex Deymo42432912013-07-12 20:21:15 -07001564
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001565 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo42432912013-07-12 20:21:15 -07001566 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1567
1568 // Simulate a successful download and update.
1569 payload_state.DownloadComplete();
1570 payload_state.UpdateSucceeded();
1571 payload_state.ExpectRebootInNewVersion("Version:12345678");
1572
1573 // Change the BootDevice to a different one, no metric should be sent.
Don Garrett6646b442013-11-13 15:29:11 -08001574 fake_hardware->SetBootDevice("/dev/sda5");
Alex Deymo42432912013-07-12 20:21:15 -07001575
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001576 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo42432912013-07-12 20:21:15 -07001577 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1578 .Times(0);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001579 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001580 metrics::kMetricFailedUpdateCount, _, _, _, _))
1581 .Times(0);
Alex Deymo42432912013-07-12 20:21:15 -07001582 payload_state.ReportFailedBootIfNeeded();
1583
1584 // A second reboot in eiher partition should not send a metric.
1585 payload_state.ReportFailedBootIfNeeded();
Don Garrett6646b442013-11-13 15:29:11 -08001586 fake_hardware->SetBootDevice("/dev/sda3");
Alex Deymo42432912013-07-12 20:21:15 -07001587 payload_state.ReportFailedBootIfNeeded();
1588
1589 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1590}
1591
1592TEST(PayloadStateTest, RebootAfterCanceledUpdate) {
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001593 FakeSystemState fake_system_state;
Alex Deymo42432912013-07-12 20:21:15 -07001594 OmahaResponse response;
1595 PayloadState payload_state;
1596 Prefs prefs;
1597 string temp_dir;
1598
1599 // Setup an environment with persistent prefs across simulated reboots.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001600 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateReboot.XXXXXX",
Alex Deymo42432912013-07-12 20:21:15 -07001601 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001602 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001603 fake_system_state.set_prefs(&prefs);
Alex Deymo42432912013-07-12 20:21:15 -07001604
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001605 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo42432912013-07-12 20:21:15 -07001606 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1607
1608 // Simulate a successful download and update.
1609 payload_state.DownloadComplete();
1610 payload_state.UpdateSucceeded();
1611 payload_state.ExpectRebootInNewVersion("Version:12345678");
1612
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001613 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo42432912013-07-12 20:21:15 -07001614 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1615 .Times(0);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001616 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001617 metrics::kMetricFailedUpdateCount, _, _, _, _))
1618 .Times(0);
Alex Deymo42432912013-07-12 20:21:15 -07001619
1620 // Cancel the applied update.
1621 payload_state.ResetUpdateStatus();
1622
1623 // Simulate a reboot.
1624 payload_state.ReportFailedBootIfNeeded();
1625
1626 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1627}
1628
1629TEST(PayloadStateTest, UpdateSuccessWithWipedPrefs) {
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001630 FakeSystemState fake_system_state;
Alex Deymo42432912013-07-12 20:21:15 -07001631 PayloadState payload_state;
1632 Prefs prefs;
1633 string temp_dir;
1634
1635 // Setup an environment with persistent but initially empty prefs.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001636 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateReboot.XXXXXX",
Alex Deymo42432912013-07-12 20:21:15 -07001637 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001638 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001639 fake_system_state.set_prefs(&prefs);
Alex Deymo42432912013-07-12 20:21:15 -07001640
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001641 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
Alex Deymo42432912013-07-12 20:21:15 -07001642
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001643 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
Alex Deymo42432912013-07-12 20:21:15 -07001644 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1645 .Times(0);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001646 EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -08001647 metrics::kMetricFailedUpdateCount, _, _, _, _))
1648 .Times(0);
Alex Deymo42432912013-07-12 20:21:15 -07001649
1650 // Simulate a reboot in this environment.
1651 payload_state.ReportFailedBootIfNeeded();
1652
1653 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1654}
1655
David Zeuthendcba8092013-08-06 12:16:35 -07001656TEST(PayloadStateTest, DisallowP2PAfterTooManyAttempts) {
1657 OmahaResponse response;
1658 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001659 FakeSystemState fake_system_state;
David Zeuthendcba8092013-08-06 12:16:35 -07001660 Prefs prefs;
1661 string temp_dir;
1662
1663 // We need persistent preferences for this test.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001664 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001665 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001666 prefs.Init(base::FilePath(temp_dir));
David Zeuthendcba8092013-08-06 12:16:35 -07001667
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001668 fake_system_state.set_prefs(&prefs);
1669 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthendcba8092013-08-06 12:16:35 -07001670 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1671
1672 // Should allow exactly kMaxP2PAttempts...
1673 for (int n = 0; n < kMaxP2PAttempts; n++) {
1674 payload_state.P2PNewAttempt();
1675 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1676 }
1677 // ... but not more than that.
1678 payload_state.P2PNewAttempt();
1679 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1680
1681 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1682}
1683
1684TEST(PayloadStateTest, DisallowP2PAfterDeadline) {
1685 OmahaResponse response;
1686 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001687 FakeSystemState fake_system_state;
David Zeuthendcba8092013-08-06 12:16:35 -07001688 FakeClock fake_clock;
1689 Prefs prefs;
1690 string temp_dir;
1691
1692 // We need persistent preferences for this test.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001693 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001694 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001695 prefs.Init(base::FilePath(temp_dir));
David Zeuthendcba8092013-08-06 12:16:35 -07001696
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001697 fake_system_state.set_clock(&fake_clock);
1698 fake_system_state.set_prefs(&prefs);
1699 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthendcba8092013-08-06 12:16:35 -07001700 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1701
1702 // Set the clock to 1 second.
1703 Time epoch = Time::FromInternalValue(1000000);
1704 fake_clock.SetWallclockTime(epoch);
1705
1706 // Do an attempt - this will set the timestamp.
1707 payload_state.P2PNewAttempt();
1708
1709 // Check that the timestamp equals what we just set.
1710 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1711
1712 // Time hasn't advanced - this should work.
1713 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1714
1715 // Set clock to half the deadline - this should work.
1716 fake_clock.SetWallclockTime(epoch +
1717 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds) / 2);
1718 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1719
1720 // Check that the first attempt timestamp hasn't changed just
1721 // because the wall-clock time changed.
1722 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1723
1724 // Set clock to _just_ before the deadline - this should work.
1725 fake_clock.SetWallclockTime(epoch +
1726 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds - 1));
1727 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1728
1729 // Set clock to _just_ after the deadline - this should not work.
1730 fake_clock.SetWallclockTime(epoch +
1731 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds + 1));
1732 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1733
1734 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1735}
1736
1737TEST(PayloadStateTest, P2PStateVarsInitialValue) {
1738 OmahaResponse response;
1739 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001740 FakeSystemState fake_system_state;
David Zeuthendcba8092013-08-06 12:16:35 -07001741 Prefs prefs;
1742 string temp_dir;
1743
Gilad Arnolda6742b32014-01-11 00:18:34 -08001744 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001745 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001746 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001747 fake_system_state.set_prefs(&prefs);
1748 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthendcba8092013-08-06 12:16:35 -07001749 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1750
1751 Time null_time = Time();
1752 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1753 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1754
1755 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1756}
1757
1758TEST(PayloadStateTest, P2PStateVarsArePersisted) {
1759 OmahaResponse response;
1760 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001761 FakeSystemState fake_system_state;
David Zeuthendcba8092013-08-06 12:16:35 -07001762 FakeClock fake_clock;
1763 Prefs prefs;
1764 string temp_dir;
1765
Gilad Arnolda6742b32014-01-11 00:18:34 -08001766 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001767 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001768 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001769 fake_system_state.set_clock(&fake_clock);
1770 fake_system_state.set_prefs(&prefs);
1771 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthendcba8092013-08-06 12:16:35 -07001772 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1773
1774 // Set the clock to something known.
1775 Time time = Time::FromInternalValue(12345);
1776 fake_clock.SetWallclockTime(time);
1777
1778 // New p2p attempt - as a side-effect this will update the p2p state vars.
1779 payload_state.P2PNewAttempt();
1780 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1781 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1782
1783 // Now create a new PayloadState and check that it loads the state
1784 // vars correctly.
1785 PayloadState payload_state2;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001786 EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
David Zeuthendcba8092013-08-06 12:16:35 -07001787 EXPECT_EQ(1, payload_state2.GetP2PNumAttempts());
1788 EXPECT_EQ(time, payload_state2.GetP2PFirstAttemptTimestamp());
1789
1790 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1791}
1792
1793TEST(PayloadStateTest, P2PStateVarsAreClearedOnNewResponse) {
1794 OmahaResponse response;
1795 PayloadState payload_state;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001796 FakeSystemState fake_system_state;
David Zeuthendcba8092013-08-06 12:16:35 -07001797 FakeClock fake_clock;
1798 Prefs prefs;
1799 string temp_dir;
1800
Gilad Arnolda6742b32014-01-11 00:18:34 -08001801 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001802 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001803 prefs.Init(base::FilePath(temp_dir));
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001804 fake_system_state.set_clock(&fake_clock);
1805 fake_system_state.set_prefs(&prefs);
1806 EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
David Zeuthendcba8092013-08-06 12:16:35 -07001807 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1808
1809 // Set the clock to something known.
1810 Time time = Time::FromInternalValue(12345);
1811 fake_clock.SetWallclockTime(time);
1812
1813 // New p2p attempt - as a side-effect this will update the p2p state vars.
1814 payload_state.P2PNewAttempt();
1815 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1816 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1817
1818 // Set a new response...
1819 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
1820
1821 // ... and check that it clears the P2P state vars.
1822 Time null_time = Time();
1823 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1824 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1825
1826 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1827}
1828
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001829} // namespace chromeos_update_engine