blob: f3b4b999d48a57e19e83ea3d854eb859527a65d7 [file] [log] [blame]
Darin Petkov7ed561b2011-10-04 02:59:03 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
adlr@google.com3defe6a2009-12-04 20:57:17 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <string>
Darin Petkov73058b42010-10-06 16:32:19 -07006
adlr@google.com3defe6a2009-12-04 20:57:17 +00007#include <gtest/gtest.h>
Darin Petkov73058b42010-10-06 16:32:19 -07008
Jay Srinivasand29695d2013-04-08 15:08:05 -07009#include "update_engine/constants.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000010#include "update_engine/omaha_response_handler_action.h"
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080011#include "update_engine/mock_system_state.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000012#include "update_engine/test_utils.h"
13#include "update_engine/utils.h"
14
15using std::string;
Darin Petkov9c096d62010-11-17 14:49:04 -080016using testing::NiceMock;
Darin Petkov73058b42010-10-06 16:32:19 -070017using testing::Return;
adlr@google.com3defe6a2009-12-04 20:57:17 +000018
19namespace chromeos_update_engine {
20
21class OmahaResponseHandlerActionTest : public ::testing::Test {
22 public:
23 // Return true iff the OmahaResponseHandlerAction succeeded.
24 // If out is non-NULL, it's set w/ the response from the action.
Jay Srinivasanae4697c2013-03-18 17:08:08 -070025 bool DoTestCommon(MockSystemState* mock_system_state,
26 const OmahaResponse& in,
27 const string& boot_dev,
28 InstallPlan* out);
Darin Petkov6a5b3222010-07-13 14:55:28 -070029 bool DoTest(const OmahaResponse& in,
adlr@google.com3defe6a2009-12-04 20:57:17 +000030 const string& boot_dev,
31 InstallPlan* out);
32};
33
34class OmahaResponseHandlerActionProcessorDelegate
35 : public ActionProcessorDelegate {
36 public:
37 OmahaResponseHandlerActionProcessorDelegate()
David Zeuthena99981f2013-04-29 13:42:47 -070038 : code_(kErrorCodeError),
Darin Petkovc1a8b422010-07-19 11:34:49 -070039 code_set_(false) {}
adlr@google.com3defe6a2009-12-04 20:57:17 +000040 void ActionCompleted(ActionProcessor* processor,
41 AbstractAction* action,
David Zeuthena99981f2013-04-29 13:42:47 -070042 ErrorCode code) {
adlr@google.com3defe6a2009-12-04 20:57:17 +000043 if (action->Type() == OmahaResponseHandlerAction::StaticType()) {
Darin Petkovc1a8b422010-07-19 11:34:49 -070044 code_ = code;
45 code_set_ = true;
adlr@google.com3defe6a2009-12-04 20:57:17 +000046 }
47 }
David Zeuthena99981f2013-04-29 13:42:47 -070048 ErrorCode code_;
Darin Petkovc1a8b422010-07-19 11:34:49 -070049 bool code_set_;
adlr@google.com3defe6a2009-12-04 20:57:17 +000050};
51
52namespace {
53const string kLongName =
54 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
55 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
56 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
57 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
58 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
59 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
60 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
61 "-the_update_a.b.c.d_DELTA_.tgz";
Chris Sosaaa18e162013-06-20 13:20:30 -070062const string kBadVersion = "don't update me";
adlr@google.com3defe6a2009-12-04 20:57:17 +000063} // namespace {}
64
Jay Srinivasanae4697c2013-03-18 17:08:08 -070065bool OmahaResponseHandlerActionTest::DoTestCommon(
66 MockSystemState* mock_system_state,
67 const OmahaResponse& in,
68 const string& boot_dev,
69 InstallPlan* out) {
adlr@google.com3defe6a2009-12-04 20:57:17 +000070 ActionProcessor processor;
71 OmahaResponseHandlerActionProcessorDelegate delegate;
72 processor.set_delegate(&delegate);
73
Darin Petkov6a5b3222010-07-13 14:55:28 -070074 ObjectFeederAction<OmahaResponse> feeder_action;
adlr@google.com3defe6a2009-12-04 20:57:17 +000075 feeder_action.set_obj(in);
Chris Sosaaa18e162013-06-20 13:20:30 -070076 if (in.update_exists and in.version != kBadVersion) {
Jay Srinivasanae4697c2013-03-18 17:08:08 -070077 EXPECT_CALL(*(mock_system_state->mock_prefs()),
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080078 SetString(kPrefsUpdateCheckResponseHash, in.hash))
Darin Petkov73058b42010-10-06 16:32:19 -070079 .WillOnce(Return(true));
80 }
Jay Srinivasan53173b92013-05-17 17:13:01 -070081
82 string current_url = in.payload_urls.size() ? in.payload_urls[0] : "";
83 EXPECT_CALL(*(mock_system_state->mock_payload_state()), GetCurrentUrl())
84 .WillRepeatedly(Return(current_url));
Chris Sosaaa18e162013-06-20 13:20:30 -070085 EXPECT_CALL(*(mock_system_state->mock_payload_state()), GetRollbackVersion())
86 .WillRepeatedly(Return(kBadVersion));
Jay Srinivasan53173b92013-05-17 17:13:01 -070087
Jay Srinivasanae4697c2013-03-18 17:08:08 -070088 OmahaResponseHandlerAction response_handler_action(mock_system_state);
adlr@google.com3defe6a2009-12-04 20:57:17 +000089 response_handler_action.set_boot_device(boot_dev);
90 BondActions(&feeder_action, &response_handler_action);
91 ObjectCollectorAction<InstallPlan> collector_action;
92 BondActions(&response_handler_action, &collector_action);
93 processor.EnqueueAction(&feeder_action);
94 processor.EnqueueAction(&response_handler_action);
95 processor.EnqueueAction(&collector_action);
96 processor.StartProcessing();
97 EXPECT_TRUE(!processor.IsRunning())
98 << "Update test to handle non-asynch actions";
99 if (out)
100 *out = collector_action.object();
Darin Petkovc1a8b422010-07-19 11:34:49 -0700101 EXPECT_TRUE(delegate.code_set_);
David Zeuthena99981f2013-04-29 13:42:47 -0700102 return delegate.code_ == kErrorCodeSuccess;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000103}
104
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700105bool OmahaResponseHandlerActionTest::DoTest(const OmahaResponse& in,
106 const string& boot_dev,
107 InstallPlan* out) {
108 MockSystemState mock_system_state;
109 return DoTestCommon(&mock_system_state, in, boot_dev, out);
110}
111
adlr@google.com3defe6a2009-12-04 20:57:17 +0000112TEST_F(OmahaResponseHandlerActionTest, SimpleTest) {
Darin Petkov6c118642010-10-21 12:06:30 -0700113 ScopedPathUnlinker deadline_unlinker(
114 OmahaResponseHandlerAction::kDeadlineFile);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000115 {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700116 OmahaResponse in;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000117 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700118 in.version = "a.b.c.d";
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800119 in.payload_urls.push_back("http://foo/the_update_a.b.c.d.tgz");
adlr@google.com3defe6a2009-12-04 20:57:17 +0000120 in.more_info_url = "http://more/info";
121 in.hash = "HASH+";
122 in.size = 12;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000123 in.prompt = false;
Darin Petkov6c118642010-10-21 12:06:30 -0700124 in.deadline = "20101020";
adlr@google.com3defe6a2009-12-04 20:57:17 +0000125 InstallPlan install_plan;
Darin Petkov7ed561b2011-10-04 02:59:03 -0700126 EXPECT_TRUE(DoTest(in, "/dev/sda3", &install_plan));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800127 EXPECT_EQ(in.payload_urls[0], install_plan.download_url);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700128 EXPECT_EQ(in.hash, install_plan.payload_hash);
Andrew de los Reyesf98bff82010-05-06 13:33:25 -0700129 EXPECT_EQ("/dev/sda5", install_plan.install_path);
Darin Petkov6c118642010-10-21 12:06:30 -0700130 string deadline;
Gilad Arnold19a45f02012-07-19 12:36:10 -0700131 EXPECT_TRUE(utils::ReadFile(
Darin Petkov6c118642010-10-21 12:06:30 -0700132 OmahaResponseHandlerAction::kDeadlineFile,
133 &deadline));
134 EXPECT_EQ("20101020", deadline);
135 struct stat deadline_stat;
136 EXPECT_EQ(0, stat(OmahaResponseHandlerAction::kDeadlineFile,
137 &deadline_stat));
138 EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH,
139 deadline_stat.st_mode);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000140 }
141 {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700142 OmahaResponse in;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000143 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700144 in.version = "a.b.c.d";
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800145 in.payload_urls.push_back("http://foo/the_update_a.b.c.d.tgz");
adlr@google.com3defe6a2009-12-04 20:57:17 +0000146 in.more_info_url = "http://more/info";
147 in.hash = "HASHj+";
148 in.size = 12;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000149 in.prompt = true;
150 InstallPlan install_plan;
Darin Petkov7ed561b2011-10-04 02:59:03 -0700151 EXPECT_TRUE(DoTest(in, "/dev/sda5", &install_plan));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800152 EXPECT_EQ(in.payload_urls[0], install_plan.download_url);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700153 EXPECT_EQ(in.hash, install_plan.payload_hash);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000154 EXPECT_EQ("/dev/sda3", install_plan.install_path);
Darin Petkov6c118642010-10-21 12:06:30 -0700155 string deadline;
Gilad Arnold19a45f02012-07-19 12:36:10 -0700156 EXPECT_TRUE(utils::ReadFile(
Darin Petkov6c118642010-10-21 12:06:30 -0700157 OmahaResponseHandlerAction::kDeadlineFile,
158 &deadline) && deadline.empty());
adlr@google.com3defe6a2009-12-04 20:57:17 +0000159 }
160 {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700161 OmahaResponse in;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000162 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700163 in.version = "a.b.c.d";
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800164 in.payload_urls.push_back(kLongName);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000165 in.more_info_url = "http://more/info";
166 in.hash = "HASHj+";
167 in.size = 12;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000168 in.prompt = true;
Darin Petkov6c118642010-10-21 12:06:30 -0700169 in.deadline = "some-deadline";
adlr@google.com3defe6a2009-12-04 20:57:17 +0000170 InstallPlan install_plan;
Darin Petkov7ed561b2011-10-04 02:59:03 -0700171 EXPECT_TRUE(DoTest(in, "/dev/sda3", &install_plan));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800172 EXPECT_EQ(in.payload_urls[0], install_plan.download_url);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700173 EXPECT_EQ(in.hash, install_plan.payload_hash);
Andrew de los Reyesf98bff82010-05-06 13:33:25 -0700174 EXPECT_EQ("/dev/sda5", install_plan.install_path);
Darin Petkov6c118642010-10-21 12:06:30 -0700175 string deadline;
Gilad Arnold19a45f02012-07-19 12:36:10 -0700176 EXPECT_TRUE(utils::ReadFile(
Darin Petkov6c118642010-10-21 12:06:30 -0700177 OmahaResponseHandlerAction::kDeadlineFile,
178 &deadline));
179 EXPECT_EQ("some-deadline", deadline);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000180 }
181}
182
183TEST_F(OmahaResponseHandlerActionTest, NoUpdatesTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700184 OmahaResponse in;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000185 in.update_exists = false;
186 InstallPlan install_plan;
Darin Petkov7ed561b2011-10-04 02:59:03 -0700187 EXPECT_FALSE(DoTest(in, "/dev/sda1", &install_plan));
adlr@google.com3defe6a2009-12-04 20:57:17 +0000188 EXPECT_EQ("", install_plan.download_url);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700189 EXPECT_EQ("", install_plan.payload_hash);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000190 EXPECT_EQ("", install_plan.install_path);
191}
192
Chris Sosaaa18e162013-06-20 13:20:30 -0700193TEST_F(OmahaResponseHandlerActionTest, RollbackVersionTest) {
194 string version_ok = "124.0.0";
195
196 InstallPlan install_plan;
197 OmahaResponse in;
198 in.update_exists = true;
199 in.version = kBadVersion;
200 in.payload_urls.push_back("http://foo/the_update_a.b.c.d.tgz");
201 in.more_info_url = "http://more/info";
202 in.hash = "HASHj+";
203 in.size = 12;
204 in.prompt = true;
205
206 // Version is blacklisted for first call so no update.
207 EXPECT_FALSE(DoTest(in, "/dev/sda5", &install_plan));
208 EXPECT_EQ("", install_plan.download_url);
209 EXPECT_EQ("", install_plan.payload_hash);
210 EXPECT_EQ("", install_plan.install_path);
211
212 // Version isn't blacklisted.
213 in.version = version_ok;
214 EXPECT_TRUE(DoTest(in, "/dev/sda5", &install_plan));
215 EXPECT_EQ(in.payload_urls[0], install_plan.download_url);
216}
217
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800218TEST_F(OmahaResponseHandlerActionTest, HashChecksForHttpTest) {
219 OmahaResponse in;
220 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700221 in.version = "a.b.c.d";
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800222 in.payload_urls.push_back("http://test.should/need/hash.checks.signed");
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800223 in.more_info_url = "http://more/info";
224 in.hash = "HASHj+";
225 in.size = 12;
226 InstallPlan install_plan;
227 EXPECT_TRUE(DoTest(in, "/dev/sda5", &install_plan));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800228 EXPECT_EQ(in.payload_urls[0], install_plan.download_url);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800229 EXPECT_EQ(in.hash, install_plan.payload_hash);
230 EXPECT_TRUE(install_plan.hash_checks_mandatory);
231}
232
233TEST_F(OmahaResponseHandlerActionTest, HashChecksForHttpsTest) {
234 OmahaResponse in;
235 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700236 in.version = "a.b.c.d";
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800237 in.payload_urls.push_back("https://test.should.not/need/hash.checks.signed");
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800238 in.more_info_url = "http://more/info";
239 in.hash = "HASHj+";
240 in.size = 12;
241 InstallPlan install_plan;
242 EXPECT_TRUE(DoTest(in, "/dev/sda5", &install_plan));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800243 EXPECT_EQ(in.payload_urls[0], install_plan.download_url);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800244 EXPECT_EQ(in.hash, install_plan.payload_hash);
245 EXPECT_FALSE(install_plan.hash_checks_mandatory);
246}
247
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800248TEST_F(OmahaResponseHandlerActionTest, HashChecksForBothHttpAndHttpsTest) {
249 OmahaResponse in;
250 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700251 in.version = "a.b.c.d";
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800252 in.payload_urls.push_back("http://test.should.still/need/hash.checks");
253 in.payload_urls.push_back("https://test.should.still/need/hash.checks");
254 in.more_info_url = "http://more/info";
255 in.hash = "HASHj+";
256 in.size = 12;
257 InstallPlan install_plan;
258 EXPECT_TRUE(DoTest(in, "/dev/sda5", &install_plan));
259 EXPECT_EQ(in.payload_urls[0], install_plan.download_url);
260 EXPECT_EQ(in.hash, install_plan.payload_hash);
261 EXPECT_TRUE(install_plan.hash_checks_mandatory);
262}
263
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700264TEST_F(OmahaResponseHandlerActionTest, ChangeToMoreStableChannelTest) {
265 OmahaResponse in;
266 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700267 in.version = "a.b.c.d";
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700268 in.payload_urls.push_back("https://MoreStableChannelTest");
269 in.more_info_url = "http://more/info";
270 in.hash = "HASHjk";
271 in.size = 15;
272
273 const string kTestDir = "omaha_response_handler_action-test";
274 ASSERT_EQ(0, System(string("mkdir -p ") + kTestDir + "/etc"));
275 ASSERT_EQ(0, System(string("mkdir -p ") + kTestDir +
Chris Sosabe45bef2013-04-09 18:25:12 -0700276 kStatefulPartition + "/etc"));
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700277 ASSERT_TRUE(WriteFileString(
278 kTestDir + "/etc/lsb-release",
279 "CHROMEOS_RELEASE_TRACK=canary-channel\n"));
280 ASSERT_TRUE(WriteFileString(
Chris Sosabe45bef2013-04-09 18:25:12 -0700281 kTestDir + kStatefulPartition + "/etc/lsb-release",
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700282 "CHROMEOS_IS_POWERWASH_ALLOWED=true\n"
283 "CHROMEOS_RELEASE_TRACK=stable-channel\n"));
284
285 MockSystemState mock_system_state;
286 OmahaRequestParams params(&mock_system_state);
287 params.set_root(string("./") + kTestDir);
288 params.SetLockDown(false);
289 params.Init("1.2.3.4", "", 0);
290 EXPECT_EQ("canary-channel", params.current_channel());
291 EXPECT_EQ("stable-channel", params.target_channel());
292 EXPECT_TRUE(params.to_more_stable_channel());
293 EXPECT_TRUE(params.is_powerwash_allowed());
294
295 mock_system_state.set_request_params(&params);
296 InstallPlan install_plan;
297 EXPECT_TRUE(DoTestCommon(&mock_system_state, in, "/dev/sda5", &install_plan));
298 EXPECT_TRUE(install_plan.powerwash_required);
299}
300
301TEST_F(OmahaResponseHandlerActionTest, ChangeToLessStableChannelTest) {
302 OmahaResponse in;
303 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700304 in.version = "a.b.c.d";
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700305 in.payload_urls.push_back("https://LessStableChannelTest");
306 in.more_info_url = "http://more/info";
307 in.hash = "HASHjk";
308 in.size = 15;
309
310 const string kTestDir = "omaha_response_handler_action-test";
311 ASSERT_EQ(0, System(string("mkdir -p ") + kTestDir + "/etc"));
312 ASSERT_EQ(0, System(string("mkdir -p ") + kTestDir +
Chris Sosabe45bef2013-04-09 18:25:12 -0700313 kStatefulPartition + "/etc"));
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700314 ASSERT_TRUE(WriteFileString(
315 kTestDir + "/etc/lsb-release",
316 "CHROMEOS_RELEASE_TRACK=stable-channel\n"));
317 ASSERT_TRUE(WriteFileString(
Chris Sosabe45bef2013-04-09 18:25:12 -0700318 kTestDir + kStatefulPartition + "/etc/lsb-release",
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700319 "CHROMEOS_RELEASE_TRACK=canary-channel\n"));
320
321 MockSystemState mock_system_state;
322 OmahaRequestParams params(&mock_system_state);
323 params.set_root(string("./") + kTestDir);
324 params.SetLockDown(false);
325 params.Init("5.6.7.8", "", 0);
326 EXPECT_EQ("stable-channel", params.current_channel());
327 params.SetTargetChannel("canary-channel", false);
328 EXPECT_EQ("canary-channel", params.target_channel());
329 EXPECT_FALSE(params.to_more_stable_channel());
330 EXPECT_FALSE(params.is_powerwash_allowed());
331
332 mock_system_state.set_request_params(&params);
333 InstallPlan install_plan;
334 EXPECT_TRUE(DoTestCommon(&mock_system_state, in, "/dev/sda5", &install_plan));
335 EXPECT_FALSE(install_plan.powerwash_required);
336}
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800337
adlr@google.com3defe6a2009-12-04 20:57:17 +0000338} // namespace chromeos_update_engine