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