blob: 77a8d020a088cccf349b2333a586b4d232013403 [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"
Jay Srinivasan19409b72013-04-12 19:23:36 -070015#include "update_engine/mock_system_state.h"
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080016#include "update_engine/omaha_request_action.h"
17#include "update_engine/payload_state.h"
David Zeuthenf413fe52013-04-22 14:04:39 -070018#include "update_engine/prefs.h"
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080019#include "update_engine/prefs_mock.h"
20#include "update_engine/test_utils.h"
21#include "update_engine/utils.h"
22
Jay Srinivasan08262882012-12-28 19:29:43 -080023using base::Time;
24using base::TimeDelta;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080025using std::string;
26using testing::_;
27using testing::NiceMock;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080028using testing::Return;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080029using testing::SetArgumentPointee;
David Zeuthen9a017f22013-04-11 16:10:26 -070030using testing::AtLeast;
Jay Srinivasandbd9ea22013-04-22 17:45:19 -070031using testing::AnyNumber;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080032
33namespace chromeos_update_engine {
34
Jay Srinivasan19409b72013-04-12 19:23:36 -070035const char* kCurrentBytesDownloadedFromHttps =
36 "current-bytes-downloaded-from-HttpsServer";
37const char* kTotalBytesDownloadedFromHttps =
38 "total-bytes-downloaded-from-HttpsServer";
39const char* kCurrentBytesDownloadedFromHttp =
40 "current-bytes-downloaded-from-HttpServer";
41const char* kTotalBytesDownloadedFromHttp =
42 "total-bytes-downloaded-from-HttpServer";
43
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080044static void SetupPayloadStateWith2Urls(string hash,
Jay Srinivasan53173b92013-05-17 17:13:01 -070045 bool http_enabled,
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080046 PayloadState* payload_state,
47 OmahaResponse* response) {
48 response->payload_urls.clear();
49 response->payload_urls.push_back("http://test");
50 response->payload_urls.push_back("https://test");
51 response->size = 523456789;
52 response->hash = hash;
53 response->metadata_size = 558123;
54 response->metadata_signature = "metasign";
55 response->max_failure_count_per_url = 3;
56 payload_state->SetResponse(*response);
Jay Srinivasan08262882012-12-28 19:29:43 -080057 string stored_response_sign = payload_state->GetResponseSignature();
Jay Srinivasan53173b92013-05-17 17:13:01 -070058
59 string expected_url_https_only =
60 "NumURLs = 1\n"
61 "Candidate Url0 = https://test\n";
62
63 string expected_urls_both =
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080064 "NumURLs = 2\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -070065 "Candidate Url0 = http://test\n"
66 "Candidate Url1 = https://test\n";
67
68 string expected_response_sign =
69 (http_enabled ? expected_urls_both : expected_url_https_only) +
70 StringPrintf("Payload Size = 523456789\n"
71 "Payload Sha256 Hash = %s\n"
72 "Metadata Size = 558123\n"
73 "Metadata Signature = metasign\n"
74 "Is Delta Payload = %d\n"
75 "Max Failure Count Per Url = %d\n"
76 "Disable Payload Backoff = %d\n",
77 hash.c_str(),
78 response->is_delta_payload,
79 response->max_failure_count_per_url,
80 response->disable_payload_backoff);
Jay Srinivasan08262882012-12-28 19:29:43 -080081 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080082}
83
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080084class PayloadStateTest : public ::testing::Test { };
85
David Zeuthena99981f2013-04-29 13:42:47 -070086TEST(PayloadStateTest, DidYouAddANewErrorCode) {
87 if (kErrorCodeUmaReportedMax != 43) {
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080088 LOG(ERROR) << "The following failure is intentional. If you added a new "
David Zeuthena99981f2013-04-29 13:42:47 -070089 << "ErrorCode enum value, make sure to add it to the "
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080090 << "PayloadState::UpdateFailed method and then update this test "
David Zeuthena99981f2013-04-29 13:42:47 -070091 << "to the new value of kErrorCodeUmaReportedMax, which is "
92 << kErrorCodeUmaReportedMax;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080093 EXPECT_FALSE("Please see the log line above");
94 }
95}
96
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080097TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
98 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -070099 MockSystemState mock_system_state;
100 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700101 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700102 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
103 .Times(AtLeast(1));
104 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
105 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
106 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
107 .Times(AtLeast(1));
108 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
109 .Times(AtLeast(1));
110 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
111 .Times(AtLeast(1));
112 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
113 .Times(AtLeast(1));
114 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
115 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700116 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800117 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700118 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800119 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800120 string stored_response_sign = payload_state.GetResponseSignature();
121 string expected_response_sign = "NumURLs = 0\n"
122 "Payload Size = 0\n"
123 "Payload Sha256 Hash = \n"
124 "Metadata Size = 0\n"
125 "Metadata Signature = \n"
126 "Is Delta Payload = 0\n"
127 "Max Failure Count Per Url = 0\n"
128 "Disable Payload Backoff = 0\n";
129 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700130 EXPECT_EQ("", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800131 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700132 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800133}
134
135TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
136 OmahaResponse response;
Jay Srinivasan53173b92013-05-17 17:13:01 -0700137 response.payload_urls.push_back("https://single.url.test");
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800138 response.size = 123456789;
139 response.hash = "hash";
140 response.metadata_size = 58123;
141 response.metadata_signature = "msign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700142 MockSystemState mock_system_state;
143 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700144 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700145 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
146 .Times(AtLeast(1));
147 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
148 .Times(AtLeast(1));
149 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
150 .Times(AtLeast(1));
151 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
152 .Times(AtLeast(1));
153 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
154 .Times(AtLeast(1));
155 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
156 .Times(AtLeast(1));
157 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
158 .Times(AtLeast(1));
159 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
160 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700161 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
162 .Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800163 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700164 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800165 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800166 string stored_response_sign = payload_state.GetResponseSignature();
167 string expected_response_sign = "NumURLs = 1\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -0700168 "Candidate Url0 = https://single.url.test\n"
Jay Srinivasan08262882012-12-28 19:29:43 -0800169 "Payload Size = 123456789\n"
170 "Payload Sha256 Hash = hash\n"
171 "Metadata Size = 58123\n"
172 "Metadata Signature = msign\n"
173 "Is Delta Payload = 0\n"
174 "Max Failure Count Per Url = 0\n"
175 "Disable Payload Backoff = 0\n";
176 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700177 EXPECT_EQ("https://single.url.test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800178 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700179 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800180}
181
182TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
183 OmahaResponse response;
184 response.payload_urls.push_back("http://multiple.url.test");
185 response.payload_urls.push_back("https://multiple.url.test");
186 response.size = 523456789;
187 response.hash = "rhash";
188 response.metadata_size = 558123;
189 response.metadata_signature = "metasign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700190 MockSystemState mock_system_state;
191 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700192 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700193 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
194 .Times(AtLeast(1));
195 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
196 .Times(AtLeast(1));
197 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
198 .Times(AtLeast(1));
199 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
200 .Times(AtLeast(1));
201 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
202 .Times(AtLeast(1));
203 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
204 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700205 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
206 .Times(AtLeast(1));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700207
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800208 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700209 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800210 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800211 string stored_response_sign = payload_state.GetResponseSignature();
212 string expected_response_sign = "NumURLs = 2\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -0700213 "Candidate Url0 = http://multiple.url.test\n"
214 "Candidate Url1 = https://multiple.url.test\n"
Jay Srinivasan08262882012-12-28 19:29:43 -0800215 "Payload Size = 523456789\n"
216 "Payload Sha256 Hash = rhash\n"
217 "Metadata Size = 558123\n"
218 "Metadata Signature = metasign\n"
219 "Is Delta Payload = 0\n"
220 "Max Failure Count Per Url = 0\n"
221 "Disable Payload Backoff = 0\n";
222 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700223 EXPECT_EQ("http://multiple.url.test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800224 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700225 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800226}
227
228TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
229 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700230 MockSystemState mock_system_state;
231 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800232 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800233
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700234 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800235 // Payload attempt should start with 0 and then advance to 1.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700236 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
237 .Times(AtLeast(1));
238 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
239 .Times(AtLeast(1));
240 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
David Zeuthen9a017f22013-04-11 16:10:26 -0700241
Chris Sosabe45bef2013-04-09 18:25:12 -0700242 // Reboots will be set
243 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1));
244
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800245 // Url index should go from 0 to 1 twice.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700246 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
247 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800248
249 // Failure count should be called each times url index is set, so that's
250 // 4 times for this test.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700251 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
252 .Times(AtLeast(4));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800253
Jay Srinivasan19409b72013-04-12 19:23:36 -0700254 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800255
256 // This does a SetResponse which causes all the states to be set to 0 for
257 // the first time.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700258 SetupPayloadStateWith2Urls("Hash1235", true, &payload_state, &response);
259 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800260
261 // Verify that on the first error, the URL index advances to 1.
David Zeuthena99981f2013-04-29 13:42:47 -0700262 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800263 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700264 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800265
266 // Verify that on the next error, the URL index wraps around to 0.
267 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700268 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800269
270 // Verify that on the next error, it again advances to 1.
271 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700272 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
David Zeuthencc6f9962013-04-18 11:57:24 -0700273
274 // Verify that we switched URLs three times
275 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800276}
277
278TEST(PayloadStateTest, NewResponseResetsPayloadState) {
279 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700280 MockSystemState mock_system_state;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800281 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800282
Jay Srinivasan19409b72013-04-12 19:23:36 -0700283 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800284
285 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700286 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800287
288 // Advance the URL index to 1 by faking an error.
David Zeuthena99981f2013-04-29 13:42:47 -0700289 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800290 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700291 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
David Zeuthencc6f9962013-04-18 11:57:24 -0700292 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800293
294 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700295 SetupPayloadStateWith2Urls("Hash8225", true, &payload_state, &response);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800296
297 // Make sure the url index was reset to 0 because of the new response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700298 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800299 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700300 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700301 EXPECT_EQ(0,
302 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
303 EXPECT_EQ(0,
304 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
305 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
306 kDownloadSourceHttpsServer));
307 EXPECT_EQ(0,
308 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800309}
310
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800311TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
312 OmahaResponse response;
313 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700314 MockSystemState mock_system_state;
315 int progress_bytes = 100;
316 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800317
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700318 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700319 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
320 .Times(AtLeast(2));
321 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
322 .Times(AtLeast(1));
323 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
324 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800325
Jay Srinivasan19409b72013-04-12 19:23:36 -0700326 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
Jay Srinivasan08262882012-12-28 19:29:43 -0800327
Jay Srinivasan19409b72013-04-12 19:23:36 -0700328 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
329 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800330
Jay Srinivasan19409b72013-04-12 19:23:36 -0700331 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
332 .Times(AtLeast(7));
333 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
334 .Times(AtLeast(2));
335 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
336 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800337
Jay Srinivasan19409b72013-04-12 19:23:36 -0700338 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
339 .Times(AtLeast(1));
340 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
341 .Times(AtLeast(1));
David Zeuthen9a017f22013-04-11 16:10:26 -0700342
Jay Srinivasan19409b72013-04-12 19:23:36 -0700343 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
344 .Times(AtLeast(1));
345 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
346 .Times(AtLeast(1));
347 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
348 .Times(AtLeast(1));
349 EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
350 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700351 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
352 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700353
354 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800355
Jay Srinivasan53173b92013-05-17 17:13:01 -0700356 SetupPayloadStateWith2Urls("Hash5873", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800357
358 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700359 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800360 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700361 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800362 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700363 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800364
365 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700366 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800367 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700368 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800369 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700370 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800371
372 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700373 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800374 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700375 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800376 EXPECT_EQ(2, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700377 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800378
379 // This should advance the URL index as we've reached the
380 // max failure count and reset the failure count for the new URL index.
381 // This should also wrap around the URL index and thus cause the payload
382 // attempt number to be incremented.
David Zeuthena99981f2013-04-29 13:42:47 -0700383 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800384 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700385 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800386 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700387 EXPECT_EQ(2, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800388 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800389
390 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700391 payload_state.UpdateFailed(kErrorCodePayloadHashMismatchError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800392 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700393 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800394 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700395 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800396 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800397
398 // This should advance the URL index and payload attempt number due to
399 // wrap-around of URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700400 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMissingError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800401 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700402 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800403 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700404 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800405 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800406
407 // This HTTP error code should only increase the failure count.
David Zeuthena99981f2013-04-29 13:42:47 -0700408 payload_state.UpdateFailed(static_cast<ErrorCode>(
409 kErrorCodeOmahaRequestHTTPResponseBase + 404));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800410 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700411 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800412 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700413 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800414 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800415
416 // And that failure count should be reset when we download some bytes
417 // afterwards.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700418 payload_state.DownloadProgress(progress_bytes);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800419 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700420 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800421 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700422 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800423 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800424
425 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700426 SetupPayloadStateWith2Urls("Hash8532", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800427
428 // Make sure the url index was reset to 0 because of the new response.
429 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700430 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800431 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700432 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800433 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800434}
435
436TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDownload) {
437 OmahaResponse response;
438 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700439 MockSystemState mock_system_state;
440 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800441
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700442 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700443 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
444 .Times(AtLeast(1));
445 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
446 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800447
Jay Srinivasan19409b72013-04-12 19:23:36 -0700448 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
449 .Times(AtLeast(2));
Jay Srinivasan08262882012-12-28 19:29:43 -0800450
Jay Srinivasan19409b72013-04-12 19:23:36 -0700451 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
452 .Times(AtLeast(1));
453 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
454 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800455
Jay Srinivasan19409b72013-04-12 19:23:36 -0700456 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800457
Jay Srinivasan53173b92013-05-17 17:13:01 -0700458 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800459
460 // This should just advance the payload attempt number;
461 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
462 payload_state.DownloadComplete();
463 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
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(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800467}
468
469TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
470 OmahaResponse response;
471 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700472 MockSystemState mock_system_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800473
Jay Srinivasan19409b72013-04-12 19:23:36 -0700474 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700475 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800476
477 // Generate enough events to advance URL index, failure count and
478 // payload attempt number all to 1.
479 payload_state.DownloadComplete();
David Zeuthena99981f2013-04-29 13:42:47 -0700480 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
481 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800482 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700483 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800484 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700485 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800486
487 // Now, simulate a corrupted url index on persisted store which gets
488 // loaded when update_engine restarts. Using a different prefs object
489 // so as to not bother accounting for the uninteresting calls above.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700490 MockSystemState mock_system_state2;
491 NiceMock<PrefsMock>* prefs2 = mock_system_state2.mock_prefs();
492 EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
493 EXPECT_CALL(*prefs2, GetInt64(_,_)).Times(AtLeast(1));
494 EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
495 .Times(AtLeast(1));
496 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
497 .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
498 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
499 .Times(AtLeast(1));
David Zeuthencc6f9962013-04-18 11:57:24 -0700500 EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _))
501 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800502
503 // Note: This will be a different payload object, but the response should
504 // have the same hash as before so as to not trivially reset because the
505 // response was different. We want to specifically test that even if the
506 // response is same, we should reset the state if we find it corrupted.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700507 EXPECT_TRUE(payload_state.Initialize(&mock_system_state2));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700508 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800509
510 // Make sure all counters get reset to 0 because of the corrupted URL index
511 // we supplied above.
512 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700513 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800514 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700515 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800516}
Jay Srinivasan08262882012-12-28 19:29:43 -0800517
518TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
519 OmahaResponse response;
520 response.is_delta_payload = true;
521 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700522 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800523
Jay Srinivasan19409b72013-04-12 19:23:36 -0700524 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700525 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800526
527 // Simulate a successful download and see that we're ready to download
528 // again without any backoff as this is a delta payload.
529 payload_state.DownloadComplete();
530 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
531 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
532
533 // Simulate two failures (enough to cause payload backoff) and check
534 // again that we're ready to re-download without any backoff as this is
535 // a delta payload.
David Zeuthena99981f2013-04-29 13:42:47 -0700536 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
537 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700538 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan08262882012-12-28 19:29:43 -0800539 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
540 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
541}
542
543static void CheckPayloadBackoffState(PayloadState* payload_state,
544 int expected_attempt_number,
545 TimeDelta expected_days) {
546 payload_state->DownloadComplete();
547 EXPECT_EQ(expected_attempt_number, payload_state->GetPayloadAttemptNumber());
548 EXPECT_TRUE(payload_state->ShouldBackoffDownload());
549 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
550 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
551 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
552 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
553 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
554 EXPECT_LT(expected_min_time.ToInternalValue(),
555 backoff_expiry_time.ToInternalValue());
556 EXPECT_GT(expected_max_time.ToInternalValue(),
557 backoff_expiry_time.ToInternalValue());
558}
559
560TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
561 OmahaResponse response;
562 response.is_delta_payload = false;
563 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700564 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800565
Jay Srinivasan19409b72013-04-12 19:23:36 -0700566 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700567 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800568
569 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
570 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
571 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
572 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
573 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
574 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
575 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
576 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
577 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
578 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
579}
580
581TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
582 OmahaResponse response;
583 response.disable_payload_backoff = true;
584 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700585 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800586
Jay Srinivasan19409b72013-04-12 19:23:36 -0700587 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700588 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800589
590 // Simulate a successful download and see that we are ready to download
591 // again without any backoff.
592 payload_state.DownloadComplete();
593 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
594 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
595
596 // Test again, this time by simulating two errors that would cause
597 // the payload attempt number to increment due to wrap around. And
598 // check that we are still ready to re-download without any backoff.
David Zeuthena99981f2013-04-29 13:42:47 -0700599 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
600 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan08262882012-12-28 19:29:43 -0800601 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
602 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
603}
604
Jay Srinivasan19409b72013-04-12 19:23:36 -0700605TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
606 OmahaResponse response;
607 response.disable_payload_backoff = true;
608 PayloadState payload_state;
609 MockSystemState mock_system_state;
610 int https_total = 0;
611 int http_total = 0;
612
613 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700614 SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
Jay Srinivasan19409b72013-04-12 19:23:36 -0700615
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700616 // Simulate a previous attempt with in order to set an initial non-zero value
617 // for the total bytes downloaded for HTTP.
618 int prev_chunk = 323456789;
619 http_total += prev_chunk;
620 payload_state.DownloadProgress(prev_chunk);
621
622 // Ensure that the initial values for HTTP reflect this attempt.
623 EXPECT_EQ(prev_chunk,
624 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
625 EXPECT_EQ(http_total,
626 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
627
628 // Change the response hash so as to simulate a new response which will
629 // reset the current bytes downloaded, but not the total bytes downloaded.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700630 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700631
632 // First, simulate successful download of a few bytes over HTTP.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700633 int first_chunk = 5000000;
634 http_total += first_chunk;
635 payload_state.DownloadProgress(first_chunk);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700636 // Test that first all progress is made on HTTP and none on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700637 EXPECT_EQ(first_chunk,
638 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
639 EXPECT_EQ(http_total,
640 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
641 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
642 kDownloadSourceHttpsServer));
643 EXPECT_EQ(https_total,
644 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
645
646 // Simulate an error that'll cause the url index to point to https.
David Zeuthena99981f2013-04-29 13:42:47 -0700647 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700648 payload_state.UpdateFailed(error);
649
Jay Srinivasan53173b92013-05-17 17:13:01 -0700650 // Test that no new progress is made on HTTP and new progress is on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700651 int second_chunk = 23456789;
652 https_total += second_chunk;
653 payload_state.DownloadProgress(second_chunk);
654 EXPECT_EQ(first_chunk,
655 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
656 EXPECT_EQ(http_total,
657 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
658 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
659 kDownloadSourceHttpsServer));
660 EXPECT_EQ(https_total,
661 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
662
663 // Simulate error to go back to http.
664 payload_state.UpdateFailed(error);
665 int third_chunk = 32345678;
666 int http_chunk = first_chunk + third_chunk;
667 http_total += third_chunk;
668 int https_chunk = second_chunk;
669 payload_state.DownloadProgress(third_chunk);
670
671 // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
672 EXPECT_EQ(http_chunk,
673 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700674 EXPECT_EQ(http_total,
Jay Srinivasan19409b72013-04-12 19:23:36 -0700675 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
676 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
677 kDownloadSourceHttpsServer));
678 EXPECT_EQ(https_total,
679 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
680
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700681 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
682 .Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700683 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
684 "Installer.SuccessfulMBsDownloadedFromHttpServer",
685 http_chunk / kNumBytesInOneMiB, _, _, _));
686 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
687 "Installer.TotalMBsDownloadedFromHttpServer",
688 http_total / kNumBytesInOneMiB, _, _, _));
689 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
690 "Installer.SuccessfulMBsDownloadedFromHttpsServer",
691 https_chunk / kNumBytesInOneMiB, _, _, _));
692 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
693 "Installer.TotalMBsDownloadedFromHttpsServer",
694 https_total / kNumBytesInOneMiB, _, _, _));
David Zeuthencc6f9962013-04-18 11:57:24 -0700695 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
696 "Installer.UpdateURLSwitches",
697 2, _, _, _));
David Zeuthen674c3182013-04-18 14:05:20 -0700698 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
699 "Installer.UpdateDurationMinutes",
700 _, _, _, _));
701 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
702 "Installer.UpdateDurationUptimeMinutes",
703 _, _, _, _));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700704 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
705 "Installer.DownloadSourcesUsed", 3, _, _, _));
706 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
707 "Installer.DownloadOverheadPercentage", 542, _, _, _));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700708
709 payload_state.UpdateSucceeded();
710
711 // Make sure the metrics are reset after a successful update.
712 EXPECT_EQ(0,
713 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
714 EXPECT_EQ(0,
715 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
716 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
717 kDownloadSourceHttpsServer));
718 EXPECT_EQ(0,
719 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
720}
721
722TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
723 OmahaResponse response;
724 MockSystemState mock_system_state;
725 PayloadState payload_state;
726
727 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
728
729 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700730 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
Jay Srinivasan19409b72013-04-12 19:23:36 -0700731
732 int num_bytes = 10000;
733 payload_state.DownloadProgress(num_bytes);
734 EXPECT_EQ(num_bytes,
735 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
736 EXPECT_EQ(num_bytes,
737 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
738 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
739 kDownloadSourceHttpsServer));
740 EXPECT_EQ(0,
741 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
742
743 payload_state.UpdateRestarted();
744 // Make sure the current bytes downloaded is reset, but not the total bytes.
745 EXPECT_EQ(0,
746 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
747 EXPECT_EQ(num_bytes,
748 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
749}
750
Chris Sosabe45bef2013-04-09 18:25:12 -0700751TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
752 MockSystemState mock_system_state;
753 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700754
Chris Sosabe45bef2013-04-09 18:25:12 -0700755 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
756 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
757 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
758
759 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
760
761 payload_state.UpdateRestarted();
762 EXPECT_EQ(0, payload_state.GetNumReboots());
763
764 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(true));
765 payload_state.UpdateResumed();
766 // Num reboots should be incremented because system rebooted detected.
767 EXPECT_EQ(1, payload_state.GetNumReboots());
768
769 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(false));
770 payload_state.UpdateResumed();
771 // Num reboots should now be 1 as reboot was not detected.
772 EXPECT_EQ(1, payload_state.GetNumReboots());
773
774 // Restart the update again to verify we set the num of reboots back to 0.
775 payload_state.UpdateRestarted();
776 EXPECT_EQ(0, payload_state.GetNumReboots());
777}
Jay Srinivasan19409b72013-04-12 19:23:36 -0700778
David Zeuthenf413fe52013-04-22 14:04:39 -0700779TEST(PayloadStateTest, DurationsAreCorrect) {
780 OmahaResponse response;
781 PayloadState payload_state;
782 MockSystemState mock_system_state;
783 FakeClock fake_clock;
784 Prefs prefs;
785 string temp_dir;
786
787 // Set the clock to a well-known time - 1 second on the wall-clock
788 // and 2 seconds on the monotonic clock
789 fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
790 fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
791
792 // We need persistent preferences for this test
793 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateDurationTests.XXXXXX",
794 &temp_dir));
795 prefs.Init(FilePath(temp_dir));
796
797 mock_system_state.set_clock(&fake_clock);
798 mock_system_state.set_prefs(&prefs);
799 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
800
801 // Check that durations are correct for a successful update where
802 // time has advanced 7 seconds on the wall clock and 4 seconds on
803 // the monotonic clock.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700804 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -0700805 fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
806 fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
807 payload_state.UpdateSucceeded();
808 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
809 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
810
811 // Check that durations are reset when a new response comes in.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700812 SetupPayloadStateWith2Urls("Hash8594", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -0700813 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
814 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
815
816 // Advance time a bit (10 secs), simulate download progress and
817 // check that durations are updated.
818 fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
819 fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
820 payload_state.DownloadProgress(10);
821 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
822 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
823
824 // Now simulate a reboot by resetting monotonic time (to 5000) and
825 // creating a new PayloadState object and check that we load the
826 // durations correctly (e.g. they are the same as before).
827 fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
828 PayloadState payload_state2;
829 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
830 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
831 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),10000000);
832
833 // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
834 // and check that the durations are increased accordingly.
835 fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
836 fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
837 payload_state2.UpdateSucceeded();
838 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
839 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),16000000);
840
841 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
842}
843
Jay Srinivasan53173b92013-05-17 17:13:01 -0700844TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
845 OmahaResponse response;
846 MockSystemState mock_system_state;
847 PayloadState payload_state;
848
849 // Pretend that this is an offical build so that the HTTP download policy
850 // is honored.
851 EXPECT_CALL(mock_system_state, IsOfficialBuild())
852 .WillRepeatedly(Return(true));
853
854 policy::MockDevicePolicy disable_http_policy;
855 EXPECT_CALL(mock_system_state, device_policy())
856 .WillRepeatedly(Return(&disable_http_policy));
857 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
858 .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
859
860 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
861
862 // Set the first response.
863 SetupPayloadStateWith2Urls("Hash8433", false, &payload_state, &response);
864
865 // Check that we skip the HTTP URL and use only the HTTPS url.
866 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
867
868 // Advance the URL index to 1 by faking an error.
869 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
870 payload_state.UpdateFailed(error);
871
872 // Check that we still skip the HTTP URL and use only the HTTPS url.
873 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
874 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
875
876 // Now, slightly change the response and set it again.
877 SetupPayloadStateWith2Urls("Hash2399", false, &payload_state, &response);
878
879 // Check that we still skip the HTTP URL and use only the HTTPS url.
880 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
881
882 // Now, pretend that the HTTP policy is turned on. We want to make sure
883 // the new policy is honored.
884 policy::MockDevicePolicy enable_http_policy;
885 EXPECT_CALL(mock_system_state, device_policy())
886 .WillRepeatedly(Return(&enable_http_policy));
887 EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
888 .WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
889
890 // Now, set the same response using the same hash
891 // so that we can test that the state is reset not because of the
892 // hash but because of the policy change which results in candidate url
893 // list change.
894 SetupPayloadStateWith2Urls("Hash2399", true, &payload_state, &response);
895
896 // Check that we use the HTTP URL now and the failure count is reset.
897 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
898 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
899
900 // Fake a failure and see if we're moving over to the HTTPS url and update
901 // the URL switch count properly.
902 payload_state.UpdateFailed(error);
903 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
904 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
905 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
906}
907
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800908}