blob: d8032fe20fbb3f3d0a176d3f837cdd54df8d5542 [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
Chris Sosabe45bef2013-04-09 18:25:12 -07007#include "base/file_path.h"
8#include "base/file_util.h"
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08009#include "base/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) +
76 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 Garrett81018e02013-07-30 18:46:31 -070093 if (kErrorCodeUmaReportedMax != 44) {
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
648TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
649 OmahaResponse response;
650 response.is_delta_payload = true;
651 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700652 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800653
Jay Srinivasan19409b72013-04-12 19:23:36 -0700654 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700655 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800656
657 // Simulate a successful download and see that we're ready to download
658 // again without any backoff as this is a delta payload.
659 payload_state.DownloadComplete();
Alex Deymo820cc702013-06-28 15:43:46 -0700660 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
661 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800662 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
663
664 // Simulate two failures (enough to cause payload backoff) and check
665 // again that we're ready to re-download without any backoff as this is
666 // a delta payload.
David Zeuthena99981f2013-04-29 13:42:47 -0700667 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
668 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700669 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Alex Deymo820cc702013-06-28 15:43:46 -0700670 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
671 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800672 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
673}
674
675static void CheckPayloadBackoffState(PayloadState* payload_state,
676 int expected_attempt_number,
677 TimeDelta expected_days) {
678 payload_state->DownloadComplete();
Alex Deymo820cc702013-06-28 15:43:46 -0700679 EXPECT_EQ(expected_attempt_number,
680 payload_state->GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800681 EXPECT_TRUE(payload_state->ShouldBackoffDownload());
682 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
683 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
684 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
685 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
686 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
687 EXPECT_LT(expected_min_time.ToInternalValue(),
688 backoff_expiry_time.ToInternalValue());
689 EXPECT_GT(expected_max_time.ToInternalValue(),
690 backoff_expiry_time.ToInternalValue());
691}
692
693TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
694 OmahaResponse response;
695 response.is_delta_payload = false;
696 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700697 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800698
Jay Srinivasan19409b72013-04-12 19:23:36 -0700699 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700700 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800701
702 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
703 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
704 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
705 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
706 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
707 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
708 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
709 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
710 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
711 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
712}
713
714TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
715 OmahaResponse response;
716 response.disable_payload_backoff = true;
717 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700718 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800719
Jay Srinivasan19409b72013-04-12 19:23:36 -0700720 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700721 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800722
723 // Simulate a successful download and see that we are ready to download
724 // again without any backoff.
725 payload_state.DownloadComplete();
726 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700727 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800728 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
729
730 // Test again, this time by simulating two errors that would cause
731 // the payload attempt number to increment due to wrap around. And
732 // check that we are still ready to re-download without any backoff.
David Zeuthena99981f2013-04-29 13:42:47 -0700733 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
734 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan08262882012-12-28 19:29:43 -0800735 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700736 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800737 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
738}
739
Jay Srinivasan19409b72013-04-12 19:23:36 -0700740TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
741 OmahaResponse response;
742 response.disable_payload_backoff = true;
743 PayloadState payload_state;
744 MockSystemState mock_system_state;
745 int https_total = 0;
746 int http_total = 0;
747
748 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700749 SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700750 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700751
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700752 // Simulate a previous attempt with in order to set an initial non-zero value
753 // for the total bytes downloaded for HTTP.
754 int prev_chunk = 323456789;
755 http_total += prev_chunk;
756 payload_state.DownloadProgress(prev_chunk);
757
758 // Ensure that the initial values for HTTP reflect this attempt.
759 EXPECT_EQ(prev_chunk,
760 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
761 EXPECT_EQ(http_total,
762 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
763
764 // Change the response hash so as to simulate a new response which will
765 // reset the current bytes downloaded, but not the total bytes downloaded.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700766 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700767 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700768
769 // First, simulate successful download of a few bytes over HTTP.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700770 int first_chunk = 5000000;
771 http_total += first_chunk;
772 payload_state.DownloadProgress(first_chunk);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700773 // Test that first all progress is made on HTTP and none on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700774 EXPECT_EQ(first_chunk,
775 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
776 EXPECT_EQ(http_total,
777 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
778 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
779 kDownloadSourceHttpsServer));
780 EXPECT_EQ(https_total,
781 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
782
783 // Simulate an error that'll cause the url index to point to https.
David Zeuthena99981f2013-04-29 13:42:47 -0700784 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700785 payload_state.UpdateFailed(error);
786
Jay Srinivasan53173b92013-05-17 17:13:01 -0700787 // Test that no new progress is made on HTTP and new progress is on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700788 int second_chunk = 23456789;
789 https_total += second_chunk;
790 payload_state.DownloadProgress(second_chunk);
791 EXPECT_EQ(first_chunk,
792 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
793 EXPECT_EQ(http_total,
794 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
795 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
796 kDownloadSourceHttpsServer));
797 EXPECT_EQ(https_total,
798 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
799
800 // Simulate error to go back to http.
801 payload_state.UpdateFailed(error);
802 int third_chunk = 32345678;
803 int http_chunk = first_chunk + third_chunk;
804 http_total += third_chunk;
805 int https_chunk = second_chunk;
806 payload_state.DownloadProgress(third_chunk);
807
808 // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
809 EXPECT_EQ(http_chunk,
810 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700811 EXPECT_EQ(http_total,
Jay Srinivasan19409b72013-04-12 19:23:36 -0700812 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
813 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
814 kDownloadSourceHttpsServer));
815 EXPECT_EQ(https_total,
816 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
817
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700818 // Simulate error (will cause URL switch), set p2p is to be used and
819 // then do 42MB worth of progress
820 payload_state.UpdateFailed(error);
821 payload_state.SetUsingP2PForDownloading(true);
822 int p2p_total = 42 * 1000 * 1000;
823 payload_state.DownloadProgress(p2p_total);
824
825 EXPECT_EQ(p2p_total,
826 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpPeer));
827
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700828 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
829 .Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700830 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
831 "Installer.SuccessfulMBsDownloadedFromHttpServer",
832 http_chunk / kNumBytesInOneMiB, _, _, _));
833 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
834 "Installer.TotalMBsDownloadedFromHttpServer",
835 http_total / kNumBytesInOneMiB, _, _, _));
836 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
837 "Installer.SuccessfulMBsDownloadedFromHttpsServer",
838 https_chunk / kNumBytesInOneMiB, _, _, _));
839 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
840 "Installer.TotalMBsDownloadedFromHttpsServer",
841 https_total / kNumBytesInOneMiB, _, _, _));
David Zeuthencc6f9962013-04-18 11:57:24 -0700842 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700843 "Installer.SuccessfulMBsDownloadedFromHttpPeer",
844 p2p_total / kNumBytesInOneMiB, _, _, _));
845 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
846 "Installer.TotalMBsDownloadedFromHttpPeer",
847 p2p_total / kNumBytesInOneMiB, _, _, _));
848 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthencc6f9962013-04-18 11:57:24 -0700849 "Installer.UpdateURLSwitches",
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700850 3, _, _, _));
David Zeuthen674c3182013-04-18 14:05:20 -0700851 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
852 "Installer.UpdateDurationMinutes",
853 _, _, _, _));
854 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
855 "Installer.UpdateDurationUptimeMinutes",
856 _, _, _, _));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700857 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700858 "Installer.DownloadSourcesUsed",
859 (1 << kDownloadSourceHttpsServer) | (1 << kDownloadSourceHttpServer) |
860 (1 << kDownloadSourceHttpPeer),
861 _, _, _));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700862 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700863 "Installer.DownloadOverheadPercentage", 318, _, _, _));
Alex Deymo1c656c42013-06-28 11:02:14 -0700864 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
865 "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
Alex Deymo820cc702013-06-28 15:43:46 -0700866 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
867 "Installer.AttemptsCount.Total", 1, _, _, _));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700868
869 payload_state.UpdateSucceeded();
870
871 // Make sure the metrics are reset after a successful update.
872 EXPECT_EQ(0,
873 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
874 EXPECT_EQ(0,
875 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
876 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
877 kDownloadSourceHttpsServer));
878 EXPECT_EQ(0,
879 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
David Zeuthena573d6f2013-06-14 16:13:36 -0700880 EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700881}
882
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700883TEST(PayloadStateTest, DownloadSourcesUsedIsCorrect) {
884 OmahaResponse response;
885 PayloadState payload_state;
886 MockSystemState mock_system_state;
887
888 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
889 SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
890
891 // Simulate progress in order to mark HTTP as one of the sources used.
892 int num_bytes = 42 * 1000 * 1000;
893 payload_state.DownloadProgress(num_bytes);
894
895 // Check that this was done via HTTP.
896 EXPECT_EQ(num_bytes,
897 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
898 EXPECT_EQ(num_bytes,
899 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
900
901 // Check that only HTTP is reported as a download source.
902 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
903 .Times(AnyNumber());
904 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
905 "Installer.DownloadSourcesUsed",
906 (1 << kDownloadSourceHttpServer),
907 _, _, _));
908
909 payload_state.UpdateSucceeded();
910}
911
Jay Srinivasan19409b72013-04-12 19:23:36 -0700912TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
913 OmahaResponse response;
914 MockSystemState mock_system_state;
915 PayloadState payload_state;
916
917 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
918
919 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700920 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
Jay Srinivasan19409b72013-04-12 19:23:36 -0700921
922 int num_bytes = 10000;
923 payload_state.DownloadProgress(num_bytes);
924 EXPECT_EQ(num_bytes,
925 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
926 EXPECT_EQ(num_bytes,
927 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
928 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
929 kDownloadSourceHttpsServer));
930 EXPECT_EQ(0,
931 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
932
933 payload_state.UpdateRestarted();
934 // Make sure the current bytes downloaded is reset, but not the total bytes.
935 EXPECT_EQ(0,
936 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
937 EXPECT_EQ(num_bytes,
938 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
939}
940
Chris Sosabe45bef2013-04-09 18:25:12 -0700941TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
942 MockSystemState mock_system_state;
943 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700944
Chris Sosabe45bef2013-04-09 18:25:12 -0700945 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
946 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
947 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
948
949 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
950
951 payload_state.UpdateRestarted();
952 EXPECT_EQ(0, payload_state.GetNumReboots());
953
954 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(true));
955 payload_state.UpdateResumed();
956 // Num reboots should be incremented because system rebooted detected.
957 EXPECT_EQ(1, payload_state.GetNumReboots());
958
959 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(false));
960 payload_state.UpdateResumed();
961 // Num reboots should now be 1 as reboot was not detected.
962 EXPECT_EQ(1, payload_state.GetNumReboots());
963
964 // Restart the update again to verify we set the num of reboots back to 0.
965 payload_state.UpdateRestarted();
966 EXPECT_EQ(0, payload_state.GetNumReboots());
967}
Jay Srinivasan19409b72013-04-12 19:23:36 -0700968
Chris Sosaaa18e162013-06-20 13:20:30 -0700969TEST(PayloadStateTest, RollbackVersion) {
970 MockSystemState mock_system_state;
971 PayloadState payload_state;
972
973 NiceMock<PrefsMock>* mock_powerwash_safe_prefs =
974 mock_system_state.mock_powerwash_safe_prefs();
975 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
976
977 // Verify pre-conditions are good.
978 EXPECT_TRUE(payload_state.GetRollbackVersion().empty());
979
980 // Mock out the os version and make sure it's blacklisted correctly.
981 string rollback_version = "2345.0.0";
982 OmahaRequestParams params(&mock_system_state);
983 params.Init(rollback_version, "", false);
984 mock_system_state.set_request_params(&params);
985
986 EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion,
987 rollback_version));
988 payload_state.Rollback();
989
990 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
Chris Sosab3dcdb32013-09-04 15:22:12 -0700991
992 // Change it up a little and verify we load it correctly.
993 rollback_version = "2345.0.1";
994 // Let's verify we can reload it correctly.
995 EXPECT_CALL(*mock_powerwash_safe_prefs, GetString(
996 kPrefsRollbackVersion, _)).WillOnce(DoAll(
997 SetArgumentPointee<1>(rollback_version), Return(true)));
998 EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion,
999 rollback_version));
1000 payload_state.LoadRollbackVersion();
1001 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
Chris Sosaaa18e162013-06-20 13:20:30 -07001002}
1003
David Zeuthenf413fe52013-04-22 14:04:39 -07001004TEST(PayloadStateTest, DurationsAreCorrect) {
1005 OmahaResponse response;
1006 PayloadState payload_state;
1007 MockSystemState mock_system_state;
1008 FakeClock fake_clock;
1009 Prefs prefs;
1010 string temp_dir;
1011
1012 // Set the clock to a well-known time - 1 second on the wall-clock
1013 // and 2 seconds on the monotonic clock
1014 fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
1015 fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
1016
1017 // We need persistent preferences for this test
1018 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateDurationTests.XXXXXX",
1019 &temp_dir));
1020 prefs.Init(FilePath(temp_dir));
1021
1022 mock_system_state.set_clock(&fake_clock);
1023 mock_system_state.set_prefs(&prefs);
1024 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1025
1026 // Check that durations are correct for a successful update where
1027 // time has advanced 7 seconds on the wall clock and 4 seconds on
1028 // the monotonic clock.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001029 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -07001030 fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
1031 fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
1032 payload_state.UpdateSucceeded();
1033 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
1034 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
1035
1036 // Check that durations are reset when a new response comes in.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001037 SetupPayloadStateWith2Urls("Hash8594", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -07001038 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
1039 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
1040
1041 // Advance time a bit (10 secs), simulate download progress and
1042 // check that durations are updated.
1043 fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
1044 fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
1045 payload_state.DownloadProgress(10);
1046 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
1047 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
1048
1049 // Now simulate a reboot by resetting monotonic time (to 5000) and
1050 // creating a new PayloadState object and check that we load the
1051 // durations correctly (e.g. they are the same as before).
1052 fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
1053 PayloadState payload_state2;
1054 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
1055 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
1056 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),10000000);
1057
1058 // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
1059 // and check that the durations are increased accordingly.
1060 fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
1061 fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
1062 payload_state2.UpdateSucceeded();
1063 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
1064 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),16000000);
1065
1066 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1067}
1068
David Zeuthene4c58bf2013-06-18 17:26:50 -07001069TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
1070 OmahaResponse response;
1071 PayloadState payload_state;
1072 MockSystemState mock_system_state;
1073 FakeClock fake_clock;
1074 Prefs prefs;
1075 string temp_dir;
1076
1077 // Set the clock to a well-known time (t = 30 seconds).
1078 fake_clock.SetWallclockTime(Time::FromInternalValue(
1079 30 * Time::kMicrosecondsPerSecond));
1080
1081 // We need persistent preferences for this test
1082 EXPECT_TRUE(utils::MakeTempDirectory(
1083 "/tmp/RebootAfterSuccessfulUpdateTest.XXXXXX", &temp_dir));
1084 prefs.Init(FilePath(temp_dir));
1085
1086 mock_system_state.set_clock(&fake_clock);
1087 mock_system_state.set_prefs(&prefs);
1088 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1089
1090 // Make the update succeed.
1091 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1092 payload_state.UpdateSucceeded();
1093
1094 // Check that the marker was written.
1095 EXPECT_TRUE(prefs.Exists(kPrefsSystemUpdatedMarker));
1096
1097 // Now simulate a reboot and set the wallclock time to a later point
1098 // (t = 500 seconds). We do this by using a new PayloadState object
1099 // and checking that it emits the right UMA metric with the right
1100 // value.
1101 fake_clock.SetWallclockTime(Time::FromInternalValue(
1102 500 * Time::kMicrosecondsPerSecond));
1103 PayloadState payload_state2;
1104 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
1105
1106 // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
1107 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1108 "Installer.TimeToRebootMinutes",
1109 7, _, _, _));
Alex Deymo569c4242013-07-24 12:01:01 -07001110 EXPECT_CALL(mock_system_state, system_rebooted())
1111 .WillRepeatedly(Return(true));
David Zeuthene4c58bf2013-06-18 17:26:50 -07001112
1113 payload_state2.UpdateEngineStarted();
1114
1115 // Check that the marker was nuked.
1116 EXPECT_FALSE(prefs.Exists(kPrefsSystemUpdatedMarker));
1117
1118 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1119}
1120
Alex Deymo569c4242013-07-24 12:01:01 -07001121TEST(PayloadStateTest, RestartAfterCrash) {
1122 PayloadState payload_state;
1123 MockSystemState mock_system_state;
1124 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
1125
1126 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1127
1128 // No prefs should be used after a crash.
1129 EXPECT_CALL(*prefs, Exists(_)).Times(0);
1130 EXPECT_CALL(*prefs, SetString(_, _)).Times(0);
1131 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(0);
1132 EXPECT_CALL(*prefs, SetBoolean(_, _)).Times(0);
1133 EXPECT_CALL(*prefs, GetString(_, _)).Times(0);
1134 EXPECT_CALL(*prefs, GetInt64(_, _)).Times(0);
1135 EXPECT_CALL(*prefs, GetBoolean(_, _)).Times(0);
1136
1137 // No metrics are reported after a crash.
1138 EXPECT_CALL(*mock_system_state.mock_metrics_lib(),
1139 SendToUMA(_, _, _, _, _)).Times(0);
1140
1141 // Simulate an update_engine restart without a reboot.
1142 EXPECT_CALL(mock_system_state, system_rebooted())
1143 .WillRepeatedly(Return(false));
1144
1145 payload_state.UpdateEngineStarted();
1146}
1147
Jay Srinivasan53173b92013-05-17 17:13:01 -07001148TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
1149 OmahaResponse response;
1150 MockSystemState mock_system_state;
1151 PayloadState payload_state;
1152
1153 // Pretend that this is an offical build so that the HTTP download policy
1154 // is honored.
1155 EXPECT_CALL(mock_system_state, IsOfficialBuild())
1156 .WillRepeatedly(Return(true));
1157
1158 policy::MockDevicePolicy disable_http_policy;
1159 EXPECT_CALL(mock_system_state, device_policy())
1160 .WillRepeatedly(Return(&disable_http_policy));
Chris Sosaf7d80042013-08-22 16:45:17 -07001161 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1162
1163 // Test with no device policy. Should default to allowing http.
1164 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1165 .WillRepeatedly(Return(false));
1166
1167 // Set the first response.
1168 SetupPayloadStateWith2Urls("Hash8433", true, &payload_state, &response);
1169
1170 // Check that we use the HTTP URL since there is no value set for allowing
1171 // http.
1172 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1173
1174 // Test with device policy not allowing http updates.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001175 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1176 .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
1177
Chris Sosaf7d80042013-08-22 16:45:17 -07001178 // Reset state and set again.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001179 SetupPayloadStateWith2Urls("Hash8433", false, &payload_state, &response);
1180
1181 // Check that we skip the HTTP URL and use only the HTTPS url.
1182 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1183
1184 // Advance the URL index to 1 by faking an error.
1185 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
1186 payload_state.UpdateFailed(error);
1187
1188 // Check that we still skip the HTTP URL and use only the HTTPS url.
1189 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1190 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
1191
1192 // Now, slightly change the response and set it again.
1193 SetupPayloadStateWith2Urls("Hash2399", false, &payload_state, &response);
1194
1195 // Check that we still skip the HTTP URL and use only the HTTPS url.
1196 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1197
1198 // Now, pretend that the HTTP policy is turned on. We want to make sure
1199 // the new policy is honored.
1200 policy::MockDevicePolicy enable_http_policy;
1201 EXPECT_CALL(mock_system_state, device_policy())
1202 .WillRepeatedly(Return(&enable_http_policy));
1203 EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
1204 .WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
1205
1206 // Now, set the same response using the same hash
1207 // so that we can test that the state is reset not because of the
1208 // hash but because of the policy change which results in candidate url
1209 // list change.
1210 SetupPayloadStateWith2Urls("Hash2399", true, &payload_state, &response);
1211
1212 // Check that we use the HTTP URL now and the failure count is reset.
1213 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1214 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1215
1216 // Fake a failure and see if we're moving over to the HTTPS url and update
1217 // the URL switch count properly.
1218 payload_state.UpdateFailed(error);
1219 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1220 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
1221 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1222}
1223
Alex Deymo1c656c42013-06-28 11:02:14 -07001224TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
1225 OmahaResponse response;
1226 response.is_delta_payload = true;
1227 PayloadState payload_state;
1228 MockSystemState mock_system_state;
1229
1230 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1231 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1232
1233 // Simulate a successful download and update.
1234 payload_state.DownloadComplete();
1235
1236 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1237 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
1238 payload_state.UpdateSucceeded();
1239
1240 // Mock the request to a request where the delta was disabled but Omaha sends
1241 // a delta anyway and test again.
1242 OmahaRequestParams params(&mock_system_state);
1243 params.set_delta_okay(false);
1244 mock_system_state.set_request_params(&params);
1245
1246 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1247 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1248
1249 payload_state.DownloadComplete();
1250
1251 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1252 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
1253 payload_state.UpdateSucceeded();
1254}
1255
1256TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
1257 OmahaResponse response;
1258 response.is_delta_payload = false;
1259 PayloadState payload_state;
1260 MockSystemState mock_system_state;
1261
1262 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1263 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1264
1265 // Mock the request to a request where the delta was disabled.
1266 OmahaRequestParams params(&mock_system_state);
1267 params.set_delta_okay(false);
1268 mock_system_state.set_request_params(&params);
1269
1270 // Simulate a successful download and update.
1271 payload_state.DownloadComplete();
1272
1273 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1274 "Installer.PayloadFormat", kPayloadTypeForcedFull, kNumPayloadTypes));
1275 payload_state.UpdateSucceeded();
1276}
1277
1278TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
1279 OmahaResponse response;
1280 response.is_delta_payload = false;
1281 PayloadState payload_state;
1282 MockSystemState mock_system_state;
1283
1284 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1285 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1286
Alex Deymo820cc702013-06-28 15:43:46 -07001287 // Mock the request to a request where the delta is enabled, although the
1288 // result is full.
Alex Deymo1c656c42013-06-28 11:02:14 -07001289 OmahaRequestParams params(&mock_system_state);
1290 params.set_delta_okay(true);
1291 mock_system_state.set_request_params(&params);
1292
1293 // Simulate a successful download and update.
1294 payload_state.DownloadComplete();
1295
1296 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1297 "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
1298 payload_state.UpdateSucceeded();
1299}
1300
Alex Deymo42432912013-07-12 20:21:15 -07001301TEST(PayloadStateTest, RebootAfterUpdateFailedMetric) {
1302 FakeHardware fake_hardware;
1303 MockSystemState mock_system_state;
1304 OmahaResponse response;
1305 PayloadState payload_state;
1306 Prefs prefs;
1307 string temp_dir;
1308
1309 // Setup an environment with persistent prefs across simulated reboots.
1310 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1311 &temp_dir));
1312 prefs.Init(FilePath(temp_dir));
1313 mock_system_state.set_prefs(&prefs);
1314
1315 fake_hardware.SetBootDevice("/dev/sda3");
1316 fake_hardware.SetKernelDeviceOfBootDevice("/dev/sda3", "/dev/sda2");
1317 mock_system_state.set_hardware(&fake_hardware);
1318
1319 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1320 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1321
1322 // Simulate a successful download and update.
1323 payload_state.DownloadComplete();
1324 payload_state.UpdateSucceeded();
1325 payload_state.ExpectRebootInNewVersion("Version:12345678");
1326
1327 // Reboot into the same environment to get an UMA metric with a value of 1.
1328 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1329 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
1330 payload_state.ReportFailedBootIfNeeded();
1331 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1332
1333 // Simulate a second update and reboot into the same environment, this should
1334 // send a value of 2.
1335 payload_state.ExpectRebootInNewVersion("Version:12345678");
1336
1337 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1338 "Installer.RebootToNewPartitionAttempt", 2, _, _, _));
1339 payload_state.ReportFailedBootIfNeeded();
1340 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1341
1342 // Simulate a third failed reboot to new version, but this time for a
1343 // different payload. This should send a value of 1 this time.
1344 payload_state.ExpectRebootInNewVersion("Version:3141592");
1345 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1346 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
1347 payload_state.ReportFailedBootIfNeeded();
1348 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1349
1350 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1351}
1352
1353TEST(PayloadStateTest, RebootAfterUpdateSucceed) {
1354 FakeHardware fake_hardware;
1355 MockSystemState mock_system_state;
1356 OmahaResponse response;
1357 PayloadState payload_state;
1358 Prefs prefs;
1359 string temp_dir;
1360
1361 // Setup an environment with persistent prefs across simulated reboots.
1362 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1363 &temp_dir));
1364 prefs.Init(FilePath(temp_dir));
1365 mock_system_state.set_prefs(&prefs);
1366
1367 fake_hardware.SetKernelDeviceOfBootDevice("/dev/sda3", "/dev/sda2");
1368 fake_hardware.SetKernelDeviceOfBootDevice("/dev/sda5", "/dev/sda4");
1369 fake_hardware.SetBootDevice("/dev/sda3");
1370 mock_system_state.set_hardware(&fake_hardware);
1371
1372 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1373 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1374
1375 // Simulate a successful download and update.
1376 payload_state.DownloadComplete();
1377 payload_state.UpdateSucceeded();
1378 payload_state.ExpectRebootInNewVersion("Version:12345678");
1379
1380 // Change the BootDevice to a different one, no metric should be sent.
1381 fake_hardware.SetBootDevice("/dev/sda5");
1382
1383 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1384 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1385 .Times(0);
1386 payload_state.ReportFailedBootIfNeeded();
1387
1388 // A second reboot in eiher partition should not send a metric.
1389 payload_state.ReportFailedBootIfNeeded();
1390 fake_hardware.SetBootDevice("/dev/sda3");
1391 payload_state.ReportFailedBootIfNeeded();
1392
1393 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1394}
1395
1396TEST(PayloadStateTest, RebootAfterCanceledUpdate) {
1397 MockSystemState mock_system_state;
1398 OmahaResponse response;
1399 PayloadState payload_state;
1400 Prefs prefs;
1401 string temp_dir;
1402
1403 // Setup an environment with persistent prefs across simulated reboots.
1404 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1405 &temp_dir));
1406 prefs.Init(FilePath(temp_dir));
1407 mock_system_state.set_prefs(&prefs);
1408
1409 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1410 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1411
1412 // Simulate a successful download and update.
1413 payload_state.DownloadComplete();
1414 payload_state.UpdateSucceeded();
1415 payload_state.ExpectRebootInNewVersion("Version:12345678");
1416
1417 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1418 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1419 .Times(0);
1420
1421 // Cancel the applied update.
1422 payload_state.ResetUpdateStatus();
1423
1424 // Simulate a reboot.
1425 payload_state.ReportFailedBootIfNeeded();
1426
1427 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1428}
1429
1430TEST(PayloadStateTest, UpdateSuccessWithWipedPrefs) {
1431 MockSystemState mock_system_state;
1432 PayloadState payload_state;
1433 Prefs prefs;
1434 string temp_dir;
1435
1436 // Setup an environment with persistent but initially empty prefs.
1437 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1438 &temp_dir));
1439 prefs.Init(FilePath(temp_dir));
1440 mock_system_state.set_prefs(&prefs);
1441
1442 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1443
1444 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1445 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1446 .Times(0);
1447
1448 // Simulate a reboot in this environment.
1449 payload_state.ReportFailedBootIfNeeded();
1450
1451 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1452}
1453
David Zeuthendcba8092013-08-06 12:16:35 -07001454TEST(PayloadStateTest, DisallowP2PAfterTooManyAttempts) {
1455 OmahaResponse response;
1456 PayloadState payload_state;
1457 MockSystemState mock_system_state;
1458 Prefs prefs;
1459 string temp_dir;
1460
1461 // We need persistent preferences for this test.
1462 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1463 &temp_dir));
1464 prefs.Init(FilePath(temp_dir));
1465
1466 mock_system_state.set_prefs(&prefs);
1467 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1468 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1469
1470 // Should allow exactly kMaxP2PAttempts...
1471 for (int n = 0; n < kMaxP2PAttempts; n++) {
1472 payload_state.P2PNewAttempt();
1473 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1474 }
1475 // ... but not more than that.
1476 payload_state.P2PNewAttempt();
1477 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1478
1479 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1480}
1481
1482TEST(PayloadStateTest, DisallowP2PAfterDeadline) {
1483 OmahaResponse response;
1484 PayloadState payload_state;
1485 MockSystemState mock_system_state;
1486 FakeClock fake_clock;
1487 Prefs prefs;
1488 string temp_dir;
1489
1490 // We need persistent preferences for this test.
1491 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1492 &temp_dir));
1493 prefs.Init(FilePath(temp_dir));
1494
1495 mock_system_state.set_clock(&fake_clock);
1496 mock_system_state.set_prefs(&prefs);
1497 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1498 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1499
1500 // Set the clock to 1 second.
1501 Time epoch = Time::FromInternalValue(1000000);
1502 fake_clock.SetWallclockTime(epoch);
1503
1504 // Do an attempt - this will set the timestamp.
1505 payload_state.P2PNewAttempt();
1506
1507 // Check that the timestamp equals what we just set.
1508 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1509
1510 // Time hasn't advanced - this should work.
1511 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1512
1513 // Set clock to half the deadline - this should work.
1514 fake_clock.SetWallclockTime(epoch +
1515 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds) / 2);
1516 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1517
1518 // Check that the first attempt timestamp hasn't changed just
1519 // because the wall-clock time changed.
1520 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1521
1522 // Set clock to _just_ before the deadline - this should work.
1523 fake_clock.SetWallclockTime(epoch +
1524 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds - 1));
1525 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1526
1527 // Set clock to _just_ after the deadline - this should not work.
1528 fake_clock.SetWallclockTime(epoch +
1529 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds + 1));
1530 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1531
1532 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1533}
1534
1535TEST(PayloadStateTest, P2PStateVarsInitialValue) {
1536 OmahaResponse response;
1537 PayloadState payload_state;
1538 MockSystemState mock_system_state;
1539 Prefs prefs;
1540 string temp_dir;
1541
1542 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1543 &temp_dir));
1544 prefs.Init(FilePath(temp_dir));
1545 mock_system_state.set_prefs(&prefs);
1546 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1547 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1548
1549 Time null_time = Time();
1550 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1551 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1552
1553 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1554}
1555
1556TEST(PayloadStateTest, P2PStateVarsArePersisted) {
1557 OmahaResponse response;
1558 PayloadState payload_state;
1559 MockSystemState mock_system_state;
1560 FakeClock fake_clock;
1561 Prefs prefs;
1562 string temp_dir;
1563
1564 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1565 &temp_dir));
1566 prefs.Init(FilePath(temp_dir));
1567 mock_system_state.set_clock(&fake_clock);
1568 mock_system_state.set_prefs(&prefs);
1569 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1570 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1571
1572 // Set the clock to something known.
1573 Time time = Time::FromInternalValue(12345);
1574 fake_clock.SetWallclockTime(time);
1575
1576 // New p2p attempt - as a side-effect this will update the p2p state vars.
1577 payload_state.P2PNewAttempt();
1578 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1579 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1580
1581 // Now create a new PayloadState and check that it loads the state
1582 // vars correctly.
1583 PayloadState payload_state2;
1584 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
1585 EXPECT_EQ(1, payload_state2.GetP2PNumAttempts());
1586 EXPECT_EQ(time, payload_state2.GetP2PFirstAttemptTimestamp());
1587
1588 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1589}
1590
1591TEST(PayloadStateTest, P2PStateVarsAreClearedOnNewResponse) {
1592 OmahaResponse response;
1593 PayloadState payload_state;
1594 MockSystemState mock_system_state;
1595 FakeClock fake_clock;
1596 Prefs prefs;
1597 string temp_dir;
1598
1599 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1600 &temp_dir));
1601 prefs.Init(FilePath(temp_dir));
1602 mock_system_state.set_clock(&fake_clock);
1603 mock_system_state.set_prefs(&prefs);
1604 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1605 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1606
1607 // Set the clock to something known.
1608 Time time = Time::FromInternalValue(12345);
1609 fake_clock.SetWallclockTime(time);
1610
1611 // New p2p attempt - as a side-effect this will update the p2p state vars.
1612 payload_state.P2PNewAttempt();
1613 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1614 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1615
1616 // Set a new response...
1617 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
1618
1619 // ... and check that it clears the P2P state vars.
1620 Time null_time = Time();
1621 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1622 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1623
1624 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1625}
1626
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001627}