blob: fc6b4e912553f4f472c0b940d6765b1cedcdf9ca [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) {
Don Garrett81018e02013-07-30 18:46:31 -070089 if (kErrorCodeUmaReportedMax != 44) {
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
Alex Deymob33b0f02013-08-08 21:10:02 -0700300 // The first response doesn't send an abandoned event.
301 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
302 "Installer.UpdatesAbandonedEventCount", 0, _, _, _)).Times(0);
303
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800304 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700305 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700306 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800307
308 // Advance the URL index to 1 by faking an error.
David Zeuthena99981f2013-04-29 13:42:47 -0700309 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800310 payload_state.UpdateFailed(error);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700311 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
David Zeuthencc6f9962013-04-18 11:57:24 -0700312 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800313
Alex Deymob33b0f02013-08-08 21:10:02 -0700314 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
315 "Installer.UpdatesAbandonedEventCount", 1, _, _, _));
316
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800317 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700318 SetupPayloadStateWith2Urls("Hash8225", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700319 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800320
Alex Deymob33b0f02013-08-08 21:10:02 -0700321 // Fake an error again.
322 payload_state.UpdateFailed(error);
323 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
324 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
325
326 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
327 "Installer.UpdatesAbandonedEventCount", 2, _, _, _));
328
329 // Return a third different response.
330 SetupPayloadStateWith2Urls("Hash9999", true, &payload_state, &response);
331 EXPECT_EQ(3, payload_state.GetNumResponsesSeen());
332
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800333 // Make sure the url index was reset to 0 because of the new response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700334 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800335 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700336 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700337 EXPECT_EQ(0,
338 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
339 EXPECT_EQ(0,
340 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
341 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
342 kDownloadSourceHttpsServer));
343 EXPECT_EQ(0,
344 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800345}
346
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800347TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
348 OmahaResponse response;
349 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700350 MockSystemState mock_system_state;
351 int progress_bytes = 100;
352 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800353
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700354 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700355 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
356 .Times(AtLeast(2));
357 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
358 .Times(AtLeast(1));
359 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
360 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800361
Alex Deymo820cc702013-06-28 15:43:46 -0700362 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
363 .Times(AtLeast(2));
364 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
365 .Times(AtLeast(1));
366 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 2))
367 .Times(AtLeast(1));
368
Jay Srinivasan19409b72013-04-12 19:23:36 -0700369 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
Jay Srinivasan08262882012-12-28 19:29:43 -0800370
Jay Srinivasan19409b72013-04-12 19:23:36 -0700371 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
372 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800373
Jay Srinivasan19409b72013-04-12 19:23:36 -0700374 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
375 .Times(AtLeast(7));
376 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
377 .Times(AtLeast(2));
378 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
379 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800380
Jay Srinivasan19409b72013-04-12 19:23:36 -0700381 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
382 .Times(AtLeast(1));
383 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
384 .Times(AtLeast(1));
David Zeuthen9a017f22013-04-11 16:10:26 -0700385
Jay Srinivasan19409b72013-04-12 19:23:36 -0700386 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
387 .Times(AtLeast(1));
388 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
389 .Times(AtLeast(1));
390 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
391 .Times(AtLeast(1));
392 EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
393 .Times(AtLeast(1));
Chris Sosabe45bef2013-04-09 18:25:12 -0700394 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
395 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700396
397 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800398
Jay Srinivasan53173b92013-05-17 17:13:01 -0700399 SetupPayloadStateWith2Urls("Hash5873", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700400 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800401
402 // This should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700403 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800404 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700405 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700406 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800407 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700408 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800409
410 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700411 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800412 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700413 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700414 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800415 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700416 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800417
418 // This should advance the failure count only.
David Zeuthena99981f2013-04-29 13:42:47 -0700419 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800420 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700421 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700422 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800423 EXPECT_EQ(2, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700424 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800425
426 // This should advance the URL index as we've reached the
427 // max failure count and reset the failure count for the new URL index.
428 // This should also wrap around the URL index and thus cause the payload
429 // attempt number to be incremented.
David Zeuthena99981f2013-04-29 13:42:47 -0700430 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800431 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700432 EXPECT_EQ(1, 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(2, 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 should advance the URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700439 payload_state.UpdateFailed(kErrorCodePayloadHashMismatchError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800440 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700441 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700442 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800443 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700444 EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800445 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800446
447 // This should advance the URL index and payload attempt number due to
448 // wrap-around of URL index.
David Zeuthena99981f2013-04-29 13:42:47 -0700449 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMissingError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800450 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700451 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700452 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800453 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700454 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800455 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800456
457 // This HTTP error code should only increase the failure count.
David Zeuthena99981f2013-04-29 13:42:47 -0700458 payload_state.UpdateFailed(static_cast<ErrorCode>(
459 kErrorCodeOmahaRequestHTTPResponseBase + 404));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800460 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700461 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700462 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800463 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700464 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800465 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800466
467 // And that failure count should be reset when we download some bytes
468 // afterwards.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700469 payload_state.DownloadProgress(progress_bytes);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800470 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700471 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700472 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800473 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700474 EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800475 EXPECT_TRUE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800476
477 // Now, slightly change the response and set it again.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700478 SetupPayloadStateWith2Urls("Hash8532", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700479 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800480
481 // Make sure the url index was reset to 0 because of the new response.
482 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700483 EXPECT_EQ(0, 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(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan08262882012-12-28 19:29:43 -0800487 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800488}
489
Alex Deymo820cc702013-06-28 15:43:46 -0700490TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulFullDownload) {
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800491 OmahaResponse response;
Alex Deymo820cc702013-06-28 15:43:46 -0700492 response.is_delta_payload = false;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800493 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700494 MockSystemState mock_system_state;
495 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800496
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700497 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700498 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
499 .Times(AtLeast(1));
500 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
501 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800502
Alex Deymo820cc702013-06-28 15:43:46 -0700503 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
504 .Times(AtLeast(1));
505 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
506 .Times(AtLeast(1));
507
Jay Srinivasan19409b72013-04-12 19:23:36 -0700508 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
509 .Times(AtLeast(2));
Jay Srinivasan08262882012-12-28 19:29:43 -0800510
Jay Srinivasan19409b72013-04-12 19:23:36 -0700511 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
512 .Times(AtLeast(1));
513 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
514 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800515
Jay Srinivasan19409b72013-04-12 19:23:36 -0700516 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800517
Jay Srinivasan53173b92013-05-17 17:13:01 -0700518 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800519
Alex Deymo29b51d92013-07-09 15:26:24 -0700520 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
521 "Installer.PayloadAttemptNumber", 1, _, _, _));
522 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
523 "Installer.FullPayloadAttemptNumber", 1, _, _, _));
524
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800525 // This should just advance the payload attempt number;
526 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700527 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800528 payload_state.DownloadComplete();
529 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700530 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
531 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
532 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
533 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
534}
535
536TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDeltaDownload) {
537 OmahaResponse response;
538 response.is_delta_payload = true;
539 PayloadState payload_state;
540 MockSystemState mock_system_state;
541 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
542
543 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AnyNumber());
544 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
545 .Times(AtLeast(1));
546 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
547 .Times(AtLeast(1));
548
549 // kPrefsFullPayloadAttemptNumber is not incremented for delta payloads.
550 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
551 .Times(AtLeast(1));
552
553 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _))
554 .Times(1);
555
556 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0))
557 .Times(AtLeast(1));
558 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
559 .Times(AtLeast(1));
560
561 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
562
563 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
564
Alex Deymo29b51d92013-07-09 15:26:24 -0700565 // Metrics for Full payload attempt number is not sent with Delta payloads.
566 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
567 "Installer.PayloadAttemptNumber", 1, _, _, _));
568 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
569 "Installer.FullPayloadAttemptNumber", _, _, _, _))
570 .Times(0);
571
Alex Deymo820cc702013-06-28 15:43:46 -0700572 // This should just advance the payload attempt number;
573 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
574 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
575 payload_state.DownloadComplete();
576 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
577 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700578 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800579 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700580 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800581}
582
583TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
584 OmahaResponse response;
585 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700586 MockSystemState mock_system_state;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800587
Jay Srinivasan19409b72013-04-12 19:23:36 -0700588 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700589 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800590
591 // Generate enough events to advance URL index, failure count and
592 // payload attempt number all to 1.
593 payload_state.DownloadComplete();
David Zeuthena99981f2013-04-29 13:42:47 -0700594 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
595 payload_state.UpdateFailed(kErrorCodeDownloadTransferError);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800596 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700597 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700598 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800599 EXPECT_EQ(1, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700600 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800601
602 // Now, simulate a corrupted url index on persisted store which gets
603 // loaded when update_engine restarts. Using a different prefs object
604 // so as to not bother accounting for the uninteresting calls above.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700605 MockSystemState mock_system_state2;
606 NiceMock<PrefsMock>* prefs2 = mock_system_state2.mock_prefs();
607 EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
608 EXPECT_CALL(*prefs2, GetInt64(_,_)).Times(AtLeast(1));
609 EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
610 .Times(AtLeast(1));
Alex Deymo820cc702013-06-28 15:43:46 -0700611 EXPECT_CALL(*prefs2, GetInt64(kPrefsFullPayloadAttemptNumber, _))
612 .Times(AtLeast(1));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700613 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
614 .WillRepeatedly(DoAll(SetArgumentPointee<1>(2), Return(true)));
615 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
616 .Times(AtLeast(1));
David Zeuthencc6f9962013-04-18 11:57:24 -0700617 EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _))
618 .Times(AtLeast(1));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800619
620 // Note: This will be a different payload object, but the response should
621 // have the same hash as before so as to not trivially reset because the
622 // response was different. We want to specifically test that even if the
623 // response is same, we should reset the state if we find it corrupted.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700624 EXPECT_TRUE(payload_state.Initialize(&mock_system_state2));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700625 SetupPayloadStateWith2Urls("Hash4427", true, &payload_state, &response);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800626
627 // Make sure all counters get reset to 0 because of the corrupted URL index
628 // we supplied above.
629 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700630 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan53173b92013-05-17 17:13:01 -0700631 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800632 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
David Zeuthencc6f9962013-04-18 11:57:24 -0700633 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800634}
Jay Srinivasan08262882012-12-28 19:29:43 -0800635
636TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
637 OmahaResponse response;
638 response.is_delta_payload = true;
639 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700640 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800641
Jay Srinivasan19409b72013-04-12 19:23:36 -0700642 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700643 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800644
645 // Simulate a successful download and see that we're ready to download
646 // again without any backoff as this is a delta payload.
647 payload_state.DownloadComplete();
Alex Deymo820cc702013-06-28 15:43:46 -0700648 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
649 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800650 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
651
652 // Simulate two failures (enough to cause payload backoff) and check
653 // again that we're ready to re-download without any backoff as this is
654 // a delta payload.
David Zeuthena99981f2013-04-29 13:42:47 -0700655 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
656 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700657 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
Alex Deymo820cc702013-06-28 15:43:46 -0700658 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
659 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800660 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
661}
662
663static void CheckPayloadBackoffState(PayloadState* payload_state,
664 int expected_attempt_number,
665 TimeDelta expected_days) {
666 payload_state->DownloadComplete();
Alex Deymo820cc702013-06-28 15:43:46 -0700667 EXPECT_EQ(expected_attempt_number,
668 payload_state->GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800669 EXPECT_TRUE(payload_state->ShouldBackoffDownload());
670 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
671 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
672 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
673 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
674 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
675 EXPECT_LT(expected_min_time.ToInternalValue(),
676 backoff_expiry_time.ToInternalValue());
677 EXPECT_GT(expected_max_time.ToInternalValue(),
678 backoff_expiry_time.ToInternalValue());
679}
680
681TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
682 OmahaResponse response;
683 response.is_delta_payload = false;
684 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700685 MockSystemState mock_system_state;
Jay Srinivasan08262882012-12-28 19:29:43 -0800686
Jay Srinivasan19409b72013-04-12 19:23:36 -0700687 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700688 SetupPayloadStateWith2Urls("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800689
690 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
691 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
692 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
693 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
694 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
695 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
696 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
697 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
698 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
699 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
700}
701
702TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
703 OmahaResponse response;
704 response.disable_payload_backoff = 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("Hash8939", true, &payload_state, &response);
Jay Srinivasan08262882012-12-28 19:29:43 -0800710
711 // Simulate a successful download and see that we are ready to download
712 // again without any backoff.
713 payload_state.DownloadComplete();
714 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700715 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800716 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
717
718 // Test again, this time by simulating two errors that would cause
719 // the payload attempt number to increment due to wrap around. And
720 // check that we are still ready to re-download without any backoff.
David Zeuthena99981f2013-04-29 13:42:47 -0700721 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
722 payload_state.UpdateFailed(kErrorCodeDownloadMetadataSignatureMismatch);
Jay Srinivasan08262882012-12-28 19:29:43 -0800723 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
Alex Deymo820cc702013-06-28 15:43:46 -0700724 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
Jay Srinivasan08262882012-12-28 19:29:43 -0800725 EXPECT_FALSE(payload_state.ShouldBackoffDownload());
726}
727
Jay Srinivasan19409b72013-04-12 19:23:36 -0700728TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
729 OmahaResponse response;
730 response.disable_payload_backoff = true;
731 PayloadState payload_state;
732 MockSystemState mock_system_state;
733 int https_total = 0;
734 int http_total = 0;
735
736 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
Jay Srinivasan53173b92013-05-17 17:13:01 -0700737 SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700738 EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700739
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700740 // Simulate a previous attempt with in order to set an initial non-zero value
741 // for the total bytes downloaded for HTTP.
742 int prev_chunk = 323456789;
743 http_total += prev_chunk;
744 payload_state.DownloadProgress(prev_chunk);
745
746 // Ensure that the initial values for HTTP reflect this attempt.
747 EXPECT_EQ(prev_chunk,
748 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
749 EXPECT_EQ(http_total,
750 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
751
752 // Change the response hash so as to simulate a new response which will
753 // reset the current bytes downloaded, but not the total bytes downloaded.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700754 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
David Zeuthena573d6f2013-06-14 16:13:36 -0700755 EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700756
757 // First, simulate successful download of a few bytes over HTTP.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700758 int first_chunk = 5000000;
759 http_total += first_chunk;
760 payload_state.DownloadProgress(first_chunk);
Jay Srinivasan53173b92013-05-17 17:13:01 -0700761 // Test that first all progress is made on HTTP and none on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700762 EXPECT_EQ(first_chunk,
763 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
764 EXPECT_EQ(http_total,
765 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
766 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
767 kDownloadSourceHttpsServer));
768 EXPECT_EQ(https_total,
769 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
770
771 // Simulate an error that'll cause the url index to point to https.
David Zeuthena99981f2013-04-29 13:42:47 -0700772 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700773 payload_state.UpdateFailed(error);
774
Jay Srinivasan53173b92013-05-17 17:13:01 -0700775 // Test that no new progress is made on HTTP and new progress is on HTTPS.
Jay Srinivasan19409b72013-04-12 19:23:36 -0700776 int second_chunk = 23456789;
777 https_total += second_chunk;
778 payload_state.DownloadProgress(second_chunk);
779 EXPECT_EQ(first_chunk,
780 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
781 EXPECT_EQ(http_total,
782 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
783 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
784 kDownloadSourceHttpsServer));
785 EXPECT_EQ(https_total,
786 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
787
788 // Simulate error to go back to http.
789 payload_state.UpdateFailed(error);
790 int third_chunk = 32345678;
791 int http_chunk = first_chunk + third_chunk;
792 http_total += third_chunk;
793 int https_chunk = second_chunk;
794 payload_state.DownloadProgress(third_chunk);
795
796 // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
797 EXPECT_EQ(http_chunk,
798 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700799 EXPECT_EQ(http_total,
Jay Srinivasan19409b72013-04-12 19:23:36 -0700800 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
801 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded(
802 kDownloadSourceHttpsServer));
803 EXPECT_EQ(https_total,
804 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
805
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700806 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
807 .Times(AnyNumber());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700808 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
809 "Installer.SuccessfulMBsDownloadedFromHttpServer",
810 http_chunk / kNumBytesInOneMiB, _, _, _));
811 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
812 "Installer.TotalMBsDownloadedFromHttpServer",
813 http_total / kNumBytesInOneMiB, _, _, _));
814 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
815 "Installer.SuccessfulMBsDownloadedFromHttpsServer",
816 https_chunk / kNumBytesInOneMiB, _, _, _));
817 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
818 "Installer.TotalMBsDownloadedFromHttpsServer",
819 https_total / kNumBytesInOneMiB, _, _, _));
David Zeuthencc6f9962013-04-18 11:57:24 -0700820 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
821 "Installer.UpdateURLSwitches",
822 2, _, _, _));
David Zeuthen674c3182013-04-18 14:05:20 -0700823 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
824 "Installer.UpdateDurationMinutes",
825 _, _, _, _));
826 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
827 "Installer.UpdateDurationUptimeMinutes",
828 _, _, _, _));
Jay Srinivasandbd9ea22013-04-22 17:45:19 -0700829 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
830 "Installer.DownloadSourcesUsed", 3, _, _, _));
831 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
832 "Installer.DownloadOverheadPercentage", 542, _, _, _));
Alex Deymo1c656c42013-06-28 11:02:14 -0700833 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
834 "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
Alex Deymo820cc702013-06-28 15:43:46 -0700835 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
836 "Installer.AttemptsCount.Total", 1, _, _, _));
Jay Srinivasan19409b72013-04-12 19:23:36 -0700837
838 payload_state.UpdateSucceeded();
839
840 // Make sure the metrics are reset after a successful update.
841 EXPECT_EQ(0,
842 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
843 EXPECT_EQ(0,
844 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
845 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
846 kDownloadSourceHttpsServer));
847 EXPECT_EQ(0,
848 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
David Zeuthena573d6f2013-06-14 16:13:36 -0700849 EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
Jay Srinivasan19409b72013-04-12 19:23:36 -0700850}
851
852TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
853 OmahaResponse response;
854 MockSystemState mock_system_state;
855 PayloadState payload_state;
856
857 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
858
859 // Set the first response.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700860 SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
Jay Srinivasan19409b72013-04-12 19:23:36 -0700861
862 int num_bytes = 10000;
863 payload_state.DownloadProgress(num_bytes);
864 EXPECT_EQ(num_bytes,
865 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
866 EXPECT_EQ(num_bytes,
867 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
868 EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
869 kDownloadSourceHttpsServer));
870 EXPECT_EQ(0,
871 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
872
873 payload_state.UpdateRestarted();
874 // Make sure the current bytes downloaded is reset, but not the total bytes.
875 EXPECT_EQ(0,
876 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
877 EXPECT_EQ(num_bytes,
878 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
879}
880
Chris Sosabe45bef2013-04-09 18:25:12 -0700881TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
882 MockSystemState mock_system_state;
883 PayloadState payload_state;
Jay Srinivasan19409b72013-04-12 19:23:36 -0700884
Chris Sosabe45bef2013-04-09 18:25:12 -0700885 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
886 EXPECT_CALL(*prefs, SetInt64(_,_)).Times(AtLeast(0));
887 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
888
889 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
890
891 payload_state.UpdateRestarted();
892 EXPECT_EQ(0, payload_state.GetNumReboots());
893
894 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(true));
895 payload_state.UpdateResumed();
896 // Num reboots should be incremented because system rebooted detected.
897 EXPECT_EQ(1, payload_state.GetNumReboots());
898
899 EXPECT_CALL(mock_system_state, system_rebooted()).WillOnce(Return(false));
900 payload_state.UpdateResumed();
901 // Num reboots should now be 1 as reboot was not detected.
902 EXPECT_EQ(1, payload_state.GetNumReboots());
903
904 // Restart the update again to verify we set the num of reboots back to 0.
905 payload_state.UpdateRestarted();
906 EXPECT_EQ(0, payload_state.GetNumReboots());
907}
Jay Srinivasan19409b72013-04-12 19:23:36 -0700908
Chris Sosaaa18e162013-06-20 13:20:30 -0700909TEST(PayloadStateTest, RollbackVersion) {
910 MockSystemState mock_system_state;
911 PayloadState payload_state;
912
913 NiceMock<PrefsMock>* mock_powerwash_safe_prefs =
914 mock_system_state.mock_powerwash_safe_prefs();
915 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
916
917 // Verify pre-conditions are good.
918 EXPECT_TRUE(payload_state.GetRollbackVersion().empty());
919
920 // Mock out the os version and make sure it's blacklisted correctly.
921 string rollback_version = "2345.0.0";
922 OmahaRequestParams params(&mock_system_state);
923 params.Init(rollback_version, "", false);
924 mock_system_state.set_request_params(&params);
925
926 EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion,
927 rollback_version));
928 payload_state.Rollback();
929
930 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
931}
932
David Zeuthenf413fe52013-04-22 14:04:39 -0700933TEST(PayloadStateTest, DurationsAreCorrect) {
934 OmahaResponse response;
935 PayloadState payload_state;
936 MockSystemState mock_system_state;
937 FakeClock fake_clock;
938 Prefs prefs;
939 string temp_dir;
940
941 // Set the clock to a well-known time - 1 second on the wall-clock
942 // and 2 seconds on the monotonic clock
943 fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
944 fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
945
946 // We need persistent preferences for this test
947 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateDurationTests.XXXXXX",
948 &temp_dir));
949 prefs.Init(FilePath(temp_dir));
950
951 mock_system_state.set_clock(&fake_clock);
952 mock_system_state.set_prefs(&prefs);
953 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
954
955 // Check that durations are correct for a successful update where
956 // time has advanced 7 seconds on the wall clock and 4 seconds on
957 // the monotonic clock.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700958 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -0700959 fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
960 fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
961 payload_state.UpdateSucceeded();
962 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
963 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
964
965 // Check that durations are reset when a new response comes in.
Jay Srinivasan53173b92013-05-17 17:13:01 -0700966 SetupPayloadStateWith2Urls("Hash8594", true, &payload_state, &response);
David Zeuthenf413fe52013-04-22 14:04:39 -0700967 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
968 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
969
970 // Advance time a bit (10 secs), simulate download progress and
971 // check that durations are updated.
972 fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
973 fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
974 payload_state.DownloadProgress(10);
975 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
976 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
977
978 // Now simulate a reboot by resetting monotonic time (to 5000) and
979 // creating a new PayloadState object and check that we load the
980 // durations correctly (e.g. they are the same as before).
981 fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
982 PayloadState payload_state2;
983 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
984 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
985 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),10000000);
986
987 // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
988 // and check that the durations are increased accordingly.
989 fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
990 fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
991 payload_state2.UpdateSucceeded();
992 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
993 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),16000000);
994
995 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
996}
997
David Zeuthene4c58bf2013-06-18 17:26:50 -0700998TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
999 OmahaResponse response;
1000 PayloadState payload_state;
1001 MockSystemState mock_system_state;
1002 FakeClock fake_clock;
1003 Prefs prefs;
1004 string temp_dir;
1005
1006 // Set the clock to a well-known time (t = 30 seconds).
1007 fake_clock.SetWallclockTime(Time::FromInternalValue(
1008 30 * Time::kMicrosecondsPerSecond));
1009
1010 // We need persistent preferences for this test
1011 EXPECT_TRUE(utils::MakeTempDirectory(
1012 "/tmp/RebootAfterSuccessfulUpdateTest.XXXXXX", &temp_dir));
1013 prefs.Init(FilePath(temp_dir));
1014
1015 mock_system_state.set_clock(&fake_clock);
1016 mock_system_state.set_prefs(&prefs);
1017 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1018
1019 // Make the update succeed.
1020 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1021 payload_state.UpdateSucceeded();
1022
1023 // Check that the marker was written.
1024 EXPECT_TRUE(prefs.Exists(kPrefsSystemUpdatedMarker));
1025
1026 // Now simulate a reboot and set the wallclock time to a later point
1027 // (t = 500 seconds). We do this by using a new PayloadState object
1028 // and checking that it emits the right UMA metric with the right
1029 // value.
1030 fake_clock.SetWallclockTime(Time::FromInternalValue(
1031 500 * Time::kMicrosecondsPerSecond));
1032 PayloadState payload_state2;
1033 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
1034
1035 // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
1036 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1037 "Installer.TimeToRebootMinutes",
1038 7, _, _, _));
Alex Deymo569c4242013-07-24 12:01:01 -07001039 EXPECT_CALL(mock_system_state, system_rebooted())
1040 .WillRepeatedly(Return(true));
David Zeuthene4c58bf2013-06-18 17:26:50 -07001041
1042 payload_state2.UpdateEngineStarted();
1043
1044 // Check that the marker was nuked.
1045 EXPECT_FALSE(prefs.Exists(kPrefsSystemUpdatedMarker));
1046
1047 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1048}
1049
Alex Deymo569c4242013-07-24 12:01:01 -07001050TEST(PayloadStateTest, RestartAfterCrash) {
1051 PayloadState payload_state;
1052 MockSystemState mock_system_state;
1053 NiceMock<PrefsMock>* prefs = mock_system_state.mock_prefs();
1054
1055 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1056
1057 // No prefs should be used after a crash.
1058 EXPECT_CALL(*prefs, Exists(_)).Times(0);
1059 EXPECT_CALL(*prefs, SetString(_, _)).Times(0);
1060 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(0);
1061 EXPECT_CALL(*prefs, SetBoolean(_, _)).Times(0);
1062 EXPECT_CALL(*prefs, GetString(_, _)).Times(0);
1063 EXPECT_CALL(*prefs, GetInt64(_, _)).Times(0);
1064 EXPECT_CALL(*prefs, GetBoolean(_, _)).Times(0);
1065
1066 // No metrics are reported after a crash.
1067 EXPECT_CALL(*mock_system_state.mock_metrics_lib(),
1068 SendToUMA(_, _, _, _, _)).Times(0);
1069
1070 // Simulate an update_engine restart without a reboot.
1071 EXPECT_CALL(mock_system_state, system_rebooted())
1072 .WillRepeatedly(Return(false));
1073
1074 payload_state.UpdateEngineStarted();
1075}
1076
Jay Srinivasan53173b92013-05-17 17:13:01 -07001077TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
1078 OmahaResponse response;
1079 MockSystemState mock_system_state;
1080 PayloadState payload_state;
1081
1082 // Pretend that this is an offical build so that the HTTP download policy
1083 // is honored.
1084 EXPECT_CALL(mock_system_state, IsOfficialBuild())
1085 .WillRepeatedly(Return(true));
1086
1087 policy::MockDevicePolicy disable_http_policy;
1088 EXPECT_CALL(mock_system_state, device_policy())
1089 .WillRepeatedly(Return(&disable_http_policy));
Chris Sosaf7d80042013-08-22 16:45:17 -07001090 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1091
1092 // Test with no device policy. Should default to allowing http.
1093 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1094 .WillRepeatedly(Return(false));
1095
1096 // Set the first response.
1097 SetupPayloadStateWith2Urls("Hash8433", true, &payload_state, &response);
1098
1099 // Check that we use the HTTP URL since there is no value set for allowing
1100 // http.
1101 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1102
1103 // Test with device policy not allowing http updates.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001104 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
1105 .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
1106
Chris Sosaf7d80042013-08-22 16:45:17 -07001107 // Reset state and set again.
Jay Srinivasan53173b92013-05-17 17:13:01 -07001108 SetupPayloadStateWith2Urls("Hash8433", false, &payload_state, &response);
1109
1110 // Check that we skip the HTTP URL and use only the HTTPS url.
1111 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1112
1113 // Advance the URL index to 1 by faking an error.
1114 ErrorCode error = kErrorCodeDownloadMetadataSignatureMismatch;
1115 payload_state.UpdateFailed(error);
1116
1117 // Check that we still skip the HTTP URL and use only the HTTPS url.
1118 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1119 EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
1120
1121 // Now, slightly change the response and set it again.
1122 SetupPayloadStateWith2Urls("Hash2399", false, &payload_state, &response);
1123
1124 // Check that we still skip the HTTP URL and use only the HTTPS url.
1125 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1126
1127 // Now, pretend that the HTTP policy is turned on. We want to make sure
1128 // the new policy is honored.
1129 policy::MockDevicePolicy enable_http_policy;
1130 EXPECT_CALL(mock_system_state, device_policy())
1131 .WillRepeatedly(Return(&enable_http_policy));
1132 EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
1133 .WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
1134
1135 // Now, set the same response using the same hash
1136 // so that we can test that the state is reset not because of the
1137 // hash but because of the policy change which results in candidate url
1138 // list change.
1139 SetupPayloadStateWith2Urls("Hash2399", true, &payload_state, &response);
1140
1141 // Check that we use the HTTP URL now and the failure count is reset.
1142 EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
1143 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1144
1145 // Fake a failure and see if we're moving over to the HTTPS url and update
1146 // the URL switch count properly.
1147 payload_state.UpdateFailed(error);
1148 EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
1149 EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
1150 EXPECT_EQ(0, payload_state.GetUrlFailureCount());
1151}
1152
Alex Deymo1c656c42013-06-28 11:02:14 -07001153TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
1154 OmahaResponse response;
1155 response.is_delta_payload = true;
1156 PayloadState payload_state;
1157 MockSystemState mock_system_state;
1158
1159 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1160 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1161
1162 // Simulate a successful download and update.
1163 payload_state.DownloadComplete();
1164
1165 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1166 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
1167 payload_state.UpdateSucceeded();
1168
1169 // Mock the request to a request where the delta was disabled but Omaha sends
1170 // a delta anyway and test again.
1171 OmahaRequestParams params(&mock_system_state);
1172 params.set_delta_okay(false);
1173 mock_system_state.set_request_params(&params);
1174
1175 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1176 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1177
1178 payload_state.DownloadComplete();
1179
1180 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1181 "Installer.PayloadFormat", kPayloadTypeDelta, kNumPayloadTypes));
1182 payload_state.UpdateSucceeded();
1183}
1184
1185TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
1186 OmahaResponse response;
1187 response.is_delta_payload = false;
1188 PayloadState payload_state;
1189 MockSystemState mock_system_state;
1190
1191 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1192 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1193
1194 // Mock the request to a request where the delta was disabled.
1195 OmahaRequestParams params(&mock_system_state);
1196 params.set_delta_okay(false);
1197 mock_system_state.set_request_params(&params);
1198
1199 // Simulate a successful download and update.
1200 payload_state.DownloadComplete();
1201
1202 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1203 "Installer.PayloadFormat", kPayloadTypeForcedFull, kNumPayloadTypes));
1204 payload_state.UpdateSucceeded();
1205}
1206
1207TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
1208 OmahaResponse response;
1209 response.is_delta_payload = false;
1210 PayloadState payload_state;
1211 MockSystemState mock_system_state;
1212
1213 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1214 SetupPayloadStateWith2Urls("Hash6437", true, &payload_state, &response);
1215
Alex Deymo820cc702013-06-28 15:43:46 -07001216 // Mock the request to a request where the delta is enabled, although the
1217 // result is full.
Alex Deymo1c656c42013-06-28 11:02:14 -07001218 OmahaRequestParams params(&mock_system_state);
1219 params.set_delta_okay(true);
1220 mock_system_state.set_request_params(&params);
1221
1222 // Simulate a successful download and update.
1223 payload_state.DownloadComplete();
1224
1225 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
1226 "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
1227 payload_state.UpdateSucceeded();
1228}
1229
Alex Deymo42432912013-07-12 20:21:15 -07001230TEST(PayloadStateTest, RebootAfterUpdateFailedMetric) {
1231 FakeHardware fake_hardware;
1232 MockSystemState mock_system_state;
1233 OmahaResponse response;
1234 PayloadState payload_state;
1235 Prefs prefs;
1236 string temp_dir;
1237
1238 // Setup an environment with persistent prefs across simulated reboots.
1239 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1240 &temp_dir));
1241 prefs.Init(FilePath(temp_dir));
1242 mock_system_state.set_prefs(&prefs);
1243
1244 fake_hardware.SetBootDevice("/dev/sda3");
1245 fake_hardware.SetKernelDeviceOfBootDevice("/dev/sda3", "/dev/sda2");
1246 mock_system_state.set_hardware(&fake_hardware);
1247
1248 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1249 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1250
1251 // Simulate a successful download and update.
1252 payload_state.DownloadComplete();
1253 payload_state.UpdateSucceeded();
1254 payload_state.ExpectRebootInNewVersion("Version:12345678");
1255
1256 // Reboot into the same environment to get an UMA metric with a value of 1.
1257 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1258 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
1259 payload_state.ReportFailedBootIfNeeded();
1260 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1261
1262 // Simulate a second update and reboot into the same environment, this should
1263 // send a value of 2.
1264 payload_state.ExpectRebootInNewVersion("Version:12345678");
1265
1266 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1267 "Installer.RebootToNewPartitionAttempt", 2, _, _, _));
1268 payload_state.ReportFailedBootIfNeeded();
1269 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1270
1271 // Simulate a third failed reboot to new version, but this time for a
1272 // different payload. This should send a value of 1 this time.
1273 payload_state.ExpectRebootInNewVersion("Version:3141592");
1274 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1275 "Installer.RebootToNewPartitionAttempt", 1, _, _, _));
1276 payload_state.ReportFailedBootIfNeeded();
1277 Mock::VerifyAndClearExpectations(mock_system_state.mock_metrics_lib());
1278
1279 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1280}
1281
1282TEST(PayloadStateTest, RebootAfterUpdateSucceed) {
1283 FakeHardware fake_hardware;
1284 MockSystemState mock_system_state;
1285 OmahaResponse response;
1286 PayloadState payload_state;
1287 Prefs prefs;
1288 string temp_dir;
1289
1290 // Setup an environment with persistent prefs across simulated reboots.
1291 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1292 &temp_dir));
1293 prefs.Init(FilePath(temp_dir));
1294 mock_system_state.set_prefs(&prefs);
1295
1296 fake_hardware.SetKernelDeviceOfBootDevice("/dev/sda3", "/dev/sda2");
1297 fake_hardware.SetKernelDeviceOfBootDevice("/dev/sda5", "/dev/sda4");
1298 fake_hardware.SetBootDevice("/dev/sda3");
1299 mock_system_state.set_hardware(&fake_hardware);
1300
1301 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1302 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1303
1304 // Simulate a successful download and update.
1305 payload_state.DownloadComplete();
1306 payload_state.UpdateSucceeded();
1307 payload_state.ExpectRebootInNewVersion("Version:12345678");
1308
1309 // Change the BootDevice to a different one, no metric should be sent.
1310 fake_hardware.SetBootDevice("/dev/sda5");
1311
1312 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1313 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1314 .Times(0);
1315 payload_state.ReportFailedBootIfNeeded();
1316
1317 // A second reboot in eiher partition should not send a metric.
1318 payload_state.ReportFailedBootIfNeeded();
1319 fake_hardware.SetBootDevice("/dev/sda3");
1320 payload_state.ReportFailedBootIfNeeded();
1321
1322 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1323}
1324
1325TEST(PayloadStateTest, RebootAfterCanceledUpdate) {
1326 MockSystemState mock_system_state;
1327 OmahaResponse response;
1328 PayloadState payload_state;
1329 Prefs prefs;
1330 string temp_dir;
1331
1332 // Setup an environment with persistent prefs across simulated reboots.
1333 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1334 &temp_dir));
1335 prefs.Init(FilePath(temp_dir));
1336 mock_system_state.set_prefs(&prefs);
1337
1338 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1339 SetupPayloadStateWith2Urls("Hash3141", true, &payload_state, &response);
1340
1341 // Simulate a successful download and update.
1342 payload_state.DownloadComplete();
1343 payload_state.UpdateSucceeded();
1344 payload_state.ExpectRebootInNewVersion("Version:12345678");
1345
1346 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1347 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1348 .Times(0);
1349
1350 // Cancel the applied update.
1351 payload_state.ResetUpdateStatus();
1352
1353 // Simulate a reboot.
1354 payload_state.ReportFailedBootIfNeeded();
1355
1356 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1357}
1358
1359TEST(PayloadStateTest, UpdateSuccessWithWipedPrefs) {
1360 MockSystemState mock_system_state;
1361 PayloadState payload_state;
1362 Prefs prefs;
1363 string temp_dir;
1364
1365 // Setup an environment with persistent but initially empty prefs.
1366 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateReboot.XXXXXX",
1367 &temp_dir));
1368 prefs.Init(FilePath(temp_dir));
1369 mock_system_state.set_prefs(&prefs);
1370
1371 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1372
1373 EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
1374 "Installer.RebootToNewPartitionAttempt", _, _, _, _))
1375 .Times(0);
1376
1377 // Simulate a reboot in this environment.
1378 payload_state.ReportFailedBootIfNeeded();
1379
1380 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1381}
1382
David Zeuthendcba8092013-08-06 12:16:35 -07001383TEST(PayloadStateTest, DisallowP2PAfterTooManyAttempts) {
1384 OmahaResponse response;
1385 PayloadState payload_state;
1386 MockSystemState mock_system_state;
1387 Prefs prefs;
1388 string temp_dir;
1389
1390 // We need persistent preferences for this test.
1391 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1392 &temp_dir));
1393 prefs.Init(FilePath(temp_dir));
1394
1395 mock_system_state.set_prefs(&prefs);
1396 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1397 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1398
1399 // Should allow exactly kMaxP2PAttempts...
1400 for (int n = 0; n < kMaxP2PAttempts; n++) {
1401 payload_state.P2PNewAttempt();
1402 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1403 }
1404 // ... but not more than that.
1405 payload_state.P2PNewAttempt();
1406 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1407
1408 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1409}
1410
1411TEST(PayloadStateTest, DisallowP2PAfterDeadline) {
1412 OmahaResponse response;
1413 PayloadState payload_state;
1414 MockSystemState mock_system_state;
1415 FakeClock fake_clock;
1416 Prefs prefs;
1417 string temp_dir;
1418
1419 // We need persistent preferences for this test.
1420 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1421 &temp_dir));
1422 prefs.Init(FilePath(temp_dir));
1423
1424 mock_system_state.set_clock(&fake_clock);
1425 mock_system_state.set_prefs(&prefs);
1426 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1427 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1428
1429 // Set the clock to 1 second.
1430 Time epoch = Time::FromInternalValue(1000000);
1431 fake_clock.SetWallclockTime(epoch);
1432
1433 // Do an attempt - this will set the timestamp.
1434 payload_state.P2PNewAttempt();
1435
1436 // Check that the timestamp equals what we just set.
1437 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1438
1439 // Time hasn't advanced - this should work.
1440 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1441
1442 // Set clock to half the deadline - this should work.
1443 fake_clock.SetWallclockTime(epoch +
1444 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds) / 2);
1445 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1446
1447 // Check that the first attempt timestamp hasn't changed just
1448 // because the wall-clock time changed.
1449 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
1450
1451 // Set clock to _just_ before the deadline - this should work.
1452 fake_clock.SetWallclockTime(epoch +
1453 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds - 1));
1454 EXPECT_TRUE(payload_state.P2PAttemptAllowed());
1455
1456 // Set clock to _just_ after the deadline - this should not work.
1457 fake_clock.SetWallclockTime(epoch +
1458 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds + 1));
1459 EXPECT_FALSE(payload_state.P2PAttemptAllowed());
1460
1461 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1462}
1463
1464TEST(PayloadStateTest, P2PStateVarsInitialValue) {
1465 OmahaResponse response;
1466 PayloadState payload_state;
1467 MockSystemState mock_system_state;
1468 Prefs prefs;
1469 string temp_dir;
1470
1471 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1472 &temp_dir));
1473 prefs.Init(FilePath(temp_dir));
1474 mock_system_state.set_prefs(&prefs);
1475 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1476 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1477
1478 Time null_time = Time();
1479 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1480 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1481
1482 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1483}
1484
1485TEST(PayloadStateTest, P2PStateVarsArePersisted) {
1486 OmahaResponse response;
1487 PayloadState payload_state;
1488 MockSystemState mock_system_state;
1489 FakeClock fake_clock;
1490 Prefs prefs;
1491 string temp_dir;
1492
1493 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1494 &temp_dir));
1495 prefs.Init(FilePath(temp_dir));
1496 mock_system_state.set_clock(&fake_clock);
1497 mock_system_state.set_prefs(&prefs);
1498 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1499 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1500
1501 // Set the clock to something known.
1502 Time time = Time::FromInternalValue(12345);
1503 fake_clock.SetWallclockTime(time);
1504
1505 // New p2p attempt - as a side-effect this will update the p2p state vars.
1506 payload_state.P2PNewAttempt();
1507 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1508 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1509
1510 // Now create a new PayloadState and check that it loads the state
1511 // vars correctly.
1512 PayloadState payload_state2;
1513 EXPECT_TRUE(payload_state2.Initialize(&mock_system_state));
1514 EXPECT_EQ(1, payload_state2.GetP2PNumAttempts());
1515 EXPECT_EQ(time, payload_state2.GetP2PFirstAttemptTimestamp());
1516
1517 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1518}
1519
1520TEST(PayloadStateTest, P2PStateVarsAreClearedOnNewResponse) {
1521 OmahaResponse response;
1522 PayloadState payload_state;
1523 MockSystemState mock_system_state;
1524 FakeClock fake_clock;
1525 Prefs prefs;
1526 string temp_dir;
1527
1528 EXPECT_TRUE(utils::MakeTempDirectory("/tmp/PayloadStateP2PTests.XXXXXX",
1529 &temp_dir));
1530 prefs.Init(FilePath(temp_dir));
1531 mock_system_state.set_clock(&fake_clock);
1532 mock_system_state.set_prefs(&prefs);
1533 EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
1534 SetupPayloadStateWith2Urls("Hash8593", true, &payload_state, &response);
1535
1536 // Set the clock to something known.
1537 Time time = Time::FromInternalValue(12345);
1538 fake_clock.SetWallclockTime(time);
1539
1540 // New p2p attempt - as a side-effect this will update the p2p state vars.
1541 payload_state.P2PNewAttempt();
1542 EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
1543 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
1544
1545 // Set a new response...
1546 SetupPayloadStateWith2Urls("Hash9904", true, &payload_state, &response);
1547
1548 // ... and check that it clears the P2P state vars.
1549 Time null_time = Time();
1550 EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
1551 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
1552
1553 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1554}
1555
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001556}