blob: 613940ee38ed227310b0059cbf4ea1a8a3cd4f42 [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());
991}
992
David Zeuthenf413fe52013-04-22 14:04:39 -0700993TEST(PayloadStateTest, DurationsAreCorrect) {
994 OmahaResponse response;
995 PayloadState payload_state;
996 MockSystemState mock_system_state;
997 FakeClock fake_clock;
998 Prefs prefs;
999 string temp_dir;
1000
1001 // Set the clock to a well-known time - 1 second on the wall-clock
1002 // and 2 seconds on the monotonic clock
1003 fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
1004 fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
1005
1006 // We need persistent preferences for this test
1007 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateDurationTests.XXXXXX",
1008 &temp_dir));
1009 prefs.Init(FilePath(temp_dir));
1010
1011 mock_system_state.set_clock(&fake_clock);
1012 mock_system_state.set_prefs(&prefs);
1013 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1014
1015 // Check that durations are correct for a successful update where
1016 // time has advanced 7 seconds on the wall clock and 4 seconds on
1017 // the monotonic clock.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001018 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -07001019 fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
1020 fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
1021 payload_state.UpdateSucceeded();
1022 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
1023 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
1024
1025 // Check that durations are reset when a new response comes in.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001026 SetupPayloadStateWith2Urls("Hash8594", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -07001027 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
1028 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
1029
1030 // Advance time a bit (10 secs), simulate download progress and
1031 // check that durations are updated.
1032 fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
1033 fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
1034 payload_state.DownloadProgress(10);
1035 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
1036 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
1037
1038 // Now simulate a reboot by resetting monotonic time (to 5000) and
1039 // creating a new PayloadState object and check that we load the
1040 // durations correctly (e.g. they are the same as before).
1041 fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
1042 PayloadState payload_state2;
1043 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
1044 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
1045 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),10000000);
1046
1047 // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
1048 // and check that the durations are increased accordingly.
1049 fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
1050 fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
1051 payload_state2.UpdateSucceeded();
1052 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
1053 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),16000000);
1054
1055 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1056}
1057
David Zeuthene4c58bf2013-06-18 17:26:50 -07001058TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
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 (t = 30 seconds).
1067 fake_clock.SetWallclockTime(Time::FromInternalValue(
1068 30 * Time::kMicrosecondsPerSecond));
1069
1070 // We need persistent preferences for this test
1071 EXPECT_TRUE(utils::MakeTempDirectory(
1072 "/tmp/RebootAfterSuccessfulUpdateTest.XXXXXX", &temp_dir));
1073 prefs.Init(FilePath(temp_dir));
1074
1075 mock_system_state.set_clock(&fake_clock);
1076 mock_system_state.set_prefs(&prefs);
1077 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1078
1079 // Make the update succeed.
1080 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1081 payload_state.UpdateSucceeded();
1082
1083 // Check that the marker was written.
1084 EXPECT_TRUE(prefs.Exists(kPrefsSystemUpdatedMarker));
1085
1086 // Now simulate a reboot and set the wallclock time to a later point
1087 // (t = 500 seconds). We do this by using a new PayloadState object
1088 // and checking that it emits the right UMA metric with the right
1089 // value.
1090 fake_clock.SetWallclockTime(Time::FromInternalValue(
1091 500 * Time::kMicrosecondsPerSecond));
1092 PayloadState payload_state2;
1093 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
1094
1095 // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
1096 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1097 "Installer.TimeToRebootMinutes",
1098 7, _, _, _));
Alex Deymo569c4242013-07-24 12:01:01 -07001099 EXPECT_CALL(mock_system_state, system_rebooted())
1100 .WillRepeatedly(Return(true));
David Zeuthene4c58bf2013-06-18 17:26:50 -07001101
1102 payload_state2.UpdateEngineStarted();
1103
1104 // Check that the marker was nuked.
1105 EXPECT_FALSE(prefs.Exists(kPrefsSystemUpdatedMarker));
1106
1107 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1108}
1109
Alex Deymo569c4242013-07-24 12:01:01 -07001110TEST(PayloadStateTest, RestartAfterCrash) {
1111 PayloadState payload_state;
1112 MockSystemState mock_system_state;
1113 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
1114
1115 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1116
1117 // No prefs should be used after a crash.
1118 EXPECT_CALL(*prefs, Exists(_)).Times(0);
1119 EXPECT_CALL(*prefs, SetString(_, _)).Times(0);
1120 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(0);
1121 EXPECT_CALL(*prefs, SetBoolean(_, _)).Times(0);
1122 EXPECT_CALL(*prefs, GetString(_, _)).Times(0);
1123 EXPECT_CALL(*prefs, GetInt64(_, _)).Times(0);
1124 EXPECT_CALL(*prefs, GetBoolean(_, _)).Times(0);
1125
1126 // No metrics are reported after a crash.
1127 EXPECT_CALL(*mock_system_state.mock_metrics_lib(),
1128 SendToUMA(_, _, _, _, _)).Times(0);
1129
1130 // Simulate an update_engine restart without a reboot.
1131 EXPECT_CALL(mock_system_state, system_rebooted())
1132 .WillRepeatedly(Return(false));
1133
1134 payload_state.UpdateEngineStarted();
1135}
1136
Jay Srinivasan53173b92013-05-17 17:13:01 -07001137TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
1138 OmahaResponse response;
1139 MockSystemState mock_system_state;
1140 PayloadState payload_state;
1141
1142 // Pretend that this is an offical build so that the HTTP download policy
1143 // is honored.
1144 EXPECT_CALL(mock_system_state, IsOfficialBuild())
1145 .WillRepeatedly(Return(true));
1146
1147 policy::MockDevicePolicy disable_http_policy;
1148 EXPECT_CALL(mock_system_state, device_policy())
1149 .WillRepeatedly(Return(&disable_http_policy));
Chris Sosaf7d80042013-08-22 16:45:17 -07001150 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1151
1152 // Test with no device policy. Should default to allowing http.
1153 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1154 .WillRepeatedly(Return(false));
1155
1156 // Set the first response.
1157 SetupPayloadStateWith2Urls("Hash8433", true, &payload_state, &response);
1158
1159 // Check that we use the HTTP URL since there is no value set for allowing
1160 // http.
1161 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1162
1163 // Test with device policy not allowing http updates.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001164 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1165 .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
1166
Chris Sosaf7d80042013-08-22 16:45:17 -07001167 // Reset state and set again.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001168 SetupPayloadStateWith2Urls("Hash8433", false, &payload_state, &response);
1169
1170 // Check that we skip the HTTP URL and use only the HTTPS url.
1171 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1172
1173 // Advance the URL index to 1 by faking an error.
1174 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
1175 payload_state.UpdateFailed(error);
1176
1177 // Check that we still skip the HTTP URL and use only the HTTPS url.
1178 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1179 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
1180
1181 // Now, slightly change the response and set it again.
1182 SetupPayloadStateWith2Urls("Hash2399", false, &payload_state, &response);
1183
1184 // Check that we still skip the HTTP URL and use only the HTTPS url.
1185 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1186
1187 // Now, pretend that the HTTP policy is turned on. We want to make sure
1188 // the new policy is honored.
1189 policy::MockDevicePolicy enable_http_policy;
1190 EXPECT_CALL(mock_system_state, device_policy())
1191 .WillRepeatedly(Return(&enable_http_policy));
1192 EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
1193 .WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
1194
1195 // Now, set the same response using the same hash
1196 // so that we can test that the state is reset not because of the
1197 // hash but because of the policy change which results in candidate url
1198 // list change.
1199 SetupPayloadStateWith2Urls("Hash2399", true, &payload_state, &response);
1200
1201 // Check that we use the HTTP URL now and the failure count is reset.
1202 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1203 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1204
1205 // Fake a failure and see if we're moving over to the HTTPS url and update
1206 // the URL switch count properly.
1207 payload_state.UpdateFailed(error);
1208 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1209 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
1210 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1211}
1212
Alex Deymo1c656c42013-06-28 11:02:14 -07001213TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
1214 OmahaResponse response;
1215 response.is_delta_payload = true;
1216 PayloadState payload_state;
1217 MockSystemState mock_system_state;
1218
1219 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1220 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1221
1222 // Simulate a successful download and update.
1223 payload_state.DownloadComplete();
1224
1225 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1226 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
1227 payload_state.UpdateSucceeded();
1228
1229 // Mock the request to a request where the delta was disabled but Omaha sends
1230 // a delta anyway and test again.
1231 OmahaRequestParams params(&mock_system_state);
1232 params.set_delta_okay(false);
1233 mock_system_state.set_request_params(&params);
1234
1235 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1236 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1237
1238 payload_state.DownloadComplete();
1239
1240 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1241 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
1242 payload_state.UpdateSucceeded();
1243}
1244
1245TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
1246 OmahaResponse response;
1247 response.is_delta_payload = false;
1248 PayloadState payload_state;
1249 MockSystemState mock_system_state;
1250
1251 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1252 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1253
1254 // Mock the request to a request where the delta was disabled.
1255 OmahaRequestParams params(&mock_system_state);
1256 params.set_delta_okay(false);
1257 mock_system_state.set_request_params(&params);
1258
1259 // Simulate a successful download and update.
1260 payload_state.DownloadComplete();
1261
1262 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1263 "Installer.PayloadFormat", kPayloadTypeForcedFull, kNumPayloadTypes));
1264 payload_state.UpdateSucceeded();
1265}
1266
1267TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
1268 OmahaResponse response;
1269 response.is_delta_payload = false;
1270 PayloadState payload_state;
1271 MockSystemState mock_system_state;
1272
1273 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1274 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1275
Alex Deymo820cc702013-06-28 15:43:46 -07001276 // Mock the request to a request where the delta is enabled, although the
1277 // result is full.
Alex Deymo1c656c42013-06-28 11:02:14 -07001278 OmahaRequestParams params(&mock_system_state);
1279 params.set_delta_okay(true);
1280 mock_system_state.set_request_params(&params);
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", kPayloadTypeFull, kNumPayloadTypes));
1287 payload_state.UpdateSucceeded();
1288}
1289
Alex Deymo42432912013-07-12 20:21:15 -07001290TEST(PayloadStateTest, RebootAfterUpdateFailedMetric) {
1291 FakeHardware fake_hardware;
1292 MockSystemState mock_system_state;
1293 OmahaResponse response;
1294 PayloadState payload_state;
1295 Prefs prefs;
1296 string temp_dir;
1297
1298 // Setup an environment with persistent prefs across simulated reboots.
1299 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1300 &temp_dir));
1301 prefs.Init(FilePath(temp_dir));
1302 mock_system_state.set_prefs(&prefs);
1303
1304 fake_hardware.SetBootDevice("/dev/sda3");
1305 fake_hardware.SetKernelDeviceOfBootDevice("/dev/sda3", "/dev/sda2");
1306 mock_system_state.set_hardware(&fake_hardware);
1307
1308 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1309 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1310
1311 // Simulate a successful download and update.
1312 payload_state.DownloadComplete();
1313 payload_state.UpdateSucceeded();
1314 payload_state.ExpectRebootInNewVersion("Version:12345678");
1315
1316 // Reboot into the same environment to get an UMA metric with a value of 1.
1317 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1318 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
1319 payload_state.ReportFailedBootIfNeeded();
1320 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1321
1322 // Simulate a second update and reboot into the same environment, this should
1323 // send a value of 2.
1324 payload_state.ExpectRebootInNewVersion("Version:12345678");
1325
1326 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1327 "Installer.RebootToNewPartitionAttempt", 2, _, _, _));
1328 payload_state.ReportFailedBootIfNeeded();
1329 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1330
1331 // Simulate a third failed reboot to new version, but this time for a
1332 // different payload. This should send a value of 1 this time.
1333 payload_state.ExpectRebootInNewVersion("Version:3141592");
1334 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1335 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
1336 payload_state.ReportFailedBootIfNeeded();
1337 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1338
1339 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1340}
1341
1342TEST(PayloadStateTest, RebootAfterUpdateSucceed) {
1343 FakeHardware fake_hardware;
1344 MockSystemState mock_system_state;
1345 OmahaResponse response;
1346 PayloadState payload_state;
1347 Prefs prefs;
1348 string temp_dir;
1349
1350 // Setup an environment with persistent prefs across simulated reboots.
1351 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1352 &temp_dir));
1353 prefs.Init(FilePath(temp_dir));
1354 mock_system_state.set_prefs(&prefs);
1355
1356 fake_hardware.SetKernelDeviceOfBootDevice("/dev/sda3", "/dev/sda2");
1357 fake_hardware.SetKernelDeviceOfBootDevice("/dev/sda5", "/dev/sda4");
1358 fake_hardware.SetBootDevice("/dev/sda3");
1359 mock_system_state.set_hardware(&fake_hardware);
1360
1361 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1362 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1363
1364 // Simulate a successful download and update.
1365 payload_state.DownloadComplete();
1366 payload_state.UpdateSucceeded();
1367 payload_state.ExpectRebootInNewVersion("Version:12345678");
1368
1369 // Change the BootDevice to a different one, no metric should be sent.
1370 fake_hardware.SetBootDevice("/dev/sda5");
1371
1372 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1373 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1374 .Times(0);
1375 payload_state.ReportFailedBootIfNeeded();
1376
1377 // A second reboot in eiher partition should not send a metric.
1378 payload_state.ReportFailedBootIfNeeded();
1379 fake_hardware.SetBootDevice("/dev/sda3");
1380 payload_state.ReportFailedBootIfNeeded();
1381
1382 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1383}
1384
1385TEST(PayloadStateTest, RebootAfterCanceledUpdate) {
1386 MockSystemState mock_system_state;
1387 OmahaResponse response;
1388 PayloadState payload_state;
1389 Prefs prefs;
1390 string temp_dir;
1391
1392 // Setup an environment with persistent prefs across simulated reboots.
1393 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1394 &temp_dir));
1395 prefs.Init(FilePath(temp_dir));
1396 mock_system_state.set_prefs(&prefs);
1397
1398 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1399 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1400
1401 // Simulate a successful download and update.
1402 payload_state.DownloadComplete();
1403 payload_state.UpdateSucceeded();
1404 payload_state.ExpectRebootInNewVersion("Version:12345678");
1405
1406 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1407 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1408 .Times(0);
1409
1410 // Cancel the applied update.
1411 payload_state.ResetUpdateStatus();
1412
1413 // Simulate a reboot.
1414 payload_state.ReportFailedBootIfNeeded();
1415
1416 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1417}
1418
1419TEST(PayloadStateTest, UpdateSuccessWithWipedPrefs) {
1420 MockSystemState mock_system_state;
1421 PayloadState payload_state;
1422 Prefs prefs;
1423 string temp_dir;
1424
1425 // Setup an environment with persistent but initially empty prefs.
1426 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1427 &temp_dir));
1428 prefs.Init(FilePath(temp_dir));
1429 mock_system_state.set_prefs(&prefs);
1430
1431 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1432
1433 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1434 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1435 .Times(0);
1436
1437 // Simulate a reboot in this environment.
1438 payload_state.ReportFailedBootIfNeeded();
1439
1440 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1441}
1442
David Zeuthendcba8092013-08-06 12:16:35 -07001443TEST(PayloadStateTest, DisallowP2PAfterTooManyAttempts) {
1444 OmahaResponse response;
1445 PayloadState payload_state;
1446 MockSystemState mock_system_state;
1447 Prefs prefs;
1448 string temp_dir;
1449
1450 // We need persistent preferences for this test.
1451 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1452 &temp_dir));
1453 prefs.Init(FilePath(temp_dir));
1454
1455 mock_system_state.set_prefs(&prefs);
1456 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1457 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1458
1459 // Should allow exactly kMaxP2PAttempts...
1460 for (int n = 0; n < kMaxP2PAttempts; n++) {
1461 payload_state.P2PNewAttempt();
1462 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1463 }
1464 // ... but not more than that.
1465 payload_state.P2PNewAttempt();
1466 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1467
1468 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1469}
1470
1471TEST(PayloadStateTest, DisallowP2PAfterDeadline) {
1472 OmahaResponse response;
1473 PayloadState payload_state;
1474 MockSystemState mock_system_state;
1475 FakeClock fake_clock;
1476 Prefs prefs;
1477 string temp_dir;
1478
1479 // We need persistent preferences for this test.
1480 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1481 &temp_dir));
1482 prefs.Init(FilePath(temp_dir));
1483
1484 mock_system_state.set_clock(&fake_clock);
1485 mock_system_state.set_prefs(&prefs);
1486 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1487 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1488
1489 // Set the clock to 1 second.
1490 Time epoch = Time::FromInternalValue(1000000);
1491 fake_clock.SetWallclockTime(epoch);
1492
1493 // Do an attempt - this will set the timestamp.
1494 payload_state.P2PNewAttempt();
1495
1496 // Check that the timestamp equals what we just set.
1497 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1498
1499 // Time hasn't advanced - this should work.
1500 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1501
1502 // Set clock to half the deadline - this should work.
1503 fake_clock.SetWallclockTime(epoch +
1504 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds) / 2);
1505 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1506
1507 // Check that the first attempt timestamp hasn't changed just
1508 // because the wall-clock time changed.
1509 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1510
1511 // Set clock to _just_ before the deadline - this should work.
1512 fake_clock.SetWallclockTime(epoch +
1513 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds - 1));
1514 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1515
1516 // Set clock to _just_ after the deadline - this should not work.
1517 fake_clock.SetWallclockTime(epoch +
1518 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds + 1));
1519 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1520
1521 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1522}
1523
1524TEST(PayloadStateTest, P2PStateVarsInitialValue) {
1525 OmahaResponse response;
1526 PayloadState payload_state;
1527 MockSystemState mock_system_state;
1528 Prefs prefs;
1529 string temp_dir;
1530
1531 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1532 &temp_dir));
1533 prefs.Init(FilePath(temp_dir));
1534 mock_system_state.set_prefs(&prefs);
1535 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1536 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1537
1538 Time null_time = Time();
1539 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1540 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1541
1542 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1543}
1544
1545TEST(PayloadStateTest, P2PStateVarsArePersisted) {
1546 OmahaResponse response;
1547 PayloadState payload_state;
1548 MockSystemState mock_system_state;
1549 FakeClock fake_clock;
1550 Prefs prefs;
1551 string temp_dir;
1552
1553 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1554 &temp_dir));
1555 prefs.Init(FilePath(temp_dir));
1556 mock_system_state.set_clock(&fake_clock);
1557 mock_system_state.set_prefs(&prefs);
1558 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1559 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1560
1561 // Set the clock to something known.
1562 Time time = Time::FromInternalValue(12345);
1563 fake_clock.SetWallclockTime(time);
1564
1565 // New p2p attempt - as a side-effect this will update the p2p state vars.
1566 payload_state.P2PNewAttempt();
1567 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1568 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1569
1570 // Now create a new PayloadState and check that it loads the state
1571 // vars correctly.
1572 PayloadState payload_state2;
1573 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
1574 EXPECT_EQ(1, payload_state2.GetP2PNumAttempts());
1575 EXPECT_EQ(time, payload_state2.GetP2PFirstAttemptTimestamp());
1576
1577 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1578}
1579
1580TEST(PayloadStateTest, P2PStateVarsAreClearedOnNewResponse) {
1581 OmahaResponse response;
1582 PayloadState payload_state;
1583 MockSystemState mock_system_state;
1584 FakeClock fake_clock;
1585 Prefs prefs;
1586 string temp_dir;
1587
1588 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1589 &temp_dir));
1590 prefs.Init(FilePath(temp_dir));
1591 mock_system_state.set_clock(&fake_clock);
1592 mock_system_state.set_prefs(&prefs);
1593 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1594 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1595
1596 // Set the clock to something known.
1597 Time time = Time::FromInternalValue(12345);
1598 fake_clock.SetWallclockTime(time);
1599
1600 // New p2p attempt - as a side-effect this will update the p2p state vars.
1601 payload_state.P2PNewAttempt();
1602 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1603 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1604
1605 // Set a new response...
1606 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
1607
1608 // ... and check that it clears the P2P state vars.
1609 Time null_time = Time();
1610 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1611 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1612
1613 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1614}
1615
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001616}