blob: f7665aed3d3a62dcb024f9cc2ca05f7c2b61802f [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));
Alex Deymo820cc702013-06-28 15:43:46 -0700104 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
105 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700106 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
107 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
108 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
109 .Times(AtLeast(1));
110 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
111 .Times(AtLeast(1));
112 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
113 .Times(AtLeast(1));
114 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
115 .Times(AtLeast(1));
116 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
117 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700118 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800119 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700120 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800121 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800122 string stored_response_sign = payload_state.GetResponseSignature();
123 string expected_response_sign = "NumURLs = 0\n"
124 "Payload Size = 0\n"
125 "Payload Sha256 Hash = \n"
126 "Metadata Size = 0\n"
127 "Metadata Signature = \n"
128 "Is Delta Payload = 0\n"
129 "Max Failure Count Per Url = 0\n"
130 "Disable Payload Backoff = 0\n";
131 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700132 EXPECT_EQ("", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800133 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700134 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700135 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800136}
137
138TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
139 OmahaResponse response;
Jay Srinivasan53173b92013-05-17 17:13:01 -0700140 response.payload_urls.push_back("https://single.url.test");
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800141 response.size = 123456789;
142 response.hash = "hash";
143 response.metadata_size = 58123;
144 response.metadata_signature = "msign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700145 MockSystemState mock_system_state;
146 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700147 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700148 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
149 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700150 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
151 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700152 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
153 .Times(AtLeast(1));
154 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
155 .Times(AtLeast(1));
156 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
157 .Times(AtLeast(1));
158 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
159 .Times(AtLeast(1));
160 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
161 .Times(AtLeast(1));
162 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
163 .Times(AtLeast(1));
164 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
165 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700166 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
167 .Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800168 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700169 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800170 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800171 string stored_response_sign = payload_state.GetResponseSignature();
172 string expected_response_sign = "NumURLs = 1\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -0700173 "Candidate Url0 = https://single.url.test\n"
Jay Srinivasan08262882012-12-28 19:29:43 -0800174 "Payload Size = 123456789\n"
175 "Payload Sha256 Hash = hash\n"
176 "Metadata Size = 58123\n"
177 "Metadata Signature = msign\n"
178 "Is Delta Payload = 0\n"
179 "Max Failure Count Per Url = 0\n"
180 "Disable Payload Backoff = 0\n";
181 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700182 EXPECT_EQ("https://single.url.test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800183 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700184 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700185 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800186}
187
188TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
189 OmahaResponse response;
190 response.payload_urls.push_back("http://multiple.url.test");
191 response.payload_urls.push_back("https://multiple.url.test");
192 response.size = 523456789;
193 response.hash = "rhash";
194 response.metadata_size = 558123;
195 response.metadata_signature = "metasign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700196 MockSystemState mock_system_state;
197 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700198 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700199 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
200 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700201 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
202 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700203 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
204 .Times(AtLeast(1));
205 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
206 .Times(AtLeast(1));
207 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
208 .Times(AtLeast(1));
209 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
210 .Times(AtLeast(1));
211 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
212 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700213 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
214 .Times(AtLeast(1));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700215
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800216 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700217 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800218 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800219 string stored_response_sign = payload_state.GetResponseSignature();
220 string expected_response_sign = "NumURLs = 2\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -0700221 "Candidate Url0 = http://multiple.url.test\n"
222 "Candidate Url1 = https://multiple.url.test\n"
Jay Srinivasan08262882012-12-28 19:29:43 -0800223 "Payload Size = 523456789\n"
224 "Payload Sha256 Hash = rhash\n"
225 "Metadata Size = 558123\n"
226 "Metadata Signature = metasign\n"
227 "Is Delta Payload = 0\n"
228 "Max Failure Count Per Url = 0\n"
229 "Disable Payload Backoff = 0\n";
230 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700231 EXPECT_EQ("http://multiple.url.test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800232 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700233 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700234 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800235}
236
237TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
238 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700239 MockSystemState mock_system_state;
240 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800241 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800242
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700243 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800244 // Payload attempt should start with 0 and then advance to 1.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700245 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
246 .Times(AtLeast(1));
247 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
248 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700249 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
250 .Times(AtLeast(1));
251 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
252 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700253 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
David Zeuthen9a017f22013-04-11 16:10:26 -0700254
Chris Sosabe45bef2013-04-09 18:25:12 -0700255 // Reboots will be set
256 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1));
257
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800258 // Url index should go from 0 to 1 twice.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700259 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
260 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800261
262 // Failure count should be called each times url index is set, so that's
263 // 4 times for this test.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700264 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
265 .Times(AtLeast(4));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800266
Jay Srinivasan19409b72013-04-12 19:23:36 -0700267 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800268
269 // This does a SetResponse which causes all the states to be set to 0 for
270 // the first time.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700271 SetupPayloadStateWith2Urls("Hash1235", true, &payload_state, &response);
272 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800273
274 // Verify that on the first error, the URL index advances to 1.
David Zeuthena99981f2013-04-29 13:42:47 -0700275 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800276 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700277 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800278
279 // Verify that on the next error, the URL index wraps around to 0.
280 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700281 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800282
283 // Verify that on the next error, it again advances to 1.
284 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700285 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
David Zeuthencc6f9962013-04-18 11:57:24 -0700286
287 // Verify that we switched URLs three times
288 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800289}
290
291TEST(PayloadStateTest, NewResponseResetsPayloadState) {
292 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700293 MockSystemState mock_system_state;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800294 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800295
Jay Srinivasan19409b72013-04-12 19:23:36 -0700296 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800297
298 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700299 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700300 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800301
302 // Advance the URL index to 1 by faking an error.
David Zeuthena99981f2013-04-29 13:42:47 -0700303 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800304 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700305 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
David Zeuthencc6f9962013-04-18 11:57:24 -0700306 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800307
308 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700309 SetupPayloadStateWith2Urls("Hash8225", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700310 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800311
312 // Make sure the url index was reset to 0 because of the new response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700313 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800314 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700315 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700316 EXPECT_EQ(0,
317 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
318 EXPECT_EQ(0,
319 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
320 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
321 kDownloadSourceHttpsServer));
322 EXPECT_EQ(0,
323 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800324}
325
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800326TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
327 OmahaResponse response;
328 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700329 MockSystemState mock_system_state;
330 int progress_bytes = 100;
331 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800332
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700333 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700334 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
335 .Times(AtLeast(2));
336 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
337 .Times(AtLeast(1));
338 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
339 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800340
Alex Deymo820cc702013-06-28 15:43:46 -0700341 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
342 .Times(AtLeast(2));
343 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
344 .Times(AtLeast(1));
345 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 2))
346 .Times(AtLeast(1));
347
Jay Srinivasan19409b72013-04-12 19:23:36 -0700348 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
Jay Srinivasan08262882012-12-28 19:29:43 -0800349
Jay Srinivasan19409b72013-04-12 19:23:36 -0700350 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
351 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800352
Jay Srinivasan19409b72013-04-12 19:23:36 -0700353 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
354 .Times(AtLeast(7));
355 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
356 .Times(AtLeast(2));
357 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
358 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800359
Jay Srinivasan19409b72013-04-12 19:23:36 -0700360 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
361 .Times(AtLeast(1));
362 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
363 .Times(AtLeast(1));
David Zeuthen9a017f22013-04-11 16:10:26 -0700364
Jay Srinivasan19409b72013-04-12 19:23:36 -0700365 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
366 .Times(AtLeast(1));
367 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
368 .Times(AtLeast(1));
369 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
370 .Times(AtLeast(1));
371 EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
372 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700373 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
374 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700375
376 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800377
Jay Srinivasan53173b92013-05-17 17:13:01 -0700378 SetupPayloadStateWith2Urls("Hash5873", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700379 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800380
381 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700382 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800383 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700384 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700385 EXPECT_EQ("https://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(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800388
389 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700390 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800391 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700392 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
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(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700395 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800396
397 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700398 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800399 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700400 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700401 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800402 EXPECT_EQ(2, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700403 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800404
405 // This should advance the URL index as we've reached the
406 // max failure count and reset the failure count for the new URL index.
407 // This should also wrap around the URL index and thus cause the payload
408 // attempt number to be incremented.
David Zeuthena99981f2013-04-29 13:42:47 -0700409 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800410 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700411 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700412 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800413 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700414 EXPECT_EQ(2, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800415 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800416
417 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700418 payload_state.UpdateFailed(kErrorCodePayloadHashMismatchError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800419 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700420 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700421 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800422 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700423 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800424 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800425
426 // This should advance the URL index and payload attempt number due to
427 // wrap-around of URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700428 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMissingError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800429 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700430 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700431 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800432 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700433 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800434 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800435
436 // This HTTP error code should only increase the failure count.
David Zeuthena99981f2013-04-29 13:42:47 -0700437 payload_state.UpdateFailed(static_cast<ErrorCode>(
438 kErrorCodeOmahaRequestHTTPResponseBase + 404));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800439 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700440 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700441 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800442 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700443 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800444 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800445
446 // And that failure count should be reset when we download some bytes
447 // afterwards.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700448 payload_state.DownloadProgress(progress_bytes);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800449 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700450 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700451 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800452 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700453 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800454 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800455
456 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700457 SetupPayloadStateWith2Urls("Hash8532", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700458 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800459
460 // Make sure the url index was reset to 0 because of the new response.
461 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700462 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700463 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800464 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700465 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800466 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800467}
468
Alex Deymo820cc702013-06-28 15:43:46 -0700469TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulFullDownload) {
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800470 OmahaResponse response;
Alex Deymo820cc702013-06-28 15:43:46 -0700471 response.is_delta_payload = false;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800472 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700473 MockSystemState mock_system_state;
474 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800475
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700476 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700477 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
478 .Times(AtLeast(1));
479 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
480 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800481
Alex Deymo820cc702013-06-28 15:43:46 -0700482 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
483 .Times(AtLeast(1));
484 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
485 .Times(AtLeast(1));
486
Jay Srinivasan19409b72013-04-12 19:23:36 -0700487 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
488 .Times(AtLeast(2));
Jay Srinivasan08262882012-12-28 19:29:43 -0800489
Jay Srinivasan19409b72013-04-12 19:23:36 -0700490 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
491 .Times(AtLeast(1));
492 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
493 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800494
Jay Srinivasan19409b72013-04-12 19:23:36 -0700495 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800496
Jay Srinivasan53173b92013-05-17 17:13:01 -0700497 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800498
Alex Deymo29b51d92013-07-09 15:26:24 -0700499 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
500 "Installer.PayloadAttemptNumber", 1, _, _, _));
501 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
502 "Installer.FullPayloadAttemptNumber", 1, _, _, _));
503
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800504 // This should just advance the payload attempt number;
505 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700506 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800507 payload_state.DownloadComplete();
508 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700509 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
510 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
511 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
512 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
513}
514
515TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDeltaDownload) {
516 OmahaResponse response;
517 response.is_delta_payload = true;
518 PayloadState payload_state;
519 MockSystemState mock_system_state;
520 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
521
522 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
523 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
524 .Times(AtLeast(1));
525 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
526 .Times(AtLeast(1));
527
528 // kPrefsFullPayloadAttemptNumber is not incremented for delta payloads.
529 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
530 .Times(AtLeast(1));
531
532 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
533 .Times(1);
534
535 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
536 .Times(AtLeast(1));
537 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
538 .Times(AtLeast(1));
539
540 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
541
542 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
543
Alex Deymo29b51d92013-07-09 15:26:24 -0700544 // Metrics for Full payload attempt number is not sent with Delta payloads.
545 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
546 "Installer.PayloadAttemptNumber", 1, _, _, _));
547 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
548 "Installer.FullPayloadAttemptNumber", _, _, _, _))
549 .Times(0);
550
Alex Deymo820cc702013-06-28 15:43:46 -0700551 // This should just advance the payload attempt number;
552 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
553 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
554 payload_state.DownloadComplete();
555 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
556 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700557 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800558 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700559 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800560}
561
562TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
563 OmahaResponse response;
564 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700565 MockSystemState mock_system_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800566
Jay Srinivasan19409b72013-04-12 19:23:36 -0700567 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700568 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800569
570 // Generate enough events to advance URL index, failure count and
571 // payload attempt number all to 1.
572 payload_state.DownloadComplete();
David Zeuthena99981f2013-04-29 13:42:47 -0700573 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
574 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800575 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700576 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700577 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800578 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700579 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800580
581 // Now, simulate a corrupted url index on persisted store which gets
582 // loaded when update_engine restarts. Using a different prefs object
583 // so as to not bother accounting for the uninteresting calls above.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700584 MockSystemState mock_system_state2;
585 NiceMock<PrefsMock>* prefs2 = mock_system_state2.mock_prefs();
586 EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
587 EXPECT_CALL(*prefs2, GetInt64(_,_)).Times(AtLeast(1));
588 EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
589 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700590 EXPECT_CALL(*prefs2, GetInt64(kPrefsFullPayloadAttemptNumber, _))
591 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700592 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
593 .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
594 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
595 .Times(AtLeast(1));
David Zeuthencc6f9962013-04-18 11:57:24 -0700596 EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _))
597 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800598
599 // Note: This will be a different payload object, but the response should
600 // have the same hash as before so as to not trivially reset because the
601 // response was different. We want to specifically test that even if the
602 // response is same, we should reset the state if we find it corrupted.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700603 EXPECT_TRUE(payload_state.Initialize(&mock_system_state2));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700604 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800605
606 // Make sure all counters get reset to 0 because of the corrupted URL index
607 // we supplied above.
608 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700609 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700610 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800611 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700612 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800613}
Jay Srinivasan08262882012-12-28 19:29:43 -0800614
615TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
616 OmahaResponse response;
617 response.is_delta_payload = true;
618 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700619 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800620
Jay Srinivasan19409b72013-04-12 19:23:36 -0700621 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700622 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800623
624 // Simulate a successful download and see that we're ready to download
625 // again without any backoff as this is a delta payload.
626 payload_state.DownloadComplete();
Alex Deymo820cc702013-06-28 15:43:46 -0700627 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
628 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800629 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
630
631 // Simulate two failures (enough to cause payload backoff) and check
632 // again that we're ready to re-download without any backoff as this is
633 // a delta payload.
David Zeuthena99981f2013-04-29 13:42:47 -0700634 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
635 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700636 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Alex Deymo820cc702013-06-28 15:43:46 -0700637 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
638 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800639 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
640}
641
642static void CheckPayloadBackoffState(PayloadState* payload_state,
643 int expected_attempt_number,
644 TimeDelta expected_days) {
645 payload_state->DownloadComplete();
Alex Deymo820cc702013-06-28 15:43:46 -0700646 EXPECT_EQ(expected_attempt_number,
647 payload_state->GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800648 EXPECT_TRUE(payload_state->ShouldBackoffDownload());
649 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
650 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
651 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
652 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
653 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
654 EXPECT_LT(expected_min_time.ToInternalValue(),
655 backoff_expiry_time.ToInternalValue());
656 EXPECT_GT(expected_max_time.ToInternalValue(),
657 backoff_expiry_time.ToInternalValue());
658}
659
660TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
661 OmahaResponse response;
662 response.is_delta_payload = false;
663 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700664 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800665
Jay Srinivasan19409b72013-04-12 19:23:36 -0700666 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700667 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800668
669 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
670 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
671 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
672 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
673 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
674 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
675 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
676 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
677 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
678 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
679}
680
681TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
682 OmahaResponse response;
683 response.disable_payload_backoff = true;
684 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700685 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800686
Jay Srinivasan19409b72013-04-12 19:23:36 -0700687 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700688 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800689
690 // Simulate a successful download and see that we are ready to download
691 // again without any backoff.
692 payload_state.DownloadComplete();
693 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700694 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800695 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
696
697 // Test again, this time by simulating two errors that would cause
698 // the payload attempt number to increment due to wrap around. And
699 // check that we are still ready to re-download without any backoff.
David Zeuthena99981f2013-04-29 13:42:47 -0700700 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
701 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan08262882012-12-28 19:29:43 -0800702 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700703 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800704 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
705}
706
Jay Srinivasan19409b72013-04-12 19:23:36 -0700707TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
708 OmahaResponse response;
709 response.disable_payload_backoff = true;
710 PayloadState payload_state;
711 MockSystemState mock_system_state;
712 int https_total = 0;
713 int http_total = 0;
714
715 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700716 SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700717 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700718
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700719 // Simulate a previous attempt with in order to set an initial non-zero value
720 // for the total bytes downloaded for HTTP.
721 int prev_chunk = 323456789;
722 http_total += prev_chunk;
723 payload_state.DownloadProgress(prev_chunk);
724
725 // Ensure that the initial values for HTTP reflect this attempt.
726 EXPECT_EQ(prev_chunk,
727 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
728 EXPECT_EQ(http_total,
729 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
730
731 // Change the response hash so as to simulate a new response which will
732 // reset the current bytes downloaded, but not the total bytes downloaded.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700733 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700734 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700735
736 // First, simulate successful download of a few bytes over HTTP.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700737 int first_chunk = 5000000;
738 http_total += first_chunk;
739 payload_state.DownloadProgress(first_chunk);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700740 // Test that first all progress is made on HTTP and none on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700741 EXPECT_EQ(first_chunk,
742 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
743 EXPECT_EQ(http_total,
744 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
745 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
746 kDownloadSourceHttpsServer));
747 EXPECT_EQ(https_total,
748 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
749
750 // Simulate an error that'll cause the url index to point to https.
David Zeuthena99981f2013-04-29 13:42:47 -0700751 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700752 payload_state.UpdateFailed(error);
753
Jay Srinivasan53173b92013-05-17 17:13:01 -0700754 // Test that no new progress is made on HTTP and new progress is on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700755 int second_chunk = 23456789;
756 https_total += second_chunk;
757 payload_state.DownloadProgress(second_chunk);
758 EXPECT_EQ(first_chunk,
759 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
760 EXPECT_EQ(http_total,
761 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
762 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
763 kDownloadSourceHttpsServer));
764 EXPECT_EQ(https_total,
765 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
766
767 // Simulate error to go back to http.
768 payload_state.UpdateFailed(error);
769 int third_chunk = 32345678;
770 int http_chunk = first_chunk + third_chunk;
771 http_total += third_chunk;
772 int https_chunk = second_chunk;
773 payload_state.DownloadProgress(third_chunk);
774
775 // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
776 EXPECT_EQ(http_chunk,
777 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700778 EXPECT_EQ(http_total,
Jay Srinivasan19409b72013-04-12 19:23:36 -0700779 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
780 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
781 kDownloadSourceHttpsServer));
782 EXPECT_EQ(https_total,
783 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
784
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700785 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
786 .Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700787 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
788 "Installer.SuccessfulMBsDownloadedFromHttpServer",
789 http_chunk / kNumBytesInOneMiB, _, _, _));
790 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
791 "Installer.TotalMBsDownloadedFromHttpServer",
792 http_total / kNumBytesInOneMiB, _, _, _));
793 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
794 "Installer.SuccessfulMBsDownloadedFromHttpsServer",
795 https_chunk / kNumBytesInOneMiB, _, _, _));
796 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
797 "Installer.TotalMBsDownloadedFromHttpsServer",
798 https_total / kNumBytesInOneMiB, _, _, _));
David Zeuthencc6f9962013-04-18 11:57:24 -0700799 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
800 "Installer.UpdateURLSwitches",
801 2, _, _, _));
David Zeuthen674c3182013-04-18 14:05:20 -0700802 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
803 "Installer.UpdateDurationMinutes",
804 _, _, _, _));
805 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
806 "Installer.UpdateDurationUptimeMinutes",
807 _, _, _, _));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700808 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
809 "Installer.DownloadSourcesUsed", 3, _, _, _));
810 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
811 "Installer.DownloadOverheadPercentage", 542, _, _, _));
Alex Deymo1c656c42013-06-28 11:02:14 -0700812 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
813 "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
Alex Deymo820cc702013-06-28 15:43:46 -0700814 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
815 "Installer.AttemptsCount.Total", 1, _, _, _));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700816
817 payload_state.UpdateSucceeded();
818
819 // Make sure the metrics are reset after a successful update.
820 EXPECT_EQ(0,
821 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
822 EXPECT_EQ(0,
823 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
824 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
825 kDownloadSourceHttpsServer));
826 EXPECT_EQ(0,
827 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
David Zeuthena573d6f2013-06-14 16:13:36 -0700828 EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700829}
830
831TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
832 OmahaResponse response;
833 MockSystemState mock_system_state;
834 PayloadState payload_state;
835
836 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
837
838 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700839 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
Jay Srinivasan19409b72013-04-12 19:23:36 -0700840
841 int num_bytes = 10000;
842 payload_state.DownloadProgress(num_bytes);
843 EXPECT_EQ(num_bytes,
844 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
845 EXPECT_EQ(num_bytes,
846 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
847 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
848 kDownloadSourceHttpsServer));
849 EXPECT_EQ(0,
850 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
851
852 payload_state.UpdateRestarted();
853 // Make sure the current bytes downloaded is reset, but not the total bytes.
854 EXPECT_EQ(0,
855 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
856 EXPECT_EQ(num_bytes,
857 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
858}
859
Chris Sosabe45bef2013-04-09 18:25:12 -0700860TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
861 MockSystemState mock_system_state;
862 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700863
Chris Sosabe45bef2013-04-09 18:25:12 -0700864 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
865 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
866 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
867
868 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
869
870 payload_state.UpdateRestarted();
871 EXPECT_EQ(0, payload_state.GetNumReboots());
872
873 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(true));
874 payload_state.UpdateResumed();
875 // Num reboots should be incremented because system rebooted detected.
876 EXPECT_EQ(1, payload_state.GetNumReboots());
877
878 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(false));
879 payload_state.UpdateResumed();
880 // Num reboots should now be 1 as reboot was not detected.
881 EXPECT_EQ(1, payload_state.GetNumReboots());
882
883 // Restart the update again to verify we set the num of reboots back to 0.
884 payload_state.UpdateRestarted();
885 EXPECT_EQ(0, payload_state.GetNumReboots());
886}
Jay Srinivasan19409b72013-04-12 19:23:36 -0700887
Chris Sosaaa18e162013-06-20 13:20:30 -0700888TEST(PayloadStateTest, RollbackVersion) {
889 MockSystemState mock_system_state;
890 PayloadState payload_state;
891
892 NiceMock<PrefsMock>* mock_powerwash_safe_prefs =
893 mock_system_state.mock_powerwash_safe_prefs();
894 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
895
896 // Verify pre-conditions are good.
897 EXPECT_TRUE(payload_state.GetRollbackVersion().empty());
898
899 // Mock out the os version and make sure it's blacklisted correctly.
900 string rollback_version = "2345.0.0";
901 OmahaRequestParams params(&mock_system_state);
902 params.Init(rollback_version, "", false);
903 mock_system_state.set_request_params(&params);
904
905 EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion,
906 rollback_version));
907 payload_state.Rollback();
908
909 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
910}
911
David Zeuthenf413fe52013-04-22 14:04:39 -0700912TEST(PayloadStateTest, DurationsAreCorrect) {
913 OmahaResponse response;
914 PayloadState payload_state;
915 MockSystemState mock_system_state;
916 FakeClock fake_clock;
917 Prefs prefs;
918 string temp_dir;
919
920 // Set the clock to a well-known time - 1 second on the wall-clock
921 // and 2 seconds on the monotonic clock
922 fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
923 fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
924
925 // We need persistent preferences for this test
926 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateDurationTests.XXXXXX",
927 &temp_dir));
928 prefs.Init(FilePath(temp_dir));
929
930 mock_system_state.set_clock(&fake_clock);
931 mock_system_state.set_prefs(&prefs);
932 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
933
934 // Check that durations are correct for a successful update where
935 // time has advanced 7 seconds on the wall clock and 4 seconds on
936 // the monotonic clock.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700937 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -0700938 fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
939 fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
940 payload_state.UpdateSucceeded();
941 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
942 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
943
944 // Check that durations are reset when a new response comes in.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700945 SetupPayloadStateWith2Urls("Hash8594", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -0700946 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
947 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
948
949 // Advance time a bit (10 secs), simulate download progress and
950 // check that durations are updated.
951 fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
952 fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
953 payload_state.DownloadProgress(10);
954 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
955 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
956
957 // Now simulate a reboot by resetting monotonic time (to 5000) and
958 // creating a new PayloadState object and check that we load the
959 // durations correctly (e.g. they are the same as before).
960 fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
961 PayloadState payload_state2;
962 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
963 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
964 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),10000000);
965
966 // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
967 // and check that the durations are increased accordingly.
968 fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
969 fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
970 payload_state2.UpdateSucceeded();
971 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
972 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),16000000);
973
974 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
975}
976
David Zeuthene4c58bf2013-06-18 17:26:50 -0700977TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
978 OmahaResponse response;
979 PayloadState payload_state;
980 MockSystemState mock_system_state;
981 FakeClock fake_clock;
982 Prefs prefs;
983 string temp_dir;
984
985 // Set the clock to a well-known time (t = 30 seconds).
986 fake_clock.SetWallclockTime(Time::FromInternalValue(
987 30 * Time::kMicrosecondsPerSecond));
988
989 // We need persistent preferences for this test
990 EXPECT_TRUE(utils::MakeTempDirectory(
991 "/tmp/RebootAfterSuccessfulUpdateTest.XXXXXX", &temp_dir));
992 prefs.Init(FilePath(temp_dir));
993
994 mock_system_state.set_clock(&fake_clock);
995 mock_system_state.set_prefs(&prefs);
996 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
997
998 // Make the update succeed.
999 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1000 payload_state.UpdateSucceeded();
1001
1002 // Check that the marker was written.
1003 EXPECT_TRUE(prefs.Exists(kPrefsSystemUpdatedMarker));
1004
1005 // Now simulate a reboot and set the wallclock time to a later point
1006 // (t = 500 seconds). We do this by using a new PayloadState object
1007 // and checking that it emits the right UMA metric with the right
1008 // value.
1009 fake_clock.SetWallclockTime(Time::FromInternalValue(
1010 500 * Time::kMicrosecondsPerSecond));
1011 PayloadState payload_state2;
1012 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
1013
1014 // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
1015 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1016 "Installer.TimeToRebootMinutes",
1017 7, _, _, _));
1018
1019 payload_state2.UpdateEngineStarted();
1020
1021 // Check that the marker was nuked.
1022 EXPECT_FALSE(prefs.Exists(kPrefsSystemUpdatedMarker));
1023
1024 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1025}
1026
Jay Srinivasan53173b92013-05-17 17:13:01 -07001027TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
1028 OmahaResponse response;
1029 MockSystemState mock_system_state;
1030 PayloadState payload_state;
1031
1032 // Pretend that this is an offical build so that the HTTP download policy
1033 // is honored.
1034 EXPECT_CALL(mock_system_state, IsOfficialBuild())
1035 .WillRepeatedly(Return(true));
1036
1037 policy::MockDevicePolicy disable_http_policy;
1038 EXPECT_CALL(mock_system_state, device_policy())
1039 .WillRepeatedly(Return(&disable_http_policy));
1040 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1041 .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
1042
1043 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1044
1045 // Set the first response.
1046 SetupPayloadStateWith2Urls("Hash8433", false, &payload_state, &response);
1047
1048 // Check that we skip the HTTP URL and use only the HTTPS url.
1049 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1050
1051 // Advance the URL index to 1 by faking an error.
1052 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
1053 payload_state.UpdateFailed(error);
1054
1055 // Check that we still skip the HTTP URL and use only the HTTPS url.
1056 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1057 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
1058
1059 // Now, slightly change the response and set it again.
1060 SetupPayloadStateWith2Urls("Hash2399", false, &payload_state, &response);
1061
1062 // Check that we still skip the HTTP URL and use only the HTTPS url.
1063 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1064
1065 // Now, pretend that the HTTP policy is turned on. We want to make sure
1066 // the new policy is honored.
1067 policy::MockDevicePolicy enable_http_policy;
1068 EXPECT_CALL(mock_system_state, device_policy())
1069 .WillRepeatedly(Return(&enable_http_policy));
1070 EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
1071 .WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
1072
1073 // Now, set the same response using the same hash
1074 // so that we can test that the state is reset not because of the
1075 // hash but because of the policy change which results in candidate url
1076 // list change.
1077 SetupPayloadStateWith2Urls("Hash2399", true, &payload_state, &response);
1078
1079 // Check that we use the HTTP URL now and the failure count is reset.
1080 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1081 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1082
1083 // Fake a failure and see if we're moving over to the HTTPS url and update
1084 // the URL switch count properly.
1085 payload_state.UpdateFailed(error);
1086 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1087 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
1088 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1089}
1090
Alex Deymo1c656c42013-06-28 11:02:14 -07001091TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
1092 OmahaResponse response;
1093 response.is_delta_payload = true;
1094 PayloadState payload_state;
1095 MockSystemState mock_system_state;
1096
1097 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1098 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1099
1100 // Simulate a successful download and update.
1101 payload_state.DownloadComplete();
1102
1103 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1104 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
1105 payload_state.UpdateSucceeded();
1106
1107 // Mock the request to a request where the delta was disabled but Omaha sends
1108 // a delta anyway and test again.
1109 OmahaRequestParams params(&mock_system_state);
1110 params.set_delta_okay(false);
1111 mock_system_state.set_request_params(&params);
1112
1113 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1114 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1115
1116 payload_state.DownloadComplete();
1117
1118 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1119 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
1120 payload_state.UpdateSucceeded();
1121}
1122
1123TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
1124 OmahaResponse response;
1125 response.is_delta_payload = false;
1126 PayloadState payload_state;
1127 MockSystemState mock_system_state;
1128
1129 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1130 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1131
1132 // Mock the request to a request where the delta was disabled.
1133 OmahaRequestParams params(&mock_system_state);
1134 params.set_delta_okay(false);
1135 mock_system_state.set_request_params(&params);
1136
1137 // Simulate a successful download and update.
1138 payload_state.DownloadComplete();
1139
1140 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1141 "Installer.PayloadFormat", kPayloadTypeForcedFull, kNumPayloadTypes));
1142 payload_state.UpdateSucceeded();
1143}
1144
1145TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
1146 OmahaResponse response;
1147 response.is_delta_payload = false;
1148 PayloadState payload_state;
1149 MockSystemState mock_system_state;
1150
1151 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1152 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1153
Alex Deymo820cc702013-06-28 15:43:46 -07001154 // Mock the request to a request where the delta is enabled, although the
1155 // result is full.
Alex Deymo1c656c42013-06-28 11:02:14 -07001156 OmahaRequestParams params(&mock_system_state);
1157 params.set_delta_okay(true);
1158 mock_system_state.set_request_params(&params);
1159
1160 // Simulate a successful download and update.
1161 payload_state.DownloadComplete();
1162
1163 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1164 "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
1165 payload_state.UpdateSucceeded();
1166}
1167
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001168}