blob: f804599b58f19672cf2ba1f6c650d1d582ccd74e [file] [log] [blame]
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <glib.h>
6
Alex Vakulenko75039d72014-03-25 12:36:28 -07007#include <base/files/file_path.h>
Chris Sosabe45bef2013-04-09 18:25:12 -07008#include "base/file_util.h"
Alex Vakulenko75039d72014-03-25 12:36:28 -07009#include <base/strings/stringprintf.h>
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080010#include "gmock/gmock.h"
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080011#include "gtest/gtest.h"
12
Jay Srinivasand29695d2013-04-08 15:08:05 -070013#include "update_engine/constants.h"
David Zeuthenf413fe52013-04-22 14:04:39 -070014#include "update_engine/fake_clock.h"
Alex Deymo42432912013-07-12 20:21:15 -070015#include "update_engine/fake_hardware.h"
Jay Srinivasan19409b72013-04-12 19:23:36 -070016#include "update_engine/mock_system_state.h"
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080017#include "update_engine/omaha_request_action.h"
18#include "update_engine/payload_state.h"
David Zeuthenf413fe52013-04-22 14:04:39 -070019#include "update_engine/prefs.h"
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080020#include "update_engine/prefs_mock.h"
21#include "update_engine/test_utils.h"
22#include "update_engine/utils.h"
23
Jay Srinivasan08262882012-12-28 19:29:43 -080024using base::Time;
25using base::TimeDelta;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080026using std::string;
27using testing::_;
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;
34
35namespace chromeos_update_engine {
36
Jay Srinivasan19409b72013-04-12 19:23:36 -070037const char* kCurrentBytesDownloadedFromHttps =
38 "current-bytes-downloaded-from-HttpsServer";
39const char* kTotalBytesDownloadedFromHttps =
40 "total-bytes-downloaded-from-HttpsServer";
41const char* kCurrentBytesDownloadedFromHttp =
42 "current-bytes-downloaded-from-HttpServer";
43const char* kTotalBytesDownloadedFromHttp =
44 "total-bytes-downloaded-from-HttpServer";
David Zeuthenbb8bdc72013-09-03 13:43:48 -070045const char* kCurrentBytesDownloadedFromHttpPeer =
46 "current-bytes-downloaded-from-HttpPeer";
47const char* kTotalBytesDownloadedFromHttpPeer =
48 "total-bytes-downloaded-from-HttpPeer";
Jay Srinivasan19409b72013-04-12 19:23:36 -070049
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080050static void SetupPayloadStateWith2Urls(string hash,
Jay Srinivasan53173b92013-05-17 17:13:01 -070051 bool http_enabled,
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080052 PayloadState* payload_state,
53 OmahaResponse* response) {
54 response->payload_urls.clear();
55 response->payload_urls.push_back("http://test");
56 response->payload_urls.push_back("https://test");
57 response->size = 523456789;
58 response->hash = hash;
59 response->metadata_size = 558123;
60 response->metadata_signature = "metasign";
61 response->max_failure_count_per_url = 3;
62 payload_state->SetResponse(*response);
Jay Srinivasan08262882012-12-28 19:29:43 -080063 string stored_response_sign = payload_state->GetResponseSignature();
Jay Srinivasan53173b92013-05-17 17:13:01 -070064
65 string expected_url_https_only =
66 "NumURLs = 1\n"
67 "Candidate Url0 = https://test\n";
68
69 string expected_urls_both =
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080070 "NumURLs = 2\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -070071 "Candidate Url0 = http://test\n"
72 "Candidate Url1 = https://test\n";
73
74 string expected_response_sign =
75 (http_enabled ? expected_urls_both : expected_url_https_only) +
Alex Vakulenko75039d72014-03-25 12:36:28 -070076 base::StringPrintf("Payload Size = 523456789\n"
77 "Payload Sha256 Hash = %s\n"
78 "Metadata Size = 558123\n"
79 "Metadata Signature = metasign\n"
80 "Is Delta Payload = %d\n"
81 "Max Failure Count Per Url = %d\n"
82 "Disable Payload Backoff = %d\n",
83 hash.c_str(),
84 response->is_delta_payload,
85 response->max_failure_count_per_url,
86 response->disable_payload_backoff);
Jay Srinivasan08262882012-12-28 19:29:43 -080087 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080088}
89
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080090class PayloadStateTest : public ::testing::Test { };
91
David Zeuthena99981f2013-04-29 13:42:47 -070092TEST(PayloadStateTest, DidYouAddANewErrorCode) {
Don Garrett4d039442013-10-28 18:40:06 -070093 if (kErrorCodeUmaReportedMax != 46) {
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080094 LOG(ERROR) << "The following failure is intentional. If you added a new "
David Zeuthena99981f2013-04-29 13:42:47 -070095 << "ErrorCode enum value, make sure to add it to the "
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080096 << "PayloadState::UpdateFailed method and then update this test "
David Zeuthena99981f2013-04-29 13:42:47 -070097 << "to the new value of kErrorCodeUmaReportedMax, which is "
98 << kErrorCodeUmaReportedMax;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080099 EXPECT_FALSE("Please see the log line above");
100 }
101}
102
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800103TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
104 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700105 MockSystemState mock_system_state;
106 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700107 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700108 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
109 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700110 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
111 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700112 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
113 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
114 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
115 .Times(AtLeast(1));
116 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
117 .Times(AtLeast(1));
118 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
119 .Times(AtLeast(1));
120 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
121 .Times(AtLeast(1));
122 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
123 .Times(AtLeast(1));
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700124 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
125 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700126 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800127 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700128 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800129 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800130 string stored_response_sign = payload_state.GetResponseSignature();
131 string expected_response_sign = "NumURLs = 0\n"
132 "Payload Size = 0\n"
133 "Payload Sha256 Hash = \n"
134 "Metadata Size = 0\n"
135 "Metadata Signature = \n"
136 "Is Delta Payload = 0\n"
137 "Max Failure Count Per Url = 0\n"
138 "Disable Payload Backoff = 0\n";
139 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700140 EXPECT_EQ("", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800141 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700142 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700143 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800144}
145
146TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
147 OmahaResponse response;
Jay Srinivasan53173b92013-05-17 17:13:01 -0700148 response.payload_urls.push_back("https://single.url.test");
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800149 response.size = 123456789;
150 response.hash = "hash";
151 response.metadata_size = 58123;
152 response.metadata_signature = "msign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700153 MockSystemState mock_system_state;
154 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700155 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700156 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
157 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700158 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
159 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700160 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
161 .Times(AtLeast(1));
162 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
163 .Times(AtLeast(1));
164 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
165 .Times(AtLeast(1));
166 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
167 .Times(AtLeast(1));
168 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
169 .Times(AtLeast(1));
170 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
171 .Times(AtLeast(1));
172 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
173 .Times(AtLeast(1));
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700174 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
175 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700176 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
177 .Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800178 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700179 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800180 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800181 string stored_response_sign = payload_state.GetResponseSignature();
182 string expected_response_sign = "NumURLs = 1\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -0700183 "Candidate Url0 = https://single.url.test\n"
Jay Srinivasan08262882012-12-28 19:29:43 -0800184 "Payload Size = 123456789\n"
185 "Payload Sha256 Hash = hash\n"
186 "Metadata Size = 58123\n"
187 "Metadata Signature = msign\n"
188 "Is Delta Payload = 0\n"
189 "Max Failure Count Per Url = 0\n"
190 "Disable Payload Backoff = 0\n";
191 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700192 EXPECT_EQ("https://single.url.test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800193 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700194 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700195 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800196}
197
198TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
199 OmahaResponse response;
200 response.payload_urls.push_back("http://multiple.url.test");
201 response.payload_urls.push_back("https://multiple.url.test");
202 response.size = 523456789;
203 response.hash = "rhash";
204 response.metadata_size = 558123;
205 response.metadata_signature = "metasign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700206 MockSystemState mock_system_state;
207 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700208 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700209 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
210 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700211 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
212 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700213 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
214 .Times(AtLeast(1));
215 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
216 .Times(AtLeast(1));
217 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
218 .Times(AtLeast(1));
219 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
220 .Times(AtLeast(1));
221 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
222 .Times(AtLeast(1));
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700223 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
224 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700225 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
226 .Times(AtLeast(1));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700227
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800228 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700229 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800230 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800231 string stored_response_sign = payload_state.GetResponseSignature();
232 string expected_response_sign = "NumURLs = 2\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -0700233 "Candidate Url0 = http://multiple.url.test\n"
234 "Candidate Url1 = https://multiple.url.test\n"
Jay Srinivasan08262882012-12-28 19:29:43 -0800235 "Payload Size = 523456789\n"
236 "Payload Sha256 Hash = rhash\n"
237 "Metadata Size = 558123\n"
238 "Metadata Signature = metasign\n"
239 "Is Delta Payload = 0\n"
240 "Max Failure Count Per Url = 0\n"
241 "Disable Payload Backoff = 0\n";
242 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700243 EXPECT_EQ("http://multiple.url.test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800244 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700245 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700246 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800247}
248
249TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
250 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700251 MockSystemState mock_system_state;
252 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800253 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800254
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700255 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800256 // Payload attempt should start with 0 and then advance to 1.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700257 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
258 .Times(AtLeast(1));
259 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
260 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700261 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
262 .Times(AtLeast(1));
263 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
264 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700265 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
David Zeuthen9a017f22013-04-11 16:10:26 -0700266
Chris Sosabe45bef2013-04-09 18:25:12 -0700267 // Reboots will be set
268 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1));
269
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800270 // Url index should go from 0 to 1 twice.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700271 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
272 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800273
274 // Failure count should be called each times url index is set, so that's
275 // 4 times for this test.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700276 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
277 .Times(AtLeast(4));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800278
Jay Srinivasan19409b72013-04-12 19:23:36 -0700279 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800280
281 // This does a SetResponse which causes all the states to be set to 0 for
282 // the first time.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700283 SetupPayloadStateWith2Urls("Hash1235", true, &payload_state, &response);
284 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800285
286 // Verify that on the first error, the URL index advances to 1.
David Zeuthena99981f2013-04-29 13:42:47 -0700287 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800288 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700289 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800290
291 // Verify that on the next error, the URL index wraps around to 0.
292 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700293 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800294
295 // Verify that on the next error, it again advances to 1.
296 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700297 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
David Zeuthencc6f9962013-04-18 11:57:24 -0700298
299 // Verify that we switched URLs three times
300 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800301}
302
303TEST(PayloadStateTest, NewResponseResetsPayloadState) {
304 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700305 MockSystemState mock_system_state;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800306 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800307
Jay Srinivasan19409b72013-04-12 19:23:36 -0700308 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800309
Alex Deymob33b0f02013-08-08 21:10:02 -0700310 // The first response doesn't send an abandoned event.
311 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
312 "Installer.UpdatesAbandonedEventCount", 0, _, _, _)).Times(0);
313
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800314 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700315 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700316 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800317
318 // Advance the URL index to 1 by faking an error.
David Zeuthena99981f2013-04-29 13:42:47 -0700319 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800320 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700321 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
David Zeuthencc6f9962013-04-18 11:57:24 -0700322 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800323
Alex Deymob33b0f02013-08-08 21:10:02 -0700324 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
325 "Installer.UpdatesAbandonedEventCount", 1, _, _, _));
326
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800327 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700328 SetupPayloadStateWith2Urls("Hash8225", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700329 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800330
Alex Deymob33b0f02013-08-08 21:10:02 -0700331 // Fake an error again.
332 payload_state.UpdateFailed(error);
333 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
334 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
335
336 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
337 "Installer.UpdatesAbandonedEventCount", 2, _, _, _));
338
339 // Return a third different response.
340 SetupPayloadStateWith2Urls("Hash9999", true, &payload_state, &response);
341 EXPECT_EQ(3, payload_state.GetNumResponsesSeen());
342
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800343 // Make sure the url index was reset to 0 because of the new response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700344 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800345 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700346 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700347 EXPECT_EQ(0,
348 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
349 EXPECT_EQ(0,
350 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
351 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
352 kDownloadSourceHttpsServer));
353 EXPECT_EQ(0,
354 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800355}
356
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800357TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
358 OmahaResponse response;
359 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700360 MockSystemState mock_system_state;
361 int progress_bytes = 100;
362 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800363
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700364 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700365 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
366 .Times(AtLeast(2));
367 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
368 .Times(AtLeast(1));
369 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
370 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800371
Alex Deymo820cc702013-06-28 15:43:46 -0700372 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
373 .Times(AtLeast(2));
374 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
375 .Times(AtLeast(1));
376 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 2))
377 .Times(AtLeast(1));
378
Jay Srinivasan19409b72013-04-12 19:23:36 -0700379 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
Jay Srinivasan08262882012-12-28 19:29:43 -0800380
Jay Srinivasan19409b72013-04-12 19:23:36 -0700381 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
382 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800383
Jay Srinivasan19409b72013-04-12 19:23:36 -0700384 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
385 .Times(AtLeast(7));
386 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
387 .Times(AtLeast(2));
388 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
389 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800390
Jay Srinivasan19409b72013-04-12 19:23:36 -0700391 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
392 .Times(AtLeast(1));
393 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
394 .Times(AtLeast(1));
David Zeuthen9a017f22013-04-11 16:10:26 -0700395
Jay Srinivasan19409b72013-04-12 19:23:36 -0700396 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
397 .Times(AtLeast(1));
398 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
399 .Times(AtLeast(1));
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700400 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
401 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700402 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
403 .Times(AtLeast(1));
404 EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
405 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700406 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
407 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700408
409 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800410
Jay Srinivasan53173b92013-05-17 17:13:01 -0700411 SetupPayloadStateWith2Urls("Hash5873", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700412 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800413
414 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700415 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800416 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700417 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700418 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800419 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700420 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800421
422 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700423 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800424 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700425 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700426 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800427 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700428 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800429
430 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700431 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800432 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700433 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700434 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800435 EXPECT_EQ(2, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700436 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800437
438 // This should advance the URL index as we've reached the
439 // max failure count and reset the failure count for the new URL index.
440 // This should also wrap around the URL index and thus cause the payload
441 // attempt number to be incremented.
David Zeuthena99981f2013-04-29 13:42:47 -0700442 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800443 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700444 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700445 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800446 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700447 EXPECT_EQ(2, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800448 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800449
450 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700451 payload_state.UpdateFailed(kErrorCodePayloadHashMismatchError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800452 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700453 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700454 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800455 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700456 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800457 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800458
459 // This should advance the URL index and payload attempt number due to
460 // wrap-around of URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700461 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMissingError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800462 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700463 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700464 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800465 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700466 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800467 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800468
469 // This HTTP error code should only increase the failure count.
David Zeuthena99981f2013-04-29 13:42:47 -0700470 payload_state.UpdateFailed(static_cast<ErrorCode>(
471 kErrorCodeOmahaRequestHTTPResponseBase + 404));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800472 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700473 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700474 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800475 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700476 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800477 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800478
479 // And that failure count should be reset when we download some bytes
480 // afterwards.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700481 payload_state.DownloadProgress(progress_bytes);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800482 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700483 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700484 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800485 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700486 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800487 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800488
489 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700490 SetupPayloadStateWith2Urls("Hash8532", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700491 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800492
493 // Make sure the url index was reset to 0 because of the new response.
494 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700495 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700496 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800497 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700498 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800499 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800500}
501
Alex Deymo820cc702013-06-28 15:43:46 -0700502TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulFullDownload) {
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800503 OmahaResponse response;
Alex Deymo820cc702013-06-28 15:43:46 -0700504 response.is_delta_payload = false;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800505 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700506 MockSystemState mock_system_state;
507 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800508
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700509 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700510 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
511 .Times(AtLeast(1));
512 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
513 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800514
Alex Deymo820cc702013-06-28 15:43:46 -0700515 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
516 .Times(AtLeast(1));
517 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
518 .Times(AtLeast(1));
519
Jay Srinivasan19409b72013-04-12 19:23:36 -0700520 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
521 .Times(AtLeast(2));
Jay Srinivasan08262882012-12-28 19:29:43 -0800522
Jay Srinivasan19409b72013-04-12 19:23:36 -0700523 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
524 .Times(AtLeast(1));
525 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
526 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800527
Jay Srinivasan19409b72013-04-12 19:23:36 -0700528 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800529
Jay Srinivasan53173b92013-05-17 17:13:01 -0700530 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800531
Alex Deymo29b51d92013-07-09 15:26:24 -0700532 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
533 "Installer.PayloadAttemptNumber", 1, _, _, _));
534 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
535 "Installer.FullPayloadAttemptNumber", 1, _, _, _));
536
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800537 // This should just advance the payload attempt number;
538 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700539 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800540 payload_state.DownloadComplete();
541 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700542 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
543 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
544 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
545 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
546}
547
548TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDeltaDownload) {
549 OmahaResponse response;
550 response.is_delta_payload = true;
551 PayloadState payload_state;
552 MockSystemState mock_system_state;
553 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
554
555 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
556 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
557 .Times(AtLeast(1));
558 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
559 .Times(AtLeast(1));
560
561 // kPrefsFullPayloadAttemptNumber is not incremented for delta payloads.
562 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
563 .Times(AtLeast(1));
564
565 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
566 .Times(1);
567
568 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
569 .Times(AtLeast(1));
570 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
571 .Times(AtLeast(1));
572
573 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
574
575 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
576
Alex Deymo29b51d92013-07-09 15:26:24 -0700577 // Metrics for Full payload attempt number is not sent with Delta payloads.
578 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
579 "Installer.PayloadAttemptNumber", 1, _, _, _));
580 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
581 "Installer.FullPayloadAttemptNumber", _, _, _, _))
582 .Times(0);
583
Alex Deymo820cc702013-06-28 15:43:46 -0700584 // This should just advance the payload attempt number;
585 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
586 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
587 payload_state.DownloadComplete();
588 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
589 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700590 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800591 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700592 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800593}
594
595TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
596 OmahaResponse response;
597 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700598 MockSystemState mock_system_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800599
Jay Srinivasan19409b72013-04-12 19:23:36 -0700600 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700601 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800602
603 // Generate enough events to advance URL index, failure count and
604 // payload attempt number all to 1.
605 payload_state.DownloadComplete();
David Zeuthena99981f2013-04-29 13:42:47 -0700606 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
607 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800608 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700609 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700610 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800611 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700612 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800613
614 // Now, simulate a corrupted url index on persisted store which gets
615 // loaded when update_engine restarts. Using a different prefs object
616 // so as to not bother accounting for the uninteresting calls above.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700617 MockSystemState mock_system_state2;
618 NiceMock<PrefsMock>* prefs2 = mock_system_state2.mock_prefs();
619 EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
620 EXPECT_CALL(*prefs2, GetInt64(_,_)).Times(AtLeast(1));
621 EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
622 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700623 EXPECT_CALL(*prefs2, GetInt64(kPrefsFullPayloadAttemptNumber, _))
624 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700625 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
626 .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
627 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
628 .Times(AtLeast(1));
David Zeuthencc6f9962013-04-18 11:57:24 -0700629 EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _))
630 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800631
632 // Note: This will be a different payload object, but the response should
633 // have the same hash as before so as to not trivially reset because the
634 // response was different. We want to specifically test that even if the
635 // response is same, we should reset the state if we find it corrupted.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700636 EXPECT_TRUE(payload_state.Initialize(&mock_system_state2));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700637 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800638
639 // Make sure all counters get reset to 0 because of the corrupted URL index
640 // we supplied above.
641 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700642 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700643 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800644 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700645 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800646}
Jay Srinivasan08262882012-12-28 19:29:43 -0800647
Chris Sosa20f005c2013-09-05 13:53:08 -0700648TEST(PayloadStateTest, NoBackoffInteractiveChecks) {
649 OmahaResponse response;
650 response.is_delta_payload = false;
651 PayloadState payload_state;
652 MockSystemState mock_system_state;
653 OmahaRequestParams params(&mock_system_state);
654 params.Init("", "", true); // is_interactive = True.
655 mock_system_state.set_request_params(&params);
656
657 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
658 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
659
660 // Simulate two failures (enough to cause payload backoff) and check
661 // again that we're ready to re-download without any backoff as this is
662 // an interactive check.
663 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
664 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
665 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
666 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
667 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
668 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
669}
670
671TEST(PayloadStateTest, NoBackoffForP2PUpdates) {
672 OmahaResponse response;
673 response.is_delta_payload = false;
674 PayloadState payload_state;
675 MockSystemState mock_system_state;
676 OmahaRequestParams params(&mock_system_state);
677 params.Init("", "", false); // is_interactive = False.
678 mock_system_state.set_request_params(&params);
679
680 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
681 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
682
683 // Simulate two failures (enough to cause payload backoff) and check
684 // again that we're ready to re-download without any backoff as this is
685 // an interactive check.
686 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
687 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
688 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
689 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
690 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
691 // Set p2p url.
692 params.set_use_p2p_for_downloading(true);
693 params.set_p2p_url("http://mypeer:52909/path/to/file");
694 // Should not backoff for p2p updates.
695 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
696
697 params.set_p2p_url("");
698 // No actual p2p update if no url is provided.
699 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
700}
701
Jay Srinivasan08262882012-12-28 19:29:43 -0800702TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
703 OmahaResponse response;
704 response.is_delta_payload = true;
705 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700706 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800707
Jay Srinivasan19409b72013-04-12 19:23:36 -0700708 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700709 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800710
711 // Simulate a successful download and see that we're ready to download
712 // again without any backoff as this is a delta payload.
713 payload_state.DownloadComplete();
Alex Deymo820cc702013-06-28 15:43:46 -0700714 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
715 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800716 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
717
718 // Simulate two failures (enough to cause payload backoff) and check
719 // again that we're ready to re-download without any backoff as this is
720 // a delta payload.
David Zeuthena99981f2013-04-29 13:42:47 -0700721 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
722 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700723 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Alex Deymo820cc702013-06-28 15:43:46 -0700724 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
725 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800726 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
727}
728
729static void CheckPayloadBackoffState(PayloadState* payload_state,
730 int expected_attempt_number,
731 TimeDelta expected_days) {
732 payload_state->DownloadComplete();
Alex Deymo820cc702013-06-28 15:43:46 -0700733 EXPECT_EQ(expected_attempt_number,
734 payload_state->GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800735 EXPECT_TRUE(payload_state->ShouldBackoffDownload());
736 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
737 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
738 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
739 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
740 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
741 EXPECT_LT(expected_min_time.ToInternalValue(),
742 backoff_expiry_time.ToInternalValue());
743 EXPECT_GT(expected_max_time.ToInternalValue(),
744 backoff_expiry_time.ToInternalValue());
745}
746
747TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
748 OmahaResponse response;
749 response.is_delta_payload = false;
750 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700751 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800752
Jay Srinivasan19409b72013-04-12 19:23:36 -0700753 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700754 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800755
756 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
757 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
758 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
759 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
760 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
761 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
762 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
763 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
764 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
765 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
766}
767
768TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
769 OmahaResponse response;
770 response.disable_payload_backoff = true;
771 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700772 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800773
Jay Srinivasan19409b72013-04-12 19:23:36 -0700774 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700775 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800776
777 // Simulate a successful download and see that we are ready to download
778 // again without any backoff.
779 payload_state.DownloadComplete();
780 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700781 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800782 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
783
784 // Test again, this time by simulating two errors that would cause
785 // the payload attempt number to increment due to wrap around. And
786 // check that we are still ready to re-download without any backoff.
David Zeuthena99981f2013-04-29 13:42:47 -0700787 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
788 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan08262882012-12-28 19:29:43 -0800789 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700790 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800791 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
792}
793
Jay Srinivasan19409b72013-04-12 19:23:36 -0700794TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
795 OmahaResponse response;
796 response.disable_payload_backoff = true;
797 PayloadState payload_state;
798 MockSystemState mock_system_state;
799 int https_total = 0;
800 int http_total = 0;
801
802 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700803 SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700804 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700805
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700806 // Simulate a previous attempt with in order to set an initial non-zero value
807 // for the total bytes downloaded for HTTP.
808 int prev_chunk = 323456789;
809 http_total += prev_chunk;
810 payload_state.DownloadProgress(prev_chunk);
811
812 // Ensure that the initial values for HTTP reflect this attempt.
813 EXPECT_EQ(prev_chunk,
814 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
815 EXPECT_EQ(http_total,
816 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
817
818 // Change the response hash so as to simulate a new response which will
819 // reset the current bytes downloaded, but not the total bytes downloaded.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700820 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700821 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700822
823 // First, simulate successful download of a few bytes over HTTP.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700824 int first_chunk = 5000000;
825 http_total += first_chunk;
826 payload_state.DownloadProgress(first_chunk);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700827 // Test that first all progress is made on HTTP and none on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700828 EXPECT_EQ(first_chunk,
829 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
830 EXPECT_EQ(http_total,
831 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
832 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
833 kDownloadSourceHttpsServer));
834 EXPECT_EQ(https_total,
835 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
836
837 // Simulate an error that'll cause the url index to point to https.
David Zeuthena99981f2013-04-29 13:42:47 -0700838 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700839 payload_state.UpdateFailed(error);
840
Jay Srinivasan53173b92013-05-17 17:13:01 -0700841 // Test that no new progress is made on HTTP and new progress is on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700842 int second_chunk = 23456789;
843 https_total += second_chunk;
844 payload_state.DownloadProgress(second_chunk);
845 EXPECT_EQ(first_chunk,
846 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
847 EXPECT_EQ(http_total,
848 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
849 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
850 kDownloadSourceHttpsServer));
851 EXPECT_EQ(https_total,
852 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
853
854 // Simulate error to go back to http.
855 payload_state.UpdateFailed(error);
856 int third_chunk = 32345678;
857 int http_chunk = first_chunk + third_chunk;
858 http_total += third_chunk;
859 int https_chunk = second_chunk;
860 payload_state.DownloadProgress(third_chunk);
861
862 // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
863 EXPECT_EQ(http_chunk,
864 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700865 EXPECT_EQ(http_total,
Jay Srinivasan19409b72013-04-12 19:23:36 -0700866 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
867 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
868 kDownloadSourceHttpsServer));
869 EXPECT_EQ(https_total,
870 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
871
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700872 // Simulate error (will cause URL switch), set p2p is to be used and
873 // then do 42MB worth of progress
874 payload_state.UpdateFailed(error);
875 payload_state.SetUsingP2PForDownloading(true);
876 int p2p_total = 42 * 1000 * 1000;
877 payload_state.DownloadProgress(p2p_total);
878
879 EXPECT_EQ(p2p_total,
880 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpPeer));
881
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700882 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
883 .Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700884 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
885 "Installer.SuccessfulMBsDownloadedFromHttpServer",
886 http_chunk / kNumBytesInOneMiB, _, _, _));
887 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
888 "Installer.TotalMBsDownloadedFromHttpServer",
889 http_total / kNumBytesInOneMiB, _, _, _));
890 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
891 "Installer.SuccessfulMBsDownloadedFromHttpsServer",
892 https_chunk / kNumBytesInOneMiB, _, _, _));
893 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
894 "Installer.TotalMBsDownloadedFromHttpsServer",
895 https_total / kNumBytesInOneMiB, _, _, _));
David Zeuthencc6f9962013-04-18 11:57:24 -0700896 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700897 "Installer.SuccessfulMBsDownloadedFromHttpPeer",
898 p2p_total / kNumBytesInOneMiB, _, _, _));
899 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
900 "Installer.TotalMBsDownloadedFromHttpPeer",
901 p2p_total / kNumBytesInOneMiB, _, _, _));
902 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthencc6f9962013-04-18 11:57:24 -0700903 "Installer.UpdateURLSwitches",
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700904 3, _, _, _));
David Zeuthen674c3182013-04-18 14:05:20 -0700905 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
906 "Installer.UpdateDurationMinutes",
907 _, _, _, _));
908 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
909 "Installer.UpdateDurationUptimeMinutes",
910 _, _, _, _));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700911 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700912 "Installer.DownloadSourcesUsed",
913 (1 << kDownloadSourceHttpsServer) | (1 << kDownloadSourceHttpServer) |
914 (1 << kDownloadSourceHttpPeer),
915 _, _, _));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700916 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700917 "Installer.DownloadOverheadPercentage", 318, _, _, _));
Alex Deymo1c656c42013-06-28 11:02:14 -0700918 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
919 "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
Alex Deymo820cc702013-06-28 15:43:46 -0700920 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
921 "Installer.AttemptsCount.Total", 1, _, _, _));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700922
923 payload_state.UpdateSucceeded();
924
925 // Make sure the metrics are reset after a successful update.
926 EXPECT_EQ(0,
927 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
928 EXPECT_EQ(0,
929 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
930 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
931 kDownloadSourceHttpsServer));
932 EXPECT_EQ(0,
933 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
David Zeuthena573d6f2013-06-14 16:13:36 -0700934 EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700935}
936
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700937TEST(PayloadStateTest, DownloadSourcesUsedIsCorrect) {
938 OmahaResponse response;
939 PayloadState payload_state;
940 MockSystemState mock_system_state;
941
942 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
943 SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
944
945 // Simulate progress in order to mark HTTP as one of the sources used.
946 int num_bytes = 42 * 1000 * 1000;
947 payload_state.DownloadProgress(num_bytes);
948
949 // Check that this was done via HTTP.
950 EXPECT_EQ(num_bytes,
951 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
952 EXPECT_EQ(num_bytes,
953 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
954
955 // Check that only HTTP is reported as a download source.
956 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
957 .Times(AnyNumber());
958 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
959 "Installer.DownloadSourcesUsed",
960 (1 << kDownloadSourceHttpServer),
961 _, _, _));
962
963 payload_state.UpdateSucceeded();
964}
965
Jay Srinivasan19409b72013-04-12 19:23:36 -0700966TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
967 OmahaResponse response;
968 MockSystemState mock_system_state;
969 PayloadState payload_state;
970
971 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
972
973 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700974 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
Jay Srinivasan19409b72013-04-12 19:23:36 -0700975
976 int num_bytes = 10000;
977 payload_state.DownloadProgress(num_bytes);
978 EXPECT_EQ(num_bytes,
979 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
980 EXPECT_EQ(num_bytes,
981 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
982 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
983 kDownloadSourceHttpsServer));
984 EXPECT_EQ(0,
985 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
986
987 payload_state.UpdateRestarted();
988 // Make sure the current bytes downloaded is reset, but not the total bytes.
989 EXPECT_EQ(0,
990 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
991 EXPECT_EQ(num_bytes,
992 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
993}
994
Chris Sosabe45bef2013-04-09 18:25:12 -0700995TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
996 MockSystemState mock_system_state;
997 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700998
Chris Sosabe45bef2013-04-09 18:25:12 -0700999 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
1000 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
1001 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
1002
1003 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1004
1005 payload_state.UpdateRestarted();
1006 EXPECT_EQ(0, payload_state.GetNumReboots());
1007
1008 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(true));
1009 payload_state.UpdateResumed();
1010 // Num reboots should be incremented because system rebooted detected.
1011 EXPECT_EQ(1, payload_state.GetNumReboots());
1012
1013 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(false));
1014 payload_state.UpdateResumed();
1015 // Num reboots should now be 1 as reboot was not detected.
1016 EXPECT_EQ(1, payload_state.GetNumReboots());
1017
1018 // Restart the update again to verify we set the num of reboots back to 0.
1019 payload_state.UpdateRestarted();
1020 EXPECT_EQ(0, payload_state.GetNumReboots());
1021}
Jay Srinivasan19409b72013-04-12 19:23:36 -07001022
Chris Sosaaa18e162013-06-20 13:20:30 -07001023TEST(PayloadStateTest, RollbackVersion) {
1024 MockSystemState mock_system_state;
1025 PayloadState payload_state;
1026
1027 NiceMock<PrefsMock>* mock_powerwash_safe_prefs =
1028 mock_system_state.mock_powerwash_safe_prefs();
1029 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1030
1031 // Verify pre-conditions are good.
1032 EXPECT_TRUE(payload_state.GetRollbackVersion().empty());
1033
1034 // Mock out the os version and make sure it's blacklisted correctly.
1035 string rollback_version = "2345.0.0";
1036 OmahaRequestParams params(&mock_system_state);
1037 params.Init(rollback_version, "", false);
1038 mock_system_state.set_request_params(&params);
1039
1040 EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion,
1041 rollback_version));
1042 payload_state.Rollback();
1043
1044 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
Chris Sosab3dcdb32013-09-04 15:22:12 -07001045
1046 // Change it up a little and verify we load it correctly.
1047 rollback_version = "2345.0.1";
1048 // Let's verify we can reload it correctly.
1049 EXPECT_CALL(*mock_powerwash_safe_prefs, GetString(
1050 kPrefsRollbackVersion, _)).WillOnce(DoAll(
1051 SetArgumentPointee<1>(rollback_version), Return(true)));
1052 EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion,
1053 rollback_version));
1054 payload_state.LoadRollbackVersion();
1055 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
Chris Sosaaa18e162013-06-20 13:20:30 -07001056}
1057
David Zeuthenf413fe52013-04-22 14:04:39 -07001058TEST(PayloadStateTest, DurationsAreCorrect) {
1059 OmahaResponse response;
1060 PayloadState payload_state;
1061 MockSystemState mock_system_state;
1062 FakeClock fake_clock;
1063 Prefs prefs;
1064 string temp_dir;
1065
1066 // Set the clock to a well-known time - 1 second on the wall-clock
1067 // and 2 seconds on the monotonic clock
1068 fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
1069 fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
1070
1071 // We need persistent preferences for this test
Gilad Arnolda6742b32014-01-11 00:18:34 -08001072 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateDurationTests.XXXXXX",
David Zeuthenf413fe52013-04-22 14:04:39 -07001073 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001074 prefs.Init(base::FilePath(temp_dir));
David Zeuthenf413fe52013-04-22 14:04:39 -07001075
1076 mock_system_state.set_clock(&fake_clock);
1077 mock_system_state.set_prefs(&prefs);
1078 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1079
1080 // Check that durations are correct for a successful update where
1081 // time has advanced 7 seconds on the wall clock and 4 seconds on
1082 // the monotonic clock.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001083 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -07001084 fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
1085 fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
1086 payload_state.UpdateSucceeded();
1087 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
1088 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
1089
1090 // Check that durations are reset when a new response comes in.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001091 SetupPayloadStateWith2Urls("Hash8594", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -07001092 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
1093 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
1094
1095 // Advance time a bit (10 secs), simulate download progress and
1096 // check that durations are updated.
1097 fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
1098 fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
1099 payload_state.DownloadProgress(10);
1100 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
1101 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
1102
1103 // Now simulate a reboot by resetting monotonic time (to 5000) and
1104 // creating a new PayloadState object and check that we load the
1105 // durations correctly (e.g. they are the same as before).
1106 fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
1107 PayloadState payload_state2;
1108 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
1109 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
1110 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),10000000);
1111
1112 // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
1113 // and check that the durations are increased accordingly.
1114 fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
1115 fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
1116 payload_state2.UpdateSucceeded();
1117 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
1118 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),16000000);
1119
1120 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1121}
1122
David Zeuthene4c58bf2013-06-18 17:26:50 -07001123TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
1124 OmahaResponse response;
1125 PayloadState payload_state;
1126 MockSystemState mock_system_state;
1127 FakeClock fake_clock;
1128 Prefs prefs;
1129 string temp_dir;
1130
1131 // Set the clock to a well-known time (t = 30 seconds).
1132 fake_clock.SetWallclockTime(Time::FromInternalValue(
1133 30 * Time::kMicrosecondsPerSecond));
1134
1135 // We need persistent preferences for this test
1136 EXPECT_TRUE(utils::MakeTempDirectory(
Gilad Arnolda6742b32014-01-11 00:18:34 -08001137 "RebootAfterSuccessfulUpdateTest.XXXXXX", &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001138 prefs.Init(base::FilePath(temp_dir));
David Zeuthene4c58bf2013-06-18 17:26:50 -07001139
1140 mock_system_state.set_clock(&fake_clock);
1141 mock_system_state.set_prefs(&prefs);
1142 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1143
1144 // Make the update succeed.
1145 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1146 payload_state.UpdateSucceeded();
1147
1148 // Check that the marker was written.
1149 EXPECT_TRUE(prefs.Exists(kPrefsSystemUpdatedMarker));
1150
1151 // Now simulate a reboot and set the wallclock time to a later point
1152 // (t = 500 seconds). We do this by using a new PayloadState object
1153 // and checking that it emits the right UMA metric with the right
1154 // value.
1155 fake_clock.SetWallclockTime(Time::FromInternalValue(
1156 500 * Time::kMicrosecondsPerSecond));
1157 PayloadState payload_state2;
1158 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
1159
1160 // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
1161 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1162 "Installer.TimeToRebootMinutes",
1163 7, _, _, _));
Alex Deymo569c4242013-07-24 12:01:01 -07001164 EXPECT_CALL(mock_system_state, system_rebooted())
1165 .WillRepeatedly(Return(true));
David Zeuthene4c58bf2013-06-18 17:26:50 -07001166
1167 payload_state2.UpdateEngineStarted();
1168
1169 // Check that the marker was nuked.
1170 EXPECT_FALSE(prefs.Exists(kPrefsSystemUpdatedMarker));
1171
1172 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1173}
1174
Alex Deymo569c4242013-07-24 12:01:01 -07001175TEST(PayloadStateTest, RestartAfterCrash) {
1176 PayloadState payload_state;
1177 MockSystemState mock_system_state;
1178 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
1179
1180 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1181
1182 // No prefs should be used after a crash.
1183 EXPECT_CALL(*prefs, Exists(_)).Times(0);
1184 EXPECT_CALL(*prefs, SetString(_, _)).Times(0);
1185 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(0);
1186 EXPECT_CALL(*prefs, SetBoolean(_, _)).Times(0);
1187 EXPECT_CALL(*prefs, GetString(_, _)).Times(0);
1188 EXPECT_CALL(*prefs, GetInt64(_, _)).Times(0);
1189 EXPECT_CALL(*prefs, GetBoolean(_, _)).Times(0);
1190
1191 // No metrics are reported after a crash.
1192 EXPECT_CALL(*mock_system_state.mock_metrics_lib(),
1193 SendToUMA(_, _, _, _, _)).Times(0);
1194
1195 // Simulate an update_engine restart without a reboot.
1196 EXPECT_CALL(mock_system_state, system_rebooted())
1197 .WillRepeatedly(Return(false));
1198
1199 payload_state.UpdateEngineStarted();
1200}
1201
Jay Srinivasan53173b92013-05-17 17:13:01 -07001202TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
1203 OmahaResponse response;
1204 MockSystemState mock_system_state;
1205 PayloadState payload_state;
1206
Jay Srinivasan53173b92013-05-17 17:13:01 -07001207 policy::MockDevicePolicy disable_http_policy;
1208 EXPECT_CALL(mock_system_state, device_policy())
1209 .WillRepeatedly(Return(&disable_http_policy));
Chris Sosaf7d80042013-08-22 16:45:17 -07001210 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1211
1212 // Test with no device policy. Should default to allowing http.
1213 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1214 .WillRepeatedly(Return(false));
1215
1216 // Set the first response.
1217 SetupPayloadStateWith2Urls("Hash8433", true, &payload_state, &response);
1218
1219 // Check that we use the HTTP URL since there is no value set for allowing
1220 // http.
1221 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1222
1223 // Test with device policy not allowing http updates.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001224 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1225 .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
1226
Chris Sosaf7d80042013-08-22 16:45:17 -07001227 // Reset state and set again.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001228 SetupPayloadStateWith2Urls("Hash8433", false, &payload_state, &response);
1229
1230 // Check that we skip the HTTP URL and use only the HTTPS url.
1231 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1232
1233 // Advance the URL index to 1 by faking an error.
1234 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
1235 payload_state.UpdateFailed(error);
1236
1237 // Check that we still skip the HTTP URL and use only the HTTPS url.
1238 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1239 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
1240
1241 // Now, slightly change the response and set it again.
1242 SetupPayloadStateWith2Urls("Hash2399", false, &payload_state, &response);
1243
1244 // Check that we still skip the HTTP URL and use only the HTTPS url.
1245 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1246
1247 // Now, pretend that the HTTP policy is turned on. We want to make sure
1248 // the new policy is honored.
1249 policy::MockDevicePolicy enable_http_policy;
1250 EXPECT_CALL(mock_system_state, device_policy())
1251 .WillRepeatedly(Return(&enable_http_policy));
1252 EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
1253 .WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
1254
1255 // Now, set the same response using the same hash
1256 // so that we can test that the state is reset not because of the
1257 // hash but because of the policy change which results in candidate url
1258 // list change.
1259 SetupPayloadStateWith2Urls("Hash2399", true, &payload_state, &response);
1260
1261 // Check that we use the HTTP URL now and the failure count is reset.
1262 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1263 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1264
1265 // Fake a failure and see if we're moving over to the HTTPS url and update
1266 // the URL switch count properly.
1267 payload_state.UpdateFailed(error);
1268 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1269 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
1270 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1271}
1272
Alex Deymo1c656c42013-06-28 11:02:14 -07001273TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
1274 OmahaResponse response;
1275 response.is_delta_payload = true;
1276 PayloadState payload_state;
1277 MockSystemState mock_system_state;
1278
1279 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1280 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1281
1282 // Simulate a successful download and update.
1283 payload_state.DownloadComplete();
1284
1285 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1286 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
1287 payload_state.UpdateSucceeded();
1288
1289 // Mock the request to a request where the delta was disabled but Omaha sends
1290 // a delta anyway and test again.
1291 OmahaRequestParams params(&mock_system_state);
1292 params.set_delta_okay(false);
1293 mock_system_state.set_request_params(&params);
1294
1295 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1296 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1297
1298 payload_state.DownloadComplete();
1299
1300 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1301 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
1302 payload_state.UpdateSucceeded();
1303}
1304
1305TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
1306 OmahaResponse response;
1307 response.is_delta_payload = false;
1308 PayloadState payload_state;
1309 MockSystemState mock_system_state;
1310
1311 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1312 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1313
1314 // Mock the request to a request where the delta was disabled.
1315 OmahaRequestParams params(&mock_system_state);
1316 params.set_delta_okay(false);
1317 mock_system_state.set_request_params(&params);
1318
1319 // Simulate a successful download and update.
1320 payload_state.DownloadComplete();
1321
1322 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1323 "Installer.PayloadFormat", kPayloadTypeForcedFull, kNumPayloadTypes));
1324 payload_state.UpdateSucceeded();
1325}
1326
1327TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
1328 OmahaResponse response;
1329 response.is_delta_payload = false;
1330 PayloadState payload_state;
1331 MockSystemState mock_system_state;
1332
1333 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1334 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1335
Alex Deymo820cc702013-06-28 15:43:46 -07001336 // Mock the request to a request where the delta is enabled, although the
1337 // result is full.
Alex Deymo1c656c42013-06-28 11:02:14 -07001338 OmahaRequestParams params(&mock_system_state);
1339 params.set_delta_okay(true);
1340 mock_system_state.set_request_params(&params);
1341
1342 // Simulate a successful download and update.
1343 payload_state.DownloadComplete();
1344
1345 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1346 "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
1347 payload_state.UpdateSucceeded();
1348}
1349
Alex Deymo42432912013-07-12 20:21:15 -07001350TEST(PayloadStateTest, RebootAfterUpdateFailedMetric) {
Alex Deymo42432912013-07-12 20:21:15 -07001351 MockSystemState mock_system_state;
1352 OmahaResponse response;
1353 PayloadState payload_state;
1354 Prefs prefs;
1355 string temp_dir;
1356
1357 // Setup an environment with persistent prefs across simulated reboots.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001358 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateReboot.XXXXXX",
Alex Deymo42432912013-07-12 20:21:15 -07001359 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001360 prefs.Init(base::FilePath(temp_dir));
Alex Deymo42432912013-07-12 20:21:15 -07001361 mock_system_state.set_prefs(&prefs);
1362
Don Garrett6646b442013-11-13 15:29:11 -08001363 FakeHardware* fake_hardware = mock_system_state.get_fake_hardware();
1364 fake_hardware->SetBootDevice("/dev/sda3");
Alex Deymo42432912013-07-12 20:21:15 -07001365
1366 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1367 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1368
1369 // Simulate a successful download and update.
1370 payload_state.DownloadComplete();
1371 payload_state.UpdateSucceeded();
1372 payload_state.ExpectRebootInNewVersion("Version:12345678");
1373
1374 // Reboot into the same environment to get an UMA metric with a value of 1.
1375 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1376 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
1377 payload_state.ReportFailedBootIfNeeded();
1378 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1379
1380 // Simulate a second update and reboot into the same environment, this should
1381 // send a value of 2.
1382 payload_state.ExpectRebootInNewVersion("Version:12345678");
1383
1384 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1385 "Installer.RebootToNewPartitionAttempt", 2, _, _, _));
1386 payload_state.ReportFailedBootIfNeeded();
1387 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1388
1389 // Simulate a third failed reboot to new version, but this time for a
1390 // different payload. This should send a value of 1 this time.
1391 payload_state.ExpectRebootInNewVersion("Version:3141592");
1392 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1393 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
1394 payload_state.ReportFailedBootIfNeeded();
1395 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1396
1397 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1398}
1399
1400TEST(PayloadStateTest, RebootAfterUpdateSucceed) {
Alex Deymo42432912013-07-12 20:21:15 -07001401 MockSystemState mock_system_state;
1402 OmahaResponse response;
1403 PayloadState payload_state;
1404 Prefs prefs;
1405 string temp_dir;
1406
1407 // Setup an environment with persistent prefs across simulated reboots.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001408 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateReboot.XXXXXX",
Alex Deymo42432912013-07-12 20:21:15 -07001409 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001410 prefs.Init(base::FilePath(temp_dir));
Alex Deymo42432912013-07-12 20:21:15 -07001411 mock_system_state.set_prefs(&prefs);
1412
Don Garrett6646b442013-11-13 15:29:11 -08001413 FakeHardware* fake_hardware = mock_system_state.get_fake_hardware();
1414 fake_hardware->SetBootDevice("/dev/sda3");
Alex Deymo42432912013-07-12 20:21:15 -07001415
1416 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1417 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1418
1419 // Simulate a successful download and update.
1420 payload_state.DownloadComplete();
1421 payload_state.UpdateSucceeded();
1422 payload_state.ExpectRebootInNewVersion("Version:12345678");
1423
1424 // Change the BootDevice to a different one, no metric should be sent.
Don Garrett6646b442013-11-13 15:29:11 -08001425 fake_hardware->SetBootDevice("/dev/sda5");
Alex Deymo42432912013-07-12 20:21:15 -07001426
1427 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1428 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1429 .Times(0);
1430 payload_state.ReportFailedBootIfNeeded();
1431
1432 // A second reboot in eiher partition should not send a metric.
1433 payload_state.ReportFailedBootIfNeeded();
Don Garrett6646b442013-11-13 15:29:11 -08001434 fake_hardware->SetBootDevice("/dev/sda3");
Alex Deymo42432912013-07-12 20:21:15 -07001435 payload_state.ReportFailedBootIfNeeded();
1436
1437 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1438}
1439
1440TEST(PayloadStateTest, RebootAfterCanceledUpdate) {
1441 MockSystemState mock_system_state;
1442 OmahaResponse response;
1443 PayloadState payload_state;
1444 Prefs prefs;
1445 string temp_dir;
1446
1447 // Setup an environment with persistent prefs across simulated reboots.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001448 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateReboot.XXXXXX",
Alex Deymo42432912013-07-12 20:21:15 -07001449 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001450 prefs.Init(base::FilePath(temp_dir));
Alex Deymo42432912013-07-12 20:21:15 -07001451 mock_system_state.set_prefs(&prefs);
1452
1453 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1454 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1455
1456 // Simulate a successful download and update.
1457 payload_state.DownloadComplete();
1458 payload_state.UpdateSucceeded();
1459 payload_state.ExpectRebootInNewVersion("Version:12345678");
1460
1461 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1462 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1463 .Times(0);
1464
1465 // Cancel the applied update.
1466 payload_state.ResetUpdateStatus();
1467
1468 // Simulate a reboot.
1469 payload_state.ReportFailedBootIfNeeded();
1470
1471 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1472}
1473
1474TEST(PayloadStateTest, UpdateSuccessWithWipedPrefs) {
1475 MockSystemState mock_system_state;
1476 PayloadState payload_state;
1477 Prefs prefs;
1478 string temp_dir;
1479
1480 // Setup an environment with persistent but initially empty prefs.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001481 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateReboot.XXXXXX",
Alex Deymo42432912013-07-12 20:21:15 -07001482 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001483 prefs.Init(base::FilePath(temp_dir));
Alex Deymo42432912013-07-12 20:21:15 -07001484 mock_system_state.set_prefs(&prefs);
1485
1486 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1487
1488 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1489 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1490 .Times(0);
1491
1492 // Simulate a reboot in this environment.
1493 payload_state.ReportFailedBootIfNeeded();
1494
1495 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1496}
1497
David Zeuthendcba8092013-08-06 12:16:35 -07001498TEST(PayloadStateTest, DisallowP2PAfterTooManyAttempts) {
1499 OmahaResponse response;
1500 PayloadState payload_state;
1501 MockSystemState mock_system_state;
1502 Prefs prefs;
1503 string temp_dir;
1504
1505 // We need persistent preferences for this test.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001506 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001507 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001508 prefs.Init(base::FilePath(temp_dir));
David Zeuthendcba8092013-08-06 12:16:35 -07001509
1510 mock_system_state.set_prefs(&prefs);
1511 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1512 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1513
1514 // Should allow exactly kMaxP2PAttempts...
1515 for (int n = 0; n < kMaxP2PAttempts; n++) {
1516 payload_state.P2PNewAttempt();
1517 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1518 }
1519 // ... but not more than that.
1520 payload_state.P2PNewAttempt();
1521 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1522
1523 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1524}
1525
1526TEST(PayloadStateTest, DisallowP2PAfterDeadline) {
1527 OmahaResponse response;
1528 PayloadState payload_state;
1529 MockSystemState mock_system_state;
1530 FakeClock fake_clock;
1531 Prefs prefs;
1532 string temp_dir;
1533
1534 // We need persistent preferences for this test.
Gilad Arnolda6742b32014-01-11 00:18:34 -08001535 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001536 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001537 prefs.Init(base::FilePath(temp_dir));
David Zeuthendcba8092013-08-06 12:16:35 -07001538
1539 mock_system_state.set_clock(&fake_clock);
1540 mock_system_state.set_prefs(&prefs);
1541 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1542 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1543
1544 // Set the clock to 1 second.
1545 Time epoch = Time::FromInternalValue(1000000);
1546 fake_clock.SetWallclockTime(epoch);
1547
1548 // Do an attempt - this will set the timestamp.
1549 payload_state.P2PNewAttempt();
1550
1551 // Check that the timestamp equals what we just set.
1552 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1553
1554 // Time hasn't advanced - this should work.
1555 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1556
1557 // Set clock to half the deadline - this should work.
1558 fake_clock.SetWallclockTime(epoch +
1559 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds) / 2);
1560 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1561
1562 // Check that the first attempt timestamp hasn't changed just
1563 // because the wall-clock time changed.
1564 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1565
1566 // Set clock to _just_ before the deadline - this should work.
1567 fake_clock.SetWallclockTime(epoch +
1568 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds - 1));
1569 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1570
1571 // Set clock to _just_ after the deadline - this should not work.
1572 fake_clock.SetWallclockTime(epoch +
1573 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds + 1));
1574 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1575
1576 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1577}
1578
1579TEST(PayloadStateTest, P2PStateVarsInitialValue) {
1580 OmahaResponse response;
1581 PayloadState payload_state;
1582 MockSystemState mock_system_state;
1583 Prefs prefs;
1584 string temp_dir;
1585
Gilad Arnolda6742b32014-01-11 00:18:34 -08001586 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001587 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001588 prefs.Init(base::FilePath(temp_dir));
David Zeuthendcba8092013-08-06 12:16:35 -07001589 mock_system_state.set_prefs(&prefs);
1590 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1591 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1592
1593 Time null_time = Time();
1594 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1595 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1596
1597 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1598}
1599
1600TEST(PayloadStateTest, P2PStateVarsArePersisted) {
1601 OmahaResponse response;
1602 PayloadState payload_state;
1603 MockSystemState mock_system_state;
1604 FakeClock fake_clock;
1605 Prefs prefs;
1606 string temp_dir;
1607
Gilad Arnolda6742b32014-01-11 00:18:34 -08001608 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001609 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001610 prefs.Init(base::FilePath(temp_dir));
David Zeuthendcba8092013-08-06 12:16:35 -07001611 mock_system_state.set_clock(&fake_clock);
1612 mock_system_state.set_prefs(&prefs);
1613 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1614 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1615
1616 // Set the clock to something known.
1617 Time time = Time::FromInternalValue(12345);
1618 fake_clock.SetWallclockTime(time);
1619
1620 // New p2p attempt - as a side-effect this will update the p2p state vars.
1621 payload_state.P2PNewAttempt();
1622 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1623 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1624
1625 // Now create a new PayloadState and check that it loads the state
1626 // vars correctly.
1627 PayloadState payload_state2;
1628 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
1629 EXPECT_EQ(1, payload_state2.GetP2PNumAttempts());
1630 EXPECT_EQ(time, payload_state2.GetP2PFirstAttemptTimestamp());
1631
1632 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1633}
1634
1635TEST(PayloadStateTest, P2PStateVarsAreClearedOnNewResponse) {
1636 OmahaResponse response;
1637 PayloadState payload_state;
1638 MockSystemState mock_system_state;
1639 FakeClock fake_clock;
1640 Prefs prefs;
1641 string temp_dir;
1642
Gilad Arnolda6742b32014-01-11 00:18:34 -08001643 EXPECT_TRUE(utils::MakeTempDirectory("PayloadStateP2PTests.XXXXXX",
David Zeuthendcba8092013-08-06 12:16:35 -07001644 &temp_dir));
Alex Vakulenko75039d72014-03-25 12:36:28 -07001645 prefs.Init(base::FilePath(temp_dir));
David Zeuthendcba8092013-08-06 12:16:35 -07001646 mock_system_state.set_clock(&fake_clock);
1647 mock_system_state.set_prefs(&prefs);
1648 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1649 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1650
1651 // Set the clock to something known.
1652 Time time = Time::FromInternalValue(12345);
1653 fake_clock.SetWallclockTime(time);
1654
1655 // New p2p attempt - as a side-effect this will update the p2p state vars.
1656 payload_state.P2PNewAttempt();
1657 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1658 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1659
1660 // Set a new response...
1661 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
1662
1663 // ... and check that it clears the P2P state vars.
1664 Time null_time = Time();
1665 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1666 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1667
1668 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1669}
1670
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001671}