blob: eb66628c8fcd46508a9e43bdc2e46a5a69f1dae9 [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";
45
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080046static void SetupPayloadStateWith2Urls(string hash,
Jay Srinivasan53173b92013-05-17 17:13:01 -070047 bool http_enabled,
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080048 PayloadState* payload_state,
49 OmahaResponse* response) {
50 response->payload_urls.clear();
51 response->payload_urls.push_back("http://test");
52 response->payload_urls.push_back("https://test");
53 response->size = 523456789;
54 response->hash = hash;
55 response->metadata_size = 558123;
56 response->metadata_signature = "metasign";
57 response->max_failure_count_per_url = 3;
58 payload_state->SetResponse(*response);
Jay Srinivasan08262882012-12-28 19:29:43 -080059 string stored_response_sign = payload_state->GetResponseSignature();
Jay Srinivasan53173b92013-05-17 17:13:01 -070060
61 string expected_url_https_only =
62 "NumURLs = 1\n"
63 "Candidate Url0 = https://test\n";
64
65 string expected_urls_both =
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080066 "NumURLs = 2\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -070067 "Candidate Url0 = http://test\n"
68 "Candidate Url1 = https://test\n";
69
70 string expected_response_sign =
71 (http_enabled ? expected_urls_both : expected_url_https_only) +
72 StringPrintf("Payload Size = 523456789\n"
73 "Payload Sha256 Hash = %s\n"
74 "Metadata Size = 558123\n"
75 "Metadata Signature = metasign\n"
76 "Is Delta Payload = %d\n"
77 "Max Failure Count Per Url = %d\n"
78 "Disable Payload Backoff = %d\n",
79 hash.c_str(),
80 response->is_delta_payload,
81 response->max_failure_count_per_url,
82 response->disable_payload_backoff);
Jay Srinivasan08262882012-12-28 19:29:43 -080083 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080084}
85
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080086class PayloadStateTest : public ::testing::Test { };
87
David Zeuthena99981f2013-04-29 13:42:47 -070088TEST(PayloadStateTest, DidYouAddANewErrorCode) {
89 if (kErrorCodeUmaReportedMax != 43) {
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080090 LOG(ERROR) << "The following failure is intentional. If you added a new "
David Zeuthena99981f2013-04-29 13:42:47 -070091 << "ErrorCode enum value, make sure to add it to the "
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080092 << "PayloadState::UpdateFailed method and then update this test "
David Zeuthena99981f2013-04-29 13:42:47 -070093 << "to the new value of kErrorCodeUmaReportedMax, which is "
94 << kErrorCodeUmaReportedMax;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080095 EXPECT_FALSE("Please see the log line above");
96 }
97}
98
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080099TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
100 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700101 MockSystemState mock_system_state;
102 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700103 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700104 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
105 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700106 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
107 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700108 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
109 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
110 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
111 .Times(AtLeast(1));
112 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
113 .Times(AtLeast(1));
114 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
115 .Times(AtLeast(1));
116 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
117 .Times(AtLeast(1));
118 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
119 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700120 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800121 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700122 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800123 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800124 string stored_response_sign = payload_state.GetResponseSignature();
125 string expected_response_sign = "NumURLs = 0\n"
126 "Payload Size = 0\n"
127 "Payload Sha256 Hash = \n"
128 "Metadata Size = 0\n"
129 "Metadata Signature = \n"
130 "Is Delta Payload = 0\n"
131 "Max Failure Count Per Url = 0\n"
132 "Disable Payload Backoff = 0\n";
133 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700134 EXPECT_EQ("", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800135 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700136 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700137 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800138}
139
140TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
141 OmahaResponse response;
Jay Srinivasan53173b92013-05-17 17:13:01 -0700142 response.payload_urls.push_back("https://single.url.test");
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800143 response.size = 123456789;
144 response.hash = "hash";
145 response.metadata_size = 58123;
146 response.metadata_signature = "msign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700147 MockSystemState mock_system_state;
148 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700149 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700150 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
151 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700152 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
153 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700154 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
155 .Times(AtLeast(1));
156 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
157 .Times(AtLeast(1));
158 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
159 .Times(AtLeast(1));
160 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
161 .Times(AtLeast(1));
162 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
163 .Times(AtLeast(1));
164 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
165 .Times(AtLeast(1));
166 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
167 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700168 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
169 .Times(AtLeast(1));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800170 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700171 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800172 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800173 string stored_response_sign = payload_state.GetResponseSignature();
174 string expected_response_sign = "NumURLs = 1\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -0700175 "Candidate Url0 = https://single.url.test\n"
Jay Srinivasan08262882012-12-28 19:29:43 -0800176 "Payload Size = 123456789\n"
177 "Payload Sha256 Hash = hash\n"
178 "Metadata Size = 58123\n"
179 "Metadata Signature = msign\n"
180 "Is Delta Payload = 0\n"
181 "Max Failure Count Per Url = 0\n"
182 "Disable Payload Backoff = 0\n";
183 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700184 EXPECT_EQ("https://single.url.test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800185 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700186 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700187 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800188}
189
190TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
191 OmahaResponse response;
192 response.payload_urls.push_back("http://multiple.url.test");
193 response.payload_urls.push_back("https://multiple.url.test");
194 response.size = 523456789;
195 response.hash = "rhash";
196 response.metadata_size = 558123;
197 response.metadata_signature = "metasign";
Jay Srinivasan19409b72013-04-12 19:23:36 -0700198 MockSystemState mock_system_state;
199 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700200 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700201 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
202 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700203 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
204 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700205 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0))
206 .Times(AtLeast(1));
207 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
208 .Times(AtLeast(1));
209 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
210 .Times(AtLeast(1));
211 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
212 .Times(AtLeast(1));
213 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
214 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700215 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
216 .Times(AtLeast(1));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700217
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800218 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700219 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800220 payload_state.SetResponse(response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800221 string stored_response_sign = payload_state.GetResponseSignature();
222 string expected_response_sign = "NumURLs = 2\n"
Jay Srinivasan53173b92013-05-17 17:13:01 -0700223 "Candidate Url0 = http://multiple.url.test\n"
224 "Candidate Url1 = https://multiple.url.test\n"
Jay Srinivasan08262882012-12-28 19:29:43 -0800225 "Payload Size = 523456789\n"
226 "Payload Sha256 Hash = rhash\n"
227 "Metadata Size = 558123\n"
228 "Metadata Signature = metasign\n"
229 "Is Delta Payload = 0\n"
230 "Max Failure Count Per Url = 0\n"
231 "Disable Payload Backoff = 0\n";
232 EXPECT_EQ(expected_response_sign, stored_response_sign);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700233 EXPECT_EQ("http://multiple.url.test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800234 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700235 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
David Zeuthena573d6f2013-06-14 16:13:36 -0700236 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800237}
238
239TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
240 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700241 MockSystemState mock_system_state;
242 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800243 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800244
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700245 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800246 // Payload attempt should start with 0 and then advance to 1.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700247 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
248 .Times(AtLeast(1));
249 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
250 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700251 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
252 .Times(AtLeast(1));
253 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
254 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700255 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
David Zeuthen9a017f22013-04-11 16:10:26 -0700256
Chris Sosabe45bef2013-04-09 18:25:12 -0700257 // Reboots will be set
258 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1));
259
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800260 // Url index should go from 0 to 1 twice.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700261 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
262 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800263
264 // Failure count should be called each times url index is set, so that's
265 // 4 times for this test.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700266 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
267 .Times(AtLeast(4));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800268
Jay Srinivasan19409b72013-04-12 19:23:36 -0700269 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800270
271 // This does a SetResponse which causes all the states to be set to 0 for
272 // the first time.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700273 SetupPayloadStateWith2Urls("Hash1235", true, &payload_state, &response);
274 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800275
276 // Verify that on the first error, the URL index advances to 1.
David Zeuthena99981f2013-04-29 13:42:47 -0700277 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800278 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700279 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800280
281 // Verify that on the next error, the URL index wraps around to 0.
282 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700283 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800284
285 // Verify that on the next error, it again advances to 1.
286 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700287 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
David Zeuthencc6f9962013-04-18 11:57:24 -0700288
289 // Verify that we switched URLs three times
290 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800291}
292
293TEST(PayloadStateTest, NewResponseResetsPayloadState) {
294 OmahaResponse response;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700295 MockSystemState mock_system_state;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800296 PayloadState payload_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800297
Jay Srinivasan19409b72013-04-12 19:23:36 -0700298 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800299
300 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700301 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700302 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800303
304 // Advance the URL index to 1 by faking an error.
David Zeuthena99981f2013-04-29 13:42:47 -0700305 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800306 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700307 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
David Zeuthencc6f9962013-04-18 11:57:24 -0700308 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800309
310 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700311 SetupPayloadStateWith2Urls("Hash8225", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700312 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800313
314 // Make sure the url index was reset to 0 because of the new response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700315 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800316 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700317 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700318 EXPECT_EQ(0,
319 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
320 EXPECT_EQ(0,
321 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
322 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
323 kDownloadSourceHttpsServer));
324 EXPECT_EQ(0,
325 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800326}
327
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800328TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
329 OmahaResponse response;
330 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700331 MockSystemState mock_system_state;
332 int progress_bytes = 100;
333 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800334
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700335 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700336 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
337 .Times(AtLeast(2));
338 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
339 .Times(AtLeast(1));
340 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
341 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800342
Alex Deymo820cc702013-06-28 15:43:46 -0700343 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
344 .Times(AtLeast(2));
345 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
346 .Times(AtLeast(1));
347 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 2))
348 .Times(AtLeast(1));
349
Jay Srinivasan19409b72013-04-12 19:23:36 -0700350 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
Jay Srinivasan08262882012-12-28 19:29:43 -0800351
Jay Srinivasan19409b72013-04-12 19:23:36 -0700352 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
353 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800354
Jay Srinivasan19409b72013-04-12 19:23:36 -0700355 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
356 .Times(AtLeast(7));
357 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
358 .Times(AtLeast(2));
359 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
360 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800361
Jay Srinivasan19409b72013-04-12 19:23:36 -0700362 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
363 .Times(AtLeast(1));
364 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
365 .Times(AtLeast(1));
David Zeuthen9a017f22013-04-11 16:10:26 -0700366
Jay Srinivasan19409b72013-04-12 19:23:36 -0700367 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
368 .Times(AtLeast(1));
369 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
370 .Times(AtLeast(1));
371 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
372 .Times(AtLeast(1));
373 EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
374 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700375 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
376 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700377
378 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800379
Jay Srinivasan53173b92013-05-17 17:13:01 -0700380 SetupPayloadStateWith2Urls("Hash5873", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700381 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800382
383 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700384 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800385 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700386 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700387 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800388 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700389 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800390
391 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700392 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800393 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700394 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700395 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800396 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700397 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800398
399 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700400 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800401 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700402 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700403 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800404 EXPECT_EQ(2, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700405 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800406
407 // This should advance the URL index as we've reached the
408 // max failure count and reset the failure count for the new URL index.
409 // This should also wrap around the URL index and thus cause the payload
410 // attempt number to be incremented.
David Zeuthena99981f2013-04-29 13:42:47 -0700411 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800412 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700413 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700414 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800415 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700416 EXPECT_EQ(2, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800417 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800418
419 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700420 payload_state.UpdateFailed(kErrorCodePayloadHashMismatchError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800421 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700422 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700423 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800424 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700425 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800426 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800427
428 // This should advance the URL index and payload attempt number due to
429 // wrap-around of URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700430 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMissingError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800431 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700432 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700433 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800434 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700435 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800436 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800437
438 // This HTTP error code should only increase the failure count.
David Zeuthena99981f2013-04-29 13:42:47 -0700439 payload_state.UpdateFailed(static_cast<ErrorCode>(
440 kErrorCodeOmahaRequestHTTPResponseBase + 404));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800441 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700442 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700443 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800444 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700445 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800446 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800447
448 // And that failure count should be reset when we download some bytes
449 // afterwards.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700450 payload_state.DownloadProgress(progress_bytes);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800451 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700452 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700453 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800454 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700455 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800456 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800457
458 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700459 SetupPayloadStateWith2Urls("Hash8532", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700460 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800461
462 // Make sure the url index was reset to 0 because of the new response.
463 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700464 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700465 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800466 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700467 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800468 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800469}
470
Alex Deymo820cc702013-06-28 15:43:46 -0700471TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulFullDownload) {
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800472 OmahaResponse response;
Alex Deymo820cc702013-06-28 15:43:46 -0700473 response.is_delta_payload = false;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800474 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700475 MockSystemState mock_system_state;
476 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800477
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700478 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700479 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
480 .Times(AtLeast(1));
481 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
482 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800483
Alex Deymo820cc702013-06-28 15:43:46 -0700484 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
485 .Times(AtLeast(1));
486 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
487 .Times(AtLeast(1));
488
Jay Srinivasan19409b72013-04-12 19:23:36 -0700489 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
490 .Times(AtLeast(2));
Jay Srinivasan08262882012-12-28 19:29:43 -0800491
Jay Srinivasan19409b72013-04-12 19:23:36 -0700492 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
493 .Times(AtLeast(1));
494 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
495 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800496
Jay Srinivasan19409b72013-04-12 19:23:36 -0700497 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800498
Jay Srinivasan53173b92013-05-17 17:13:01 -0700499 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800500
Alex Deymo29b51d92013-07-09 15:26:24 -0700501 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
502 "Installer.PayloadAttemptNumber", 1, _, _, _));
503 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
504 "Installer.FullPayloadAttemptNumber", 1, _, _, _));
505
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800506 // This should just advance the payload attempt number;
507 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700508 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800509 payload_state.DownloadComplete();
510 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700511 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
512 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
513 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
514 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
515}
516
517TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDeltaDownload) {
518 OmahaResponse response;
519 response.is_delta_payload = true;
520 PayloadState payload_state;
521 MockSystemState mock_system_state;
522 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
523
524 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
525 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
526 .Times(AtLeast(1));
527 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
528 .Times(AtLeast(1));
529
530 // kPrefsFullPayloadAttemptNumber is not incremented for delta payloads.
531 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
532 .Times(AtLeast(1));
533
534 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
535 .Times(1);
536
537 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
538 .Times(AtLeast(1));
539 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
540 .Times(AtLeast(1));
541
542 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
543
544 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
545
Alex Deymo29b51d92013-07-09 15:26:24 -0700546 // Metrics for Full payload attempt number is not sent with Delta payloads.
547 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
548 "Installer.PayloadAttemptNumber", 1, _, _, _));
549 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
550 "Installer.FullPayloadAttemptNumber", _, _, _, _))
551 .Times(0);
552
Alex Deymo820cc702013-06-28 15:43:46 -0700553 // This should just advance the payload attempt number;
554 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
555 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
556 payload_state.DownloadComplete();
557 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
558 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700559 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800560 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700561 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800562}
563
564TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
565 OmahaResponse response;
566 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700567 MockSystemState mock_system_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800568
Jay Srinivasan19409b72013-04-12 19:23:36 -0700569 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700570 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800571
572 // Generate enough events to advance URL index, failure count and
573 // payload attempt number all to 1.
574 payload_state.DownloadComplete();
David Zeuthena99981f2013-04-29 13:42:47 -0700575 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
576 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800577 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700578 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700579 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800580 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700581 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800582
583 // Now, simulate a corrupted url index on persisted store which gets
584 // loaded when update_engine restarts. Using a different prefs object
585 // so as to not bother accounting for the uninteresting calls above.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700586 MockSystemState mock_system_state2;
587 NiceMock<PrefsMock>* prefs2 = mock_system_state2.mock_prefs();
588 EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
589 EXPECT_CALL(*prefs2, GetInt64(_,_)).Times(AtLeast(1));
590 EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
591 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700592 EXPECT_CALL(*prefs2, GetInt64(kPrefsFullPayloadAttemptNumber, _))
593 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700594 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
595 .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
596 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
597 .Times(AtLeast(1));
David Zeuthencc6f9962013-04-18 11:57:24 -0700598 EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _))
599 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800600
601 // Note: This will be a different payload object, but the response should
602 // have the same hash as before so as to not trivially reset because the
603 // response was different. We want to specifically test that even if the
604 // response is same, we should reset the state if we find it corrupted.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700605 EXPECT_TRUE(payload_state.Initialize(&mock_system_state2));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700606 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800607
608 // Make sure all counters get reset to 0 because of the corrupted URL index
609 // we supplied above.
610 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700611 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700612 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800613 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700614 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800615}
Jay Srinivasan08262882012-12-28 19:29:43 -0800616
617TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
618 OmahaResponse response;
619 response.is_delta_payload = true;
620 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700621 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800622
Jay Srinivasan19409b72013-04-12 19:23:36 -0700623 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700624 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800625
626 // Simulate a successful download and see that we're ready to download
627 // again without any backoff as this is a delta payload.
628 payload_state.DownloadComplete();
Alex Deymo820cc702013-06-28 15:43:46 -0700629 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
630 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800631 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
632
633 // Simulate two failures (enough to cause payload backoff) and check
634 // again that we're ready to re-download without any backoff as this is
635 // a delta payload.
David Zeuthena99981f2013-04-29 13:42:47 -0700636 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
637 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700638 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Alex Deymo820cc702013-06-28 15:43:46 -0700639 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
640 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800641 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
642}
643
644static void CheckPayloadBackoffState(PayloadState* payload_state,
645 int expected_attempt_number,
646 TimeDelta expected_days) {
647 payload_state->DownloadComplete();
Alex Deymo820cc702013-06-28 15:43:46 -0700648 EXPECT_EQ(expected_attempt_number,
649 payload_state->GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800650 EXPECT_TRUE(payload_state->ShouldBackoffDownload());
651 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
652 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
653 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
654 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
655 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
656 EXPECT_LT(expected_min_time.ToInternalValue(),
657 backoff_expiry_time.ToInternalValue());
658 EXPECT_GT(expected_max_time.ToInternalValue(),
659 backoff_expiry_time.ToInternalValue());
660}
661
662TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
663 OmahaResponse response;
664 response.is_delta_payload = false;
665 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700666 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800667
Jay Srinivasan19409b72013-04-12 19:23:36 -0700668 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700669 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800670
671 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
672 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
673 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
674 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
675 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
676 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
677 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
678 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
679 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
680 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
681}
682
683TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
684 OmahaResponse response;
685 response.disable_payload_backoff = true;
686 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700687 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800688
Jay Srinivasan19409b72013-04-12 19:23:36 -0700689 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700690 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800691
692 // Simulate a successful download and see that we are ready to download
693 // again without any backoff.
694 payload_state.DownloadComplete();
695 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700696 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800697 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
698
699 // Test again, this time by simulating two errors that would cause
700 // the payload attempt number to increment due to wrap around. And
701 // check that we are still ready to re-download without any backoff.
David Zeuthena99981f2013-04-29 13:42:47 -0700702 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
703 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan08262882012-12-28 19:29:43 -0800704 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700705 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800706 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
707}
708
Jay Srinivasan19409b72013-04-12 19:23:36 -0700709TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
710 OmahaResponse response;
711 response.disable_payload_backoff = true;
712 PayloadState payload_state;
713 MockSystemState mock_system_state;
714 int https_total = 0;
715 int http_total = 0;
716
717 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700718 SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700719 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700720
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700721 // Simulate a previous attempt with in order to set an initial non-zero value
722 // for the total bytes downloaded for HTTP.
723 int prev_chunk = 323456789;
724 http_total += prev_chunk;
725 payload_state.DownloadProgress(prev_chunk);
726
727 // Ensure that the initial values for HTTP reflect this attempt.
728 EXPECT_EQ(prev_chunk,
729 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
730 EXPECT_EQ(http_total,
731 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
732
733 // Change the response hash so as to simulate a new response which will
734 // reset the current bytes downloaded, but not the total bytes downloaded.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700735 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700736 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700737
738 // First, simulate successful download of a few bytes over HTTP.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700739 int first_chunk = 5000000;
740 http_total += first_chunk;
741 payload_state.DownloadProgress(first_chunk);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700742 // Test that first all progress is made on HTTP and none on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700743 EXPECT_EQ(first_chunk,
744 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
745 EXPECT_EQ(http_total,
746 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
747 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
748 kDownloadSourceHttpsServer));
749 EXPECT_EQ(https_total,
750 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
751
752 // Simulate an error that'll cause the url index to point to https.
David Zeuthena99981f2013-04-29 13:42:47 -0700753 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700754 payload_state.UpdateFailed(error);
755
Jay Srinivasan53173b92013-05-17 17:13:01 -0700756 // Test that no new progress is made on HTTP and new progress is on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700757 int second_chunk = 23456789;
758 https_total += second_chunk;
759 payload_state.DownloadProgress(second_chunk);
760 EXPECT_EQ(first_chunk,
761 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
762 EXPECT_EQ(http_total,
763 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
764 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
765 kDownloadSourceHttpsServer));
766 EXPECT_EQ(https_total,
767 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
768
769 // Simulate error to go back to http.
770 payload_state.UpdateFailed(error);
771 int third_chunk = 32345678;
772 int http_chunk = first_chunk + third_chunk;
773 http_total += third_chunk;
774 int https_chunk = second_chunk;
775 payload_state.DownloadProgress(third_chunk);
776
777 // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
778 EXPECT_EQ(http_chunk,
779 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700780 EXPECT_EQ(http_total,
Jay Srinivasan19409b72013-04-12 19:23:36 -0700781 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
782 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
783 kDownloadSourceHttpsServer));
784 EXPECT_EQ(https_total,
785 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
786
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700787 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
788 .Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700789 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
790 "Installer.SuccessfulMBsDownloadedFromHttpServer",
791 http_chunk / kNumBytesInOneMiB, _, _, _));
792 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
793 "Installer.TotalMBsDownloadedFromHttpServer",
794 http_total / kNumBytesInOneMiB, _, _, _));
795 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
796 "Installer.SuccessfulMBsDownloadedFromHttpsServer",
797 https_chunk / kNumBytesInOneMiB, _, _, _));
798 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
799 "Installer.TotalMBsDownloadedFromHttpsServer",
800 https_total / kNumBytesInOneMiB, _, _, _));
David Zeuthencc6f9962013-04-18 11:57:24 -0700801 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
802 "Installer.UpdateURLSwitches",
803 2, _, _, _));
David Zeuthen674c3182013-04-18 14:05:20 -0700804 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
805 "Installer.UpdateDurationMinutes",
806 _, _, _, _));
807 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
808 "Installer.UpdateDurationUptimeMinutes",
809 _, _, _, _));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700810 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
811 "Installer.DownloadSourcesUsed", 3, _, _, _));
812 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
813 "Installer.DownloadOverheadPercentage", 542, _, _, _));
Alex Deymo1c656c42013-06-28 11:02:14 -0700814 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
815 "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
Alex Deymo820cc702013-06-28 15:43:46 -0700816 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
817 "Installer.AttemptsCount.Total", 1, _, _, _));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700818
819 payload_state.UpdateSucceeded();
820
821 // Make sure the metrics are reset after a successful update.
822 EXPECT_EQ(0,
823 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
824 EXPECT_EQ(0,
825 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
826 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
827 kDownloadSourceHttpsServer));
828 EXPECT_EQ(0,
829 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
David Zeuthena573d6f2013-06-14 16:13:36 -0700830 EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700831}
832
833TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
834 OmahaResponse response;
835 MockSystemState mock_system_state;
836 PayloadState payload_state;
837
838 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
839
840 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700841 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
Jay Srinivasan19409b72013-04-12 19:23:36 -0700842
843 int num_bytes = 10000;
844 payload_state.DownloadProgress(num_bytes);
845 EXPECT_EQ(num_bytes,
846 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
847 EXPECT_EQ(num_bytes,
848 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
849 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
850 kDownloadSourceHttpsServer));
851 EXPECT_EQ(0,
852 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
853
854 payload_state.UpdateRestarted();
855 // Make sure the current bytes downloaded is reset, but not the total bytes.
856 EXPECT_EQ(0,
857 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
858 EXPECT_EQ(num_bytes,
859 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
860}
861
Chris Sosabe45bef2013-04-09 18:25:12 -0700862TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
863 MockSystemState mock_system_state;
864 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700865
Chris Sosabe45bef2013-04-09 18:25:12 -0700866 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
867 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
868 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
869
870 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
871
872 payload_state.UpdateRestarted();
873 EXPECT_EQ(0, payload_state.GetNumReboots());
874
875 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(true));
876 payload_state.UpdateResumed();
877 // Num reboots should be incremented because system rebooted detected.
878 EXPECT_EQ(1, payload_state.GetNumReboots());
879
880 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(false));
881 payload_state.UpdateResumed();
882 // Num reboots should now be 1 as reboot was not detected.
883 EXPECT_EQ(1, payload_state.GetNumReboots());
884
885 // Restart the update again to verify we set the num of reboots back to 0.
886 payload_state.UpdateRestarted();
887 EXPECT_EQ(0, payload_state.GetNumReboots());
888}
Jay Srinivasan19409b72013-04-12 19:23:36 -0700889
Chris Sosaaa18e162013-06-20 13:20:30 -0700890TEST(PayloadStateTest, RollbackVersion) {
891 MockSystemState mock_system_state;
892 PayloadState payload_state;
893
894 NiceMock<PrefsMock>* mock_powerwash_safe_prefs =
895 mock_system_state.mock_powerwash_safe_prefs();
896 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
897
898 // Verify pre-conditions are good.
899 EXPECT_TRUE(payload_state.GetRollbackVersion().empty());
900
901 // Mock out the os version and make sure it's blacklisted correctly.
902 string rollback_version = "2345.0.0";
903 OmahaRequestParams params(&mock_system_state);
904 params.Init(rollback_version, "", false);
905 mock_system_state.set_request_params(&params);
906
907 EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion,
908 rollback_version));
909 payload_state.Rollback();
910
911 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
912}
913
David Zeuthenf413fe52013-04-22 14:04:39 -0700914TEST(PayloadStateTest, DurationsAreCorrect) {
915 OmahaResponse response;
916 PayloadState payload_state;
917 MockSystemState mock_system_state;
918 FakeClock fake_clock;
919 Prefs prefs;
920 string temp_dir;
921
922 // Set the clock to a well-known time - 1 second on the wall-clock
923 // and 2 seconds on the monotonic clock
924 fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
925 fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
926
927 // We need persistent preferences for this test
928 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateDurationTests.XXXXXX",
929 &temp_dir));
930 prefs.Init(FilePath(temp_dir));
931
932 mock_system_state.set_clock(&fake_clock);
933 mock_system_state.set_prefs(&prefs);
934 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
935
936 // Check that durations are correct for a successful update where
937 // time has advanced 7 seconds on the wall clock and 4 seconds on
938 // the monotonic clock.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700939 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -0700940 fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
941 fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
942 payload_state.UpdateSucceeded();
943 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
944 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
945
946 // Check that durations are reset when a new response comes in.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700947 SetupPayloadStateWith2Urls("Hash8594", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -0700948 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
949 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
950
951 // Advance time a bit (10 secs), simulate download progress and
952 // check that durations are updated.
953 fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
954 fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
955 payload_state.DownloadProgress(10);
956 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
957 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
958
959 // Now simulate a reboot by resetting monotonic time (to 5000) and
960 // creating a new PayloadState object and check that we load the
961 // durations correctly (e.g. they are the same as before).
962 fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
963 PayloadState payload_state2;
964 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
965 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
966 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),10000000);
967
968 // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
969 // and check that the durations are increased accordingly.
970 fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
971 fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
972 payload_state2.UpdateSucceeded();
973 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
974 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),16000000);
975
976 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
977}
978
David Zeuthene4c58bf2013-06-18 17:26:50 -0700979TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
980 OmahaResponse response;
981 PayloadState payload_state;
982 MockSystemState mock_system_state;
983 FakeClock fake_clock;
984 Prefs prefs;
985 string temp_dir;
986
987 // Set the clock to a well-known time (t = 30 seconds).
988 fake_clock.SetWallclockTime(Time::FromInternalValue(
989 30 * Time::kMicrosecondsPerSecond));
990
991 // We need persistent preferences for this test
992 EXPECT_TRUE(utils::MakeTempDirectory(
993 "/tmp/RebootAfterSuccessfulUpdateTest.XXXXXX", &temp_dir));
994 prefs.Init(FilePath(temp_dir));
995
996 mock_system_state.set_clock(&fake_clock);
997 mock_system_state.set_prefs(&prefs);
998 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
999
1000 // Make the update succeed.
1001 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1002 payload_state.UpdateSucceeded();
1003
1004 // Check that the marker was written.
1005 EXPECT_TRUE(prefs.Exists(kPrefsSystemUpdatedMarker));
1006
1007 // Now simulate a reboot and set the wallclock time to a later point
1008 // (t = 500 seconds). We do this by using a new PayloadState object
1009 // and checking that it emits the right UMA metric with the right
1010 // value.
1011 fake_clock.SetWallclockTime(Time::FromInternalValue(
1012 500 * Time::kMicrosecondsPerSecond));
1013 PayloadState payload_state2;
1014 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
1015
1016 // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
1017 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1018 "Installer.TimeToRebootMinutes",
1019 7, _, _, _));
Alex Deymo569c4242013-07-24 12:01:01 -07001020 EXPECT_CALL(mock_system_state, system_rebooted())
1021 .WillRepeatedly(Return(true));
David Zeuthene4c58bf2013-06-18 17:26:50 -07001022
1023 payload_state2.UpdateEngineStarted();
1024
1025 // Check that the marker was nuked.
1026 EXPECT_FALSE(prefs.Exists(kPrefsSystemUpdatedMarker));
1027
1028 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1029}
1030
Alex Deymo569c4242013-07-24 12:01:01 -07001031TEST(PayloadStateTest, RestartAfterCrash) {
1032 PayloadState payload_state;
1033 MockSystemState mock_system_state;
1034 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
1035
1036 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1037
1038 // No prefs should be used after a crash.
1039 EXPECT_CALL(*prefs, Exists(_)).Times(0);
1040 EXPECT_CALL(*prefs, SetString(_, _)).Times(0);
1041 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(0);
1042 EXPECT_CALL(*prefs, SetBoolean(_, _)).Times(0);
1043 EXPECT_CALL(*prefs, GetString(_, _)).Times(0);
1044 EXPECT_CALL(*prefs, GetInt64(_, _)).Times(0);
1045 EXPECT_CALL(*prefs, GetBoolean(_, _)).Times(0);
1046
1047 // No metrics are reported after a crash.
1048 EXPECT_CALL(*mock_system_state.mock_metrics_lib(),
1049 SendToUMA(_, _, _, _, _)).Times(0);
1050
1051 // Simulate an update_engine restart without a reboot.
1052 EXPECT_CALL(mock_system_state, system_rebooted())
1053 .WillRepeatedly(Return(false));
1054
1055 payload_state.UpdateEngineStarted();
1056}
1057
Jay Srinivasan53173b92013-05-17 17:13:01 -07001058TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
1059 OmahaResponse response;
1060 MockSystemState mock_system_state;
1061 PayloadState payload_state;
1062
1063 // Pretend that this is an offical build so that the HTTP download policy
1064 // is honored.
1065 EXPECT_CALL(mock_system_state, IsOfficialBuild())
1066 .WillRepeatedly(Return(true));
1067
1068 policy::MockDevicePolicy disable_http_policy;
1069 EXPECT_CALL(mock_system_state, device_policy())
1070 .WillRepeatedly(Return(&disable_http_policy));
1071 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1072 .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
1073
1074 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1075
1076 // Set the first response.
1077 SetupPayloadStateWith2Urls("Hash8433", false, &payload_state, &response);
1078
1079 // Check that we skip the HTTP URL and use only the HTTPS url.
1080 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1081
1082 // Advance the URL index to 1 by faking an error.
1083 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
1084 payload_state.UpdateFailed(error);
1085
1086 // Check that we still skip the HTTP URL and use only the HTTPS url.
1087 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1088 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
1089
1090 // Now, slightly change the response and set it again.
1091 SetupPayloadStateWith2Urls("Hash2399", false, &payload_state, &response);
1092
1093 // Check that we still skip the HTTP URL and use only the HTTPS url.
1094 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1095
1096 // Now, pretend that the HTTP policy is turned on. We want to make sure
1097 // the new policy is honored.
1098 policy::MockDevicePolicy enable_http_policy;
1099 EXPECT_CALL(mock_system_state, device_policy())
1100 .WillRepeatedly(Return(&enable_http_policy));
1101 EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
1102 .WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
1103
1104 // Now, set the same response using the same hash
1105 // so that we can test that the state is reset not because of the
1106 // hash but because of the policy change which results in candidate url
1107 // list change.
1108 SetupPayloadStateWith2Urls("Hash2399", true, &payload_state, &response);
1109
1110 // Check that we use the HTTP URL now and the failure count is reset.
1111 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1112 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1113
1114 // Fake a failure and see if we're moving over to the HTTPS url and update
1115 // the URL switch count properly.
1116 payload_state.UpdateFailed(error);
1117 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1118 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
1119 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1120}
1121
Alex Deymo1c656c42013-06-28 11:02:14 -07001122TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
1123 OmahaResponse response;
1124 response.is_delta_payload = true;
1125 PayloadState payload_state;
1126 MockSystemState mock_system_state;
1127
1128 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1129 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1130
1131 // Simulate a successful download and update.
1132 payload_state.DownloadComplete();
1133
1134 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1135 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
1136 payload_state.UpdateSucceeded();
1137
1138 // Mock the request to a request where the delta was disabled but Omaha sends
1139 // a delta anyway and test again.
1140 OmahaRequestParams params(&mock_system_state);
1141 params.set_delta_okay(false);
1142 mock_system_state.set_request_params(&params);
1143
1144 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1145 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1146
1147 payload_state.DownloadComplete();
1148
1149 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1150 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
1151 payload_state.UpdateSucceeded();
1152}
1153
1154TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
1155 OmahaResponse response;
1156 response.is_delta_payload = false;
1157 PayloadState payload_state;
1158 MockSystemState mock_system_state;
1159
1160 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1161 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1162
1163 // Mock the request to a request where the delta was disabled.
1164 OmahaRequestParams params(&mock_system_state);
1165 params.set_delta_okay(false);
1166 mock_system_state.set_request_params(&params);
1167
1168 // Simulate a successful download and update.
1169 payload_state.DownloadComplete();
1170
1171 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1172 "Installer.PayloadFormat", kPayloadTypeForcedFull, kNumPayloadTypes));
1173 payload_state.UpdateSucceeded();
1174}
1175
1176TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
1177 OmahaResponse response;
1178 response.is_delta_payload = false;
1179 PayloadState payload_state;
1180 MockSystemState mock_system_state;
1181
1182 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1183 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1184
Alex Deymo820cc702013-06-28 15:43:46 -07001185 // Mock the request to a request where the delta is enabled, although the
1186 // result is full.
Alex Deymo1c656c42013-06-28 11:02:14 -07001187 OmahaRequestParams params(&mock_system_state);
1188 params.set_delta_okay(true);
1189 mock_system_state.set_request_params(&params);
1190
1191 // Simulate a successful download and update.
1192 payload_state.DownloadComplete();
1193
1194 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1195 "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
1196 payload_state.UpdateSucceeded();
1197}
1198
Alex Deymo42432912013-07-12 20:21:15 -07001199TEST(PayloadStateTest, RebootAfterUpdateFailedMetric) {
1200 FakeHardware fake_hardware;
1201 MockSystemState mock_system_state;
1202 OmahaResponse response;
1203 PayloadState payload_state;
1204 Prefs prefs;
1205 string temp_dir;
1206
1207 // Setup an environment with persistent prefs across simulated reboots.
1208 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1209 &temp_dir));
1210 prefs.Init(FilePath(temp_dir));
1211 mock_system_state.set_prefs(&prefs);
1212
1213 fake_hardware.SetBootDevice("/dev/sda3");
1214 fake_hardware.SetKernelDeviceOfBootDevice("/dev/sda3", "/dev/sda2");
1215 mock_system_state.set_hardware(&fake_hardware);
1216
1217 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1218 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1219
1220 // Simulate a successful download and update.
1221 payload_state.DownloadComplete();
1222 payload_state.UpdateSucceeded();
1223 payload_state.ExpectRebootInNewVersion("Version:12345678");
1224
1225 // Reboot into the same environment to get an UMA metric with a value of 1.
1226 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1227 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
1228 payload_state.ReportFailedBootIfNeeded();
1229 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1230
1231 // Simulate a second update and reboot into the same environment, this should
1232 // send a value of 2.
1233 payload_state.ExpectRebootInNewVersion("Version:12345678");
1234
1235 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1236 "Installer.RebootToNewPartitionAttempt", 2, _, _, _));
1237 payload_state.ReportFailedBootIfNeeded();
1238 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1239
1240 // Simulate a third failed reboot to new version, but this time for a
1241 // different payload. This should send a value of 1 this time.
1242 payload_state.ExpectRebootInNewVersion("Version:3141592");
1243 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1244 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
1245 payload_state.ReportFailedBootIfNeeded();
1246 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1247
1248 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1249}
1250
1251TEST(PayloadStateTest, RebootAfterUpdateSucceed) {
1252 FakeHardware fake_hardware;
1253 MockSystemState mock_system_state;
1254 OmahaResponse response;
1255 PayloadState payload_state;
1256 Prefs prefs;
1257 string temp_dir;
1258
1259 // Setup an environment with persistent prefs across simulated reboots.
1260 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1261 &temp_dir));
1262 prefs.Init(FilePath(temp_dir));
1263 mock_system_state.set_prefs(&prefs);
1264
1265 fake_hardware.SetKernelDeviceOfBootDevice("/dev/sda3", "/dev/sda2");
1266 fake_hardware.SetKernelDeviceOfBootDevice("/dev/sda5", "/dev/sda4");
1267 fake_hardware.SetBootDevice("/dev/sda3");
1268 mock_system_state.set_hardware(&fake_hardware);
1269
1270 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1271 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1272
1273 // Simulate a successful download and update.
1274 payload_state.DownloadComplete();
1275 payload_state.UpdateSucceeded();
1276 payload_state.ExpectRebootInNewVersion("Version:12345678");
1277
1278 // Change the BootDevice to a different one, no metric should be sent.
1279 fake_hardware.SetBootDevice("/dev/sda5");
1280
1281 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1282 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1283 .Times(0);
1284 payload_state.ReportFailedBootIfNeeded();
1285
1286 // A second reboot in eiher partition should not send a metric.
1287 payload_state.ReportFailedBootIfNeeded();
1288 fake_hardware.SetBootDevice("/dev/sda3");
1289 payload_state.ReportFailedBootIfNeeded();
1290
1291 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1292}
1293
1294TEST(PayloadStateTest, RebootAfterCanceledUpdate) {
1295 MockSystemState mock_system_state;
1296 OmahaResponse response;
1297 PayloadState payload_state;
1298 Prefs prefs;
1299 string temp_dir;
1300
1301 // Setup an environment with persistent prefs across simulated reboots.
1302 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1303 &temp_dir));
1304 prefs.Init(FilePath(temp_dir));
1305 mock_system_state.set_prefs(&prefs);
1306
1307 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1308 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1309
1310 // Simulate a successful download and update.
1311 payload_state.DownloadComplete();
1312 payload_state.UpdateSucceeded();
1313 payload_state.ExpectRebootInNewVersion("Version:12345678");
1314
1315 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1316 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1317 .Times(0);
1318
1319 // Cancel the applied update.
1320 payload_state.ResetUpdateStatus();
1321
1322 // Simulate a reboot.
1323 payload_state.ReportFailedBootIfNeeded();
1324
1325 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1326}
1327
1328TEST(PayloadStateTest, UpdateSuccessWithWipedPrefs) {
1329 MockSystemState mock_system_state;
1330 PayloadState payload_state;
1331 Prefs prefs;
1332 string temp_dir;
1333
1334 // Setup an environment with persistent but initially empty prefs.
1335 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1336 &temp_dir));
1337 prefs.Init(FilePath(temp_dir));
1338 mock_system_state.set_prefs(&prefs);
1339
1340 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1341
1342 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1343 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1344 .Times(0);
1345
1346 // Simulate a reboot in this environment.
1347 payload_state.ReportFailedBootIfNeeded();
1348
1349 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1350}
1351
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001352}