blob: e4d05f4bf8f90139106ce502697f0d7850a358aa [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2011 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
adlr@google.com3defe6a2009-12-04 20:57:17 +000016
Alex Deymoaab50e32014-11-10 19:55:35 -080017#include "update_engine/omaha_response_handler_action.h"
18
Aaron Woodc73fdc12017-12-06 11:09:15 -080019#include <memory>
adlr@google.com3defe6a2009-12-04 20:57:17 +000020#include <string>
Amin Hassanid3f4bea2018-04-30 14:52:40 -070021#include <utility>
Darin Petkov73058b42010-10-06 16:32:19 -070022
Alex Deymo110e0302015-10-19 20:35:21 -070023#include <base/files/file_util.h>
Sen Jiang297e5832016-03-17 14:45:51 -070024#include <base/files/scoped_temp_dir.h>
Aaron Wood23bd3392017-10-06 14:48:25 -070025#include <brillo/message_loops/fake_message_loop.h>
adlr@google.com3defe6a2009-12-04 20:57:17 +000026#include <gtest/gtest.h>
Darin Petkov73058b42010-10-06 16:32:19 -070027
Alex Deymo39910dc2015-11-09 17:04:30 -080028#include "update_engine/common/constants.h"
29#include "update_engine/common/platform_constants.h"
30#include "update_engine/common/test_utils.h"
31#include "update_engine/common/utils.h"
Gilad Arnold5bb4c902014-04-10 12:32:13 -070032#include "update_engine/fake_system_state.h"
Gilad Arnold74b5f552014-10-07 08:17:16 -070033#include "update_engine/mock_payload_state.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080034#include "update_engine/payload_consumer/payload_constants.h"
Aaron Wood23bd3392017-10-06 14:48:25 -070035#include "update_engine/update_manager/mock_policy.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000036
Alex Deymo10875d92014-11-10 21:52:57 -080037using chromeos_update_engine::test_utils::System;
38using chromeos_update_engine::test_utils::WriteFileString;
Aaron Wood23bd3392017-10-06 14:48:25 -070039using chromeos_update_manager::EvalStatus;
40using chromeos_update_manager::FakeUpdateManager;
41using chromeos_update_manager::MockPolicy;
adlr@google.com3defe6a2009-12-04 20:57:17 +000042using std::string;
Aaron Woodc73fdc12017-12-06 11:09:15 -080043using testing::_;
Aaron Wood23bd3392017-10-06 14:48:25 -070044using testing::DoAll;
Darin Petkov73058b42010-10-06 16:32:19 -070045using testing::Return;
Aaron Wood23bd3392017-10-06 14:48:25 -070046using testing::SetArgPointee;
adlr@google.com3defe6a2009-12-04 20:57:17 +000047
48namespace chromeos_update_engine {
49
adlr@google.com3defe6a2009-12-04 20:57:17 +000050class OmahaResponseHandlerActionProcessorDelegate
51 : public ActionProcessorDelegate {
52 public:
53 OmahaResponseHandlerActionProcessorDelegate()
Aaron Woodc73fdc12017-12-06 11:09:15 -080054 : code_(ErrorCode::kError), code_set_(false) {}
adlr@google.com3defe6a2009-12-04 20:57:17 +000055 void ActionCompleted(ActionProcessor* processor,
56 AbstractAction* action,
David Zeuthena99981f2013-04-29 13:42:47 -070057 ErrorCode code) {
adlr@google.com3defe6a2009-12-04 20:57:17 +000058 if (action->Type() == OmahaResponseHandlerAction::StaticType()) {
Amin Hassanid3f4bea2018-04-30 14:52:40 -070059 auto response_handler_action =
60 static_cast<OmahaResponseHandlerAction*>(action);
Darin Petkovc1a8b422010-07-19 11:34:49 -070061 code_ = code;
62 code_set_ = true;
Amin Hassanid3f4bea2018-04-30 14:52:40 -070063 response_handler_action_install_plan_.reset(
64 new InstallPlan(response_handler_action->install_plan_));
65 } else if (action->Type() ==
66 ObjectCollectorAction<InstallPlan>::StaticType()) {
67 auto collector_action =
68 static_cast<ObjectCollectorAction<InstallPlan>*>(action);
69 collector_action_install_plan_.reset(
70 new InstallPlan(collector_action->object()));
adlr@google.com3defe6a2009-12-04 20:57:17 +000071 }
72 }
David Zeuthena99981f2013-04-29 13:42:47 -070073 ErrorCode code_;
Darin Petkovc1a8b422010-07-19 11:34:49 -070074 bool code_set_;
Amin Hassanid3f4bea2018-04-30 14:52:40 -070075 std::unique_ptr<InstallPlan> collector_action_install_plan_;
76 std::unique_ptr<InstallPlan> response_handler_action_install_plan_;
77};
78
adlr@google.com3defe6a2009-12-04 20:57:17 +000079class OmahaResponseHandlerActionTest : public ::testing::Test {
80 protected:
81 void SetUp() override {
82 FakeBootControl* fake_boot_control = fake_system_state_.fake_boot_control();
83 fake_boot_control->SetPartitionDevice(
Tudor Brindusdda79e22018-06-28 18:03:21 -070084 kPartitionNameKernel, 0, "/dev/sdz2");
adlr@google.com3defe6a2009-12-04 20:57:17 +000085 fake_boot_control->SetPartitionDevice(
Tudor Brindusdda79e22018-06-28 18:03:21 -070086 kPartitionNameRoot, 0, "/dev/sdz3");
adlr@google.com3defe6a2009-12-04 20:57:17 +000087 fake_boot_control->SetPartitionDevice(
Tudor Brindusdda79e22018-06-28 18:03:21 -070088 kPartitionNameKernel, 1, "/dev/sdz4");
adlr@google.com3defe6a2009-12-04 20:57:17 +000089 fake_boot_control->SetPartitionDevice(
Tudor Brindusdda79e22018-06-28 18:03:21 -070090 kPartitionNameRoot, 1, "/dev/sdz5");
adlr@google.com3defe6a2009-12-04 20:57:17 +000091 }
92
93 // Return true iff the OmahaResponseHandlerAction succeeded.
94 // If out is non-null, it's set w/ the response from the action.
95 bool DoTest(const OmahaResponse& in,
96 const string& deadline_file,
97 InstallPlan* out);
98
Amin Hassanid3f4bea2018-04-30 14:52:40 -070099 // Delegate passed to the ActionProcessor.
100 OmahaResponseHandlerActionProcessorDelegate delegate_;
101
adlr@google.com3defe6a2009-12-04 20:57:17 +0000102 // Captures the action's result code, for tests that need to directly verify
103 // it in non-success cases.
104 ErrorCode action_result_code_;
105
106 FakeSystemState fake_system_state_;
107 // "Hash+"
108 const brillo::Blob expected_hash_ = {0x48, 0x61, 0x73, 0x68, 0x2b};
adlr@google.com3defe6a2009-12-04 20:57:17 +0000109};
110
111namespace {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700112const char* const kLongName =
adlr@google.com3defe6a2009-12-04 20:57:17 +0000113 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
114 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
115 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
116 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
117 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
118 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
119 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
120 "-the_update_a.b.c.d_DELTA_.tgz";
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700121const char* const kBadVersion = "don't update me";
Sen Jiang2703ef42017-03-16 13:36:21 -0700122const char* const kPayloadHashHex = "486173682b";
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700123} // namespace
adlr@google.com3defe6a2009-12-04 20:57:17 +0000124
Aaron Woodc73fdc12017-12-06 11:09:15 -0800125bool OmahaResponseHandlerActionTest::DoTest(const OmahaResponse& in,
126 const string& test_deadline_file,
127 InstallPlan* out) {
Aaron Wood23bd3392017-10-06 14:48:25 -0700128 brillo::FakeMessageLoop loop(nullptr);
129 loop.SetAsCurrent();
adlr@google.com3defe6a2009-12-04 20:57:17 +0000130 ActionProcessor processor;
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700131 processor.set_delegate(&delegate_);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000132
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700133 auto feeder_action = std::make_unique<ObjectFeederAction<OmahaResponse>>();
134 feeder_action->set_obj(in);
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700135 if (in.update_exists && in.version != kBadVersion) {
Sen Jiang0affc2c2017-02-10 15:55:05 -0800136 string expected_hash;
137 for (const auto& package : in.packages)
138 expected_hash += package.hash + ":";
Alex Deymo763e7db2015-08-27 21:08:08 -0700139 EXPECT_CALL(*(fake_system_state_.mock_prefs()),
Sen Jiang0affc2c2017-02-10 15:55:05 -0800140 SetString(kPrefsUpdateCheckResponseHash, expected_hash))
Darin Petkov73058b42010-10-06 16:32:19 -0700141 .WillOnce(Return(true));
Alex Deymo85616652015-10-15 18:48:31 -0700142
143 int slot = 1 - fake_system_state_.fake_boot_control()->GetCurrentSlot();
144 string key = kPrefsChannelOnSlotPrefix + std::to_string(slot);
145 EXPECT_CALL(*(fake_system_state_.mock_prefs()), SetString(key, testing::_))
146 .WillOnce(Return(true));
Darin Petkov73058b42010-10-06 16:32:19 -0700147 }
Jay Srinivasan53173b92013-05-17 17:13:01 -0700148
Sen Jiang0affc2c2017-02-10 15:55:05 -0800149 string current_url = in.packages.size() ? in.packages[0].payload_urls[0] : "";
Alex Deymo763e7db2015-08-27 21:08:08 -0700150 EXPECT_CALL(*(fake_system_state_.mock_payload_state()), GetCurrentUrl())
Jay Srinivasan53173b92013-05-17 17:13:01 -0700151 .WillRepeatedly(Return(current_url));
152
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700153 auto response_handler_action =
154 std::make_unique<OmahaResponseHandlerAction>(&fake_system_state_);
155 if (!test_deadline_file.empty())
156 response_handler_action->deadline_file_ = test_deadline_file;
157
158 auto collector_action =
159 std::make_unique<ObjectCollectorAction<InstallPlan>>();
160
161 BondActions(feeder_action.get(), response_handler_action.get());
162 BondActions(response_handler_action.get(), collector_action.get());
163 processor.EnqueueAction(std::move(feeder_action));
164 processor.EnqueueAction(std::move(response_handler_action));
165 processor.EnqueueAction(std::move(collector_action));
adlr@google.com3defe6a2009-12-04 20:57:17 +0000166 processor.StartProcessing();
167 EXPECT_TRUE(!processor.IsRunning())
Alex Vakulenko072359c2014-07-18 11:41:07 -0700168 << "Update test to handle non-async actions";
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700169
170 if (out && delegate_.collector_action_install_plan_)
171 *out = *delegate_.collector_action_install_plan_;
172
173 EXPECT_TRUE(delegate_.code_set_);
174 action_result_code_ = delegate_.code_;
175 return delegate_.code_ == ErrorCode::kSuccess;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000176}
177
178TEST_F(OmahaResponseHandlerActionTest, SimpleTest) {
Sen Jiang0779a152018-07-02 17:34:56 -0700179 test_utils::ScopedTempFile test_deadline_file(
180 "omaha_response_handler_action_unittest-XXXXXX");
adlr@google.com3defe6a2009-12-04 20:57:17 +0000181 {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700182 OmahaResponse in;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000183 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700184 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800185 in.packages.push_back(
186 {.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
187 .size = 12,
188 .hash = kPayloadHashHex});
adlr@google.com3defe6a2009-12-04 20:57:17 +0000189 in.more_info_url = "http://more/info";
adlr@google.com3defe6a2009-12-04 20:57:17 +0000190 in.prompt = false;
Darin Petkov6c118642010-10-21 12:06:30 -0700191 in.deadline = "20101020";
adlr@google.com3defe6a2009-12-04 20:57:17 +0000192 InstallPlan install_plan;
Sen Jiang0779a152018-07-02 17:34:56 -0700193 EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800194 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
195 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Alex Deymo80f70ff2016-02-10 16:08:11 -0800196 EXPECT_EQ(1U, install_plan.target_slot);
Darin Petkov6c118642010-10-21 12:06:30 -0700197 string deadline;
Sen Jiang0779a152018-07-02 17:34:56 -0700198 EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline));
Darin Petkov6c118642010-10-21 12:06:30 -0700199 EXPECT_EQ("20101020", deadline);
200 struct stat deadline_stat;
Sen Jiang0779a152018-07-02 17:34:56 -0700201 EXPECT_EQ(0, stat(test_deadline_file.path().c_str(), &deadline_stat));
Alex Deymo80f70ff2016-02-10 16:08:11 -0800202 EXPECT_EQ(
203 static_cast<mode_t>(S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),
204 deadline_stat.st_mode);
Chris Sosafb1020e2013-07-29 17:27:33 -0700205 EXPECT_EQ(in.version, install_plan.version);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000206 }
207 {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700208 OmahaResponse in;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000209 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700210 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800211 in.packages.push_back(
212 {.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
213 .size = 12,
214 .hash = kPayloadHashHex});
adlr@google.com3defe6a2009-12-04 20:57:17 +0000215 in.more_info_url = "http://more/info";
adlr@google.com3defe6a2009-12-04 20:57:17 +0000216 in.prompt = true;
217 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700218 // Set the other slot as current.
219 fake_system_state_.fake_boot_control()->SetCurrentSlot(1);
Sen Jiang0779a152018-07-02 17:34:56 -0700220 EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800221 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
222 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Alex Deymo80f70ff2016-02-10 16:08:11 -0800223 EXPECT_EQ(0U, install_plan.target_slot);
Darin Petkov6c118642010-10-21 12:06:30 -0700224 string deadline;
Sen Jiang0779a152018-07-02 17:34:56 -0700225 EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline) &&
Gilad Arnold4dbd47e2013-07-22 05:39:26 -0700226 deadline.empty());
Chris Sosafb1020e2013-07-29 17:27:33 -0700227 EXPECT_EQ(in.version, install_plan.version);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000228 }
229 {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700230 OmahaResponse in;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000231 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700232 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800233 in.packages.push_back(
234 {.payload_urls = {kLongName}, .size = 12, .hash = kPayloadHashHex});
adlr@google.com3defe6a2009-12-04 20:57:17 +0000235 in.more_info_url = "http://more/info";
adlr@google.com3defe6a2009-12-04 20:57:17 +0000236 in.prompt = true;
Darin Petkov6c118642010-10-21 12:06:30 -0700237 in.deadline = "some-deadline";
adlr@google.com3defe6a2009-12-04 20:57:17 +0000238 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700239 fake_system_state_.fake_boot_control()->SetCurrentSlot(0);
Marton Hunyadye58bddb2018-04-10 20:27:26 +0200240 // Because rollback happened, the deadline shouldn't be written into the
241 // file.
242 EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
243 GetRollbackHappened())
244 .WillOnce(Return(true));
Sen Jiang456853f2018-08-13 15:41:43 -0700245 EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
Marton Hunyadye58bddb2018-04-10 20:27:26 +0200246 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
247 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
248 EXPECT_EQ(1U, install_plan.target_slot);
249 string deadline;
Sen Jiang456853f2018-08-13 15:41:43 -0700250 EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline));
Marton Hunyadye58bddb2018-04-10 20:27:26 +0200251 EXPECT_TRUE(deadline.empty());
252 EXPECT_EQ(in.version, install_plan.version);
253 }
254 {
255 OmahaResponse in;
256 in.update_exists = true;
257 in.version = "a.b.c.d";
258 in.packages.push_back(
259 {.payload_urls = {kLongName}, .size = 12, .hash = kPayloadHashHex});
260 in.more_info_url = "http://more/info";
261 in.prompt = true;
262 in.deadline = "some-deadline";
263 InstallPlan install_plan;
264 fake_system_state_.fake_boot_control()->SetCurrentSlot(0);
265 EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
266 GetRollbackHappened())
267 .WillOnce(Return(false));
Sen Jiang0779a152018-07-02 17:34:56 -0700268 EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800269 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
270 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Alex Deymo80f70ff2016-02-10 16:08:11 -0800271 EXPECT_EQ(1U, install_plan.target_slot);
Darin Petkov6c118642010-10-21 12:06:30 -0700272 string deadline;
Sen Jiang0779a152018-07-02 17:34:56 -0700273 EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline));
Darin Petkov6c118642010-10-21 12:06:30 -0700274 EXPECT_EQ("some-deadline", deadline);
Chris Sosafb1020e2013-07-29 17:27:33 -0700275 EXPECT_EQ(in.version, install_plan.version);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000276 }
277}
278
279TEST_F(OmahaResponseHandlerActionTest, NoUpdatesTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700280 OmahaResponse in;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000281 in.update_exists = false;
282 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700283 EXPECT_FALSE(DoTest(in, "", &install_plan));
Alex Deymoe5e5fe92015-10-05 09:28:19 -0700284 EXPECT_TRUE(install_plan.partitions.empty());
adlr@google.com3defe6a2009-12-04 20:57:17 +0000285}
286
Sen Jiang0affc2c2017-02-10 15:55:05 -0800287TEST_F(OmahaResponseHandlerActionTest, MultiPackageTest) {
288 OmahaResponse in;
289 in.update_exists = true;
290 in.version = "a.b.c.d";
291 in.packages.push_back({.payload_urls = {"http://package/1"},
292 .size = 1,
293 .hash = kPayloadHashHex});
294 in.packages.push_back({.payload_urls = {"http://package/2"},
295 .size = 2,
296 .hash = kPayloadHashHex});
297 in.more_info_url = "http://more/info";
298 InstallPlan install_plan;
299 EXPECT_TRUE(DoTest(in, "", &install_plan));
300 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
301 EXPECT_EQ(2u, install_plan.payloads.size());
302 EXPECT_EQ(in.packages[0].size, install_plan.payloads[0].size);
303 EXPECT_EQ(in.packages[1].size, install_plan.payloads[1].size);
304 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
305 EXPECT_EQ(expected_hash_, install_plan.payloads[1].hash);
306 EXPECT_EQ(in.version, install_plan.version);
307}
308
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800309TEST_F(OmahaResponseHandlerActionTest, HashChecksForHttpTest) {
310 OmahaResponse in;
311 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700312 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800313 in.packages.push_back(
314 {.payload_urls = {"http://test.should/need/hash.checks.signed"},
315 .size = 12,
316 .hash = kPayloadHashHex});
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800317 in.more_info_url = "http://more/info";
David Pursell02c18642014-11-06 11:26:11 -0800318 // Hash checks are always skipped for non-official update URLs.
Alex Deymo763e7db2015-08-27 21:08:08 -0700319 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
David Pursell02c18642014-11-06 11:26:11 -0800320 IsUpdateUrlOfficial())
321 .WillRepeatedly(Return(true));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800322 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700323 EXPECT_TRUE(DoTest(in, "", &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800324 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
325 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800326 EXPECT_TRUE(install_plan.hash_checks_mandatory);
Chris Sosafb1020e2013-07-29 17:27:33 -0700327 EXPECT_EQ(in.version, install_plan.version);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800328}
329
David Pursell02c18642014-11-06 11:26:11 -0800330TEST_F(OmahaResponseHandlerActionTest, HashChecksForUnofficialUpdateUrl) {
331 OmahaResponse in;
332 in.update_exists = true;
333 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800334 in.packages.push_back(
335 {.payload_urls = {"http://url.normally/needs/hash.checks.signed"},
336 .size = 12,
337 .hash = kPayloadHashHex});
David Pursell02c18642014-11-06 11:26:11 -0800338 in.more_info_url = "http://more/info";
Alex Deymo763e7db2015-08-27 21:08:08 -0700339 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
David Pursell02c18642014-11-06 11:26:11 -0800340 IsUpdateUrlOfficial())
341 .WillRepeatedly(Return(false));
342 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700343 EXPECT_TRUE(DoTest(in, "", &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800344 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
345 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
David Pursell02c18642014-11-06 11:26:11 -0800346 EXPECT_FALSE(install_plan.hash_checks_mandatory);
347 EXPECT_EQ(in.version, install_plan.version);
348}
349
David Pursell907b4fa2015-01-27 10:27:38 -0800350TEST_F(OmahaResponseHandlerActionTest,
351 HashChecksForOfficialUrlUnofficialBuildTest) {
352 // Official URLs for unofficial builds (dev/test images) don't require hash.
353 OmahaResponse in;
354 in.update_exists = true;
355 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800356 in.packages.push_back(
357 {.payload_urls = {"http://url.normally/needs/hash.checks.signed"},
358 .size = 12,
359 .hash = kPayloadHashHex});
David Pursell907b4fa2015-01-27 10:27:38 -0800360 in.more_info_url = "http://more/info";
Alex Deymo763e7db2015-08-27 21:08:08 -0700361 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
David Pursell907b4fa2015-01-27 10:27:38 -0800362 IsUpdateUrlOfficial())
363 .WillRepeatedly(Return(true));
Alex Deymo763e7db2015-08-27 21:08:08 -0700364 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
David Pursell907b4fa2015-01-27 10:27:38 -0800365 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700366 EXPECT_TRUE(DoTest(in, "", &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800367 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
368 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
David Pursell907b4fa2015-01-27 10:27:38 -0800369 EXPECT_FALSE(install_plan.hash_checks_mandatory);
370 EXPECT_EQ(in.version, install_plan.version);
371}
372
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800373TEST_F(OmahaResponseHandlerActionTest, HashChecksForHttpsTest) {
374 OmahaResponse in;
375 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700376 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800377 in.packages.push_back(
378 {.payload_urls = {"https://test.should/need/hash.checks.signed"},
379 .size = 12,
380 .hash = kPayloadHashHex});
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800381 in.more_info_url = "http://more/info";
Alex Deymo763e7db2015-08-27 21:08:08 -0700382 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
David Pursell02c18642014-11-06 11:26:11 -0800383 IsUpdateUrlOfficial())
384 .WillRepeatedly(Return(true));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800385 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700386 EXPECT_TRUE(DoTest(in, "", &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800387 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
388 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Sen Jiang81c705b2018-10-04 14:15:05 -0700389 EXPECT_TRUE(install_plan.hash_checks_mandatory);
Chris Sosafb1020e2013-07-29 17:27:33 -0700390 EXPECT_EQ(in.version, install_plan.version);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800391}
392
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800393TEST_F(OmahaResponseHandlerActionTest, HashChecksForBothHttpAndHttpsTest) {
394 OmahaResponse in;
395 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700396 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800397 in.packages.push_back(
398 {.payload_urls = {"http://test.should.still/need/hash.checks",
399 "https://test.should.still/need/hash.checks"},
400 .size = 12,
401 .hash = kPayloadHashHex});
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800402 in.more_info_url = "http://more/info";
Alex Deymo763e7db2015-08-27 21:08:08 -0700403 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
David Pursell02c18642014-11-06 11:26:11 -0800404 IsUpdateUrlOfficial())
405 .WillRepeatedly(Return(true));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800406 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700407 EXPECT_TRUE(DoTest(in, "", &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800408 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
409 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800410 EXPECT_TRUE(install_plan.hash_checks_mandatory);
Chris Sosafb1020e2013-07-29 17:27:33 -0700411 EXPECT_EQ(in.version, install_plan.version);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800412}
413
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700414TEST_F(OmahaResponseHandlerActionTest, ChangeToMoreStableChannelTest) {
415 OmahaResponse in;
416 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700417 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800418 in.packages.push_back({.payload_urls = {"https://MoreStableChannelTest"},
419 .size = 1,
420 .hash = kPayloadHashHex});
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700421 in.more_info_url = "http://more/info";
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700422
Gilad Arnoldeff87cc2013-07-22 18:32:09 -0700423 // Create a uniquely named test directory.
Sen Jiang297e5832016-03-17 14:45:51 -0700424 base::ScopedTempDir tempdir;
425 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700426
Alex Deymo763e7db2015-08-27 21:08:08 -0700427 OmahaRequestParams params(&fake_system_state_);
Alex Deymo85616652015-10-15 18:48:31 -0700428 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
Hidehiko Abe2b9d2412017-12-13 18:56:18 +0900429 params.set_root(tempdir.GetPath().value());
Sen Jiang297e5832016-03-17 14:45:51 -0700430 params.set_current_channel("canary-channel");
431 // The ImageProperties in Android uses prefs to store MutableImageProperties.
432#ifdef __ANDROID__
Sen Jiang297e5832016-03-17 14:45:51 -0700433 EXPECT_CALL(*fake_system_state_.mock_prefs(), SetBoolean(_, true))
434 .WillOnce(Return(true));
435#endif // __ANDROID__
436 EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
437 params.UpdateDownloadChannel();
Sen Jiang8500d3a2018-02-08 12:04:05 -0800438 EXPECT_TRUE(params.ShouldPowerwash());
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700439
Alex Deymo763e7db2015-08-27 21:08:08 -0700440 fake_system_state_.set_request_params(&params);
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700441 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700442 EXPECT_TRUE(DoTest(in, "", &install_plan));
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700443 EXPECT_TRUE(install_plan.powerwash_required);
444}
445
446TEST_F(OmahaResponseHandlerActionTest, ChangeToLessStableChannelTest) {
447 OmahaResponse in;
448 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700449 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800450 in.packages.push_back({.payload_urls = {"https://LessStableChannelTest"},
451 .size = 15,
452 .hash = kPayloadHashHex});
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700453 in.more_info_url = "http://more/info";
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700454
Gilad Arnoldeff87cc2013-07-22 18:32:09 -0700455 // Create a uniquely named test directory.
Sen Jiang297e5832016-03-17 14:45:51 -0700456 base::ScopedTempDir tempdir;
457 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700458
Alex Deymo763e7db2015-08-27 21:08:08 -0700459 OmahaRequestParams params(&fake_system_state_);
Alex Deymo85616652015-10-15 18:48:31 -0700460 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
Hidehiko Abe2b9d2412017-12-13 18:56:18 +0900461 params.set_root(tempdir.GetPath().value());
Sen Jiang297e5832016-03-17 14:45:51 -0700462 params.set_current_channel("stable-channel");
463 // The ImageProperties in Android uses prefs to store MutableImageProperties.
464#ifdef __ANDROID__
Sen Jiang297e5832016-03-17 14:45:51 -0700465 EXPECT_CALL(*fake_system_state_.mock_prefs(), SetBoolean(_, false))
466 .WillOnce(Return(true));
467#endif // __ANDROID__
468 EXPECT_TRUE(params.SetTargetChannel("canary-channel", false, nullptr));
469 params.UpdateDownloadChannel();
Sen Jiang8500d3a2018-02-08 12:04:05 -0800470 EXPECT_FALSE(params.ShouldPowerwash());
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700471
Alex Deymo763e7db2015-08-27 21:08:08 -0700472 fake_system_state_.set_request_params(&params);
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700473 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700474 EXPECT_TRUE(DoTest(in, "", &install_plan));
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700475 EXPECT_FALSE(install_plan.powerwash_required);
476}
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800477
David Zeuthen8f191b22013-08-06 12:27:50 -0700478TEST_F(OmahaResponseHandlerActionTest, P2PUrlIsUsedAndHashChecksMandatory) {
479 OmahaResponse in;
480 in.update_exists = true;
481 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800482 in.packages.push_back(
483 {.payload_urls = {"https://would.not/cause/hash/checks"},
484 .size = 12,
485 .hash = kPayloadHashHex});
David Zeuthen8f191b22013-08-06 12:27:50 -0700486 in.more_info_url = "http://more/info";
David Zeuthen8f191b22013-08-06 12:27:50 -0700487
Alex Deymo763e7db2015-08-27 21:08:08 -0700488 OmahaRequestParams params(&fake_system_state_);
David Pursell02c18642014-11-06 11:26:11 -0800489 // We're using a real OmahaRequestParams object here so we can't mock
490 // IsUpdateUrlOfficial(), but setting the update URL to the AutoUpdate test
491 // server will cause IsUpdateUrlOfficial() to return true.
Alex Deymoac41a822015-09-15 20:52:53 -0700492 params.set_update_url(constants::kOmahaDefaultAUTestURL);
Alex Deymo763e7db2015-08-27 21:08:08 -0700493 fake_system_state_.set_request_params(&params);
David Zeuthen8f191b22013-08-06 12:27:50 -0700494
Alex Deymo763e7db2015-08-27 21:08:08 -0700495 EXPECT_CALL(*fake_system_state_.mock_payload_state(),
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700496 SetUsingP2PForDownloading(true));
497
David Zeuthen8f191b22013-08-06 12:27:50 -0700498 string p2p_url = "http://9.8.7.6/p2p";
Alex Deymo763e7db2015-08-27 21:08:08 -0700499 EXPECT_CALL(*fake_system_state_.mock_payload_state(), GetP2PUrl())
Gilad Arnold74b5f552014-10-07 08:17:16 -0700500 .WillRepeatedly(Return(p2p_url));
Alex Deymo763e7db2015-08-27 21:08:08 -0700501 EXPECT_CALL(*fake_system_state_.mock_payload_state(),
Aaron Woodc73fdc12017-12-06 11:09:15 -0800502 GetUsingP2PForDownloading())
503 .WillRepeatedly(Return(true));
David Zeuthen8f191b22013-08-06 12:27:50 -0700504
505 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700506 EXPECT_TRUE(DoTest(in, "", &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800507 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Sen Jiang2703ef42017-03-16 13:36:21 -0700508 EXPECT_EQ(p2p_url, install_plan.download_url);
David Zeuthen8f191b22013-08-06 12:27:50 -0700509 EXPECT_TRUE(install_plan.hash_checks_mandatory);
510}
511
Marton Hunyady199152d2018-05-07 19:08:48 +0200512TEST_F(OmahaResponseHandlerActionTest, RollbackTest) {
513 OmahaResponse in;
514 in.update_exists = true;
515 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
516 .size = 1,
517 .hash = kPayloadHashHex});
518 in.is_rollback = true;
Zentaro Kavanagh0ff621c2018-07-13 13:06:56 -0700519 in.rollback_key_version.kernel = 1;
520 in.rollback_key_version.kernel = 2;
521 in.rollback_key_version.firmware_key = 3;
522 in.rollback_key_version.firmware = 4;
Marton Hunyady199152d2018-05-07 19:08:48 +0200523
524 fake_system_state_.fake_hardware()->SetMinKernelKeyVersion(0x00010002);
525 fake_system_state_.fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
526
527 OmahaRequestParams params(&fake_system_state_);
528 params.set_rollback_allowed(true);
529
530 fake_system_state_.set_request_params(&params);
531 InstallPlan install_plan;
532 EXPECT_TRUE(DoTest(in, "", &install_plan));
533 EXPECT_TRUE(install_plan.is_rollback);
534}
535
536TEST_F(OmahaResponseHandlerActionTest, RollbackKernelVersionErrorTest) {
537 OmahaResponse in;
538 in.update_exists = true;
539 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
540 .size = 1,
541 .hash = kPayloadHashHex});
542 in.is_rollback = true;
Zentaro Kavanagh0ff621c2018-07-13 13:06:56 -0700543 in.rollback_key_version.kernel_key = 1;
544 in.rollback_key_version.kernel = 1; // This is lower than the minimum.
545 in.rollback_key_version.firmware_key = 3;
546 in.rollback_key_version.firmware = 4;
Marton Hunyady199152d2018-05-07 19:08:48 +0200547
548 fake_system_state_.fake_hardware()->SetMinKernelKeyVersion(0x00010002);
549 fake_system_state_.fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
550
551 OmahaRequestParams params(&fake_system_state_);
552 params.set_rollback_allowed(true);
553
554 fake_system_state_.set_request_params(&params);
555 InstallPlan install_plan;
556 EXPECT_FALSE(DoTest(in, "", &install_plan));
557}
558
559TEST_F(OmahaResponseHandlerActionTest, RollbackFirmwareVersionErrorTest) {
560 OmahaResponse in;
561 in.update_exists = true;
562 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
563 .size = 1,
564 .hash = kPayloadHashHex});
565 in.is_rollback = true;
Zentaro Kavanagh0ff621c2018-07-13 13:06:56 -0700566 in.rollback_key_version.kernel_key = 1;
567 in.rollback_key_version.kernel = 2;
568 in.rollback_key_version.firmware_key = 3;
569 in.rollback_key_version.firmware = 3; // This is lower than the minimum.
Marton Hunyady199152d2018-05-07 19:08:48 +0200570
571 fake_system_state_.fake_hardware()->SetMinKernelKeyVersion(0x00010002);
572 fake_system_state_.fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
573
574 OmahaRequestParams params(&fake_system_state_);
575 params.set_rollback_allowed(true);
576
577 fake_system_state_.set_request_params(&params);
578 InstallPlan install_plan;
579 EXPECT_FALSE(DoTest(in, "", &install_plan));
580}
581
582TEST_F(OmahaResponseHandlerActionTest, RollbackNotRollbackTest) {
583 OmahaResponse in;
584 in.update_exists = true;
585 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
586 .size = 1,
587 .hash = kPayloadHashHex});
588 in.is_rollback = false;
589
590 OmahaRequestParams params(&fake_system_state_);
591 params.set_rollback_allowed(true);
592
593 fake_system_state_.set_request_params(&params);
594 InstallPlan install_plan;
595 EXPECT_TRUE(DoTest(in, "", &install_plan));
596 EXPECT_FALSE(install_plan.is_rollback);
597}
598
599TEST_F(OmahaResponseHandlerActionTest, RollbackNotAllowedTest) {
600 OmahaResponse in;
601 in.update_exists = true;
602 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
603 .size = 1,
604 .hash = kPayloadHashHex});
605 in.is_rollback = true;
606
607 OmahaRequestParams params(&fake_system_state_);
608 params.set_rollback_allowed(false);
609
610 fake_system_state_.set_request_params(&params);
611 InstallPlan install_plan;
612 EXPECT_FALSE(DoTest(in, "", &install_plan));
613}
614
Aaron Wood7dcdedf2017-09-06 17:17:41 -0700615TEST_F(OmahaResponseHandlerActionTest, SystemVersionTest) {
616 OmahaResponse in;
617 in.update_exists = true;
618 in.version = "a.b.c.d";
619 in.system_version = "b.c.d.e";
620 in.packages.push_back({.payload_urls = {"http://package/1"},
621 .size = 1,
622 .hash = kPayloadHashHex});
623 in.packages.push_back({.payload_urls = {"http://package/2"},
624 .size = 2,
625 .hash = kPayloadHashHex});
626 in.more_info_url = "http://more/info";
627 InstallPlan install_plan;
628 EXPECT_TRUE(DoTest(in, "", &install_plan));
629 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
630 EXPECT_EQ(2u, install_plan.payloads.size());
631 EXPECT_EQ(in.packages[0].size, install_plan.payloads[0].size);
632 EXPECT_EQ(in.packages[1].size, install_plan.payloads[1].size);
633 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
634 EXPECT_EQ(expected_hash_, install_plan.payloads[1].hash);
635 EXPECT_EQ(in.version, install_plan.version);
636 EXPECT_EQ(in.system_version, install_plan.system_version);
637}
638
Aaron Wood23bd3392017-10-06 14:48:25 -0700639TEST_F(OmahaResponseHandlerActionTest, TestDeferredByPolicy) {
640 OmahaResponse in;
641 in.update_exists = true;
642 in.version = "a.b.c.d";
643 in.packages.push_back({.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
644 .size = 12,
645 .hash = kPayloadHashHex});
646 // Setup the UpdateManager to disallow the update.
647 FakeClock fake_clock;
648 MockPolicy* mock_policy = new MockPolicy(&fake_clock);
649 FakeUpdateManager* fake_update_manager =
650 fake_system_state_.fake_update_manager();
651 fake_update_manager->set_policy(mock_policy);
652 EXPECT_CALL(*mock_policy, UpdateCanBeApplied(_, _, _, _, _))
653 .WillOnce(
654 DoAll(SetArgPointee<3>(ErrorCode::kOmahaUpdateDeferredPerPolicy),
655 Return(EvalStatus::kSucceeded)));
656 // Perform the Action. It should "fail" with kOmahaUpdateDeferredPerPolicy.
657 InstallPlan install_plan;
658 EXPECT_FALSE(DoTest(in, "", &install_plan));
659 EXPECT_EQ(ErrorCode::kOmahaUpdateDeferredPerPolicy, action_result_code_);
660 // Verify that DoTest() didn't set the output install plan.
661 EXPECT_EQ("", install_plan.version);
Aaron Wood23bd3392017-10-06 14:48:25 -0700662 // Now verify the InstallPlan that was generated.
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700663 install_plan = *delegate_.response_handler_action_install_plan_;
Aaron Wood23bd3392017-10-06 14:48:25 -0700664 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
665 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
666 EXPECT_EQ(1U, install_plan.target_slot);
667 EXPECT_EQ(in.version, install_plan.version);
668}
669
adlr@google.com3defe6a2009-12-04 20:57:17 +0000670} // namespace chromeos_update_engine