1 //
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 //
16
17 #include "update_engine/omaha_response_handler_action.h"
18
19 #include <memory>
20 #include <string>
21 #include <utility>
22
23 #include <base/files/file_util.h>
24 #include <base/files/scoped_temp_dir.h>
25 #include <brillo/message_loops/fake_message_loop.h>
26 #include <gtest/gtest.h>
27
28 #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"
32 #include "update_engine/fake_system_state.h"
33 #include "update_engine/mock_payload_state.h"
34 #include "update_engine/payload_consumer/payload_constants.h"
35 #include "update_engine/update_manager/mock_policy.h"
36
37 using chromeos_update_engine::test_utils::System;
38 using chromeos_update_engine::test_utils::WriteFileString;
39 using chromeos_update_manager::EvalStatus;
40 using chromeos_update_manager::FakeUpdateManager;
41 using chromeos_update_manager::MockPolicy;
42 using std::string;
43 using testing::_;
44 using testing::DoAll;
45 using testing::Return;
46 using testing::SetArgPointee;
47
48 namespace chromeos_update_engine {
49
50 class OmahaResponseHandlerActionProcessorDelegate
51 : public ActionProcessorDelegate {
52 public:
OmahaResponseHandlerActionProcessorDelegate()53 OmahaResponseHandlerActionProcessorDelegate()
54 : code_(ErrorCode::kError), code_set_(false) {}
ActionCompleted(ActionProcessor * processor,AbstractAction * action,ErrorCode code)55 void ActionCompleted(ActionProcessor* processor,
56 AbstractAction* action,
57 ErrorCode code) {
58 if (action->Type() == OmahaResponseHandlerAction::StaticType()) {
59 auto response_handler_action =
60 static_cast<OmahaResponseHandlerAction*>(action);
61 code_ = code;
62 code_set_ = true;
63 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()));
71 }
72 }
73 ErrorCode code_;
74 bool code_set_;
75 std::unique_ptr<InstallPlan> collector_action_install_plan_;
76 std::unique_ptr<InstallPlan> response_handler_action_install_plan_;
77 };
78
79 class OmahaResponseHandlerActionTest : public ::testing::Test {
80 protected:
SetUp()81 void SetUp() override {
82 FakeBootControl* fake_boot_control = fake_system_state_.fake_boot_control();
83 fake_boot_control->SetPartitionDevice(kPartitionNameKernel, 0, "/dev/sdz2");
84 fake_boot_control->SetPartitionDevice(kPartitionNameRoot, 0, "/dev/sdz3");
85 fake_boot_control->SetPartitionDevice(kPartitionNameKernel, 1, "/dev/sdz4");
86 fake_boot_control->SetPartitionDevice(kPartitionNameRoot, 1, "/dev/sdz5");
87 }
88
89 // Return true iff the OmahaResponseHandlerAction succeeded.
90 // If out is non-null, it's set w/ the response from the action.
91 bool DoTest(const OmahaResponse& in,
92 const string& deadline_file,
93 InstallPlan* out);
94
95 // Delegate passed to the ActionProcessor.
96 OmahaResponseHandlerActionProcessorDelegate delegate_;
97
98 // Captures the action's result code, for tests that need to directly verify
99 // it in non-success cases.
100 ErrorCode action_result_code_;
101
102 FakeSystemState fake_system_state_;
103 // "Hash+"
104 const brillo::Blob expected_hash_ = {0x48, 0x61, 0x73, 0x68, 0x2b};
105 };
106
107 namespace {
108 const char* const kLongName =
109 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
110 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
111 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
112 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
113 "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 "-the_update_a.b.c.d_DELTA_.tgz";
117 const char* const kBadVersion = "don't update me";
118 const char* const kPayloadHashHex = "486173682b";
119 } // namespace
120
DoTest(const OmahaResponse & in,const string & test_deadline_file,InstallPlan * out)121 bool OmahaResponseHandlerActionTest::DoTest(const OmahaResponse& in,
122 const string& test_deadline_file,
123 InstallPlan* out) {
124 brillo::FakeMessageLoop loop(nullptr);
125 loop.SetAsCurrent();
126 ActionProcessor processor;
127 processor.set_delegate(&delegate_);
128
129 auto feeder_action = std::make_unique<ObjectFeederAction<OmahaResponse>>();
130 feeder_action->set_obj(in);
131 if (in.update_exists && in.version != kBadVersion) {
132 string expected_hash;
133 for (const auto& package : in.packages)
134 expected_hash += package.hash + ":";
135 EXPECT_CALL(*(fake_system_state_.mock_prefs()),
136 SetString(kPrefsUpdateCheckResponseHash, expected_hash))
137 .WillOnce(Return(true));
138
139 int slot =
140 fake_system_state_.request_params()->is_install()
141 ? fake_system_state_.fake_boot_control()->GetCurrentSlot()
142 : 1 - fake_system_state_.fake_boot_control()->GetCurrentSlot();
143 string key = kPrefsChannelOnSlotPrefix + std::to_string(slot);
144 EXPECT_CALL(*(fake_system_state_.mock_prefs()), SetString(key, testing::_))
145 .WillOnce(Return(true));
146 }
147
148 string current_url = in.packages.size() ? in.packages[0].payload_urls[0] : "";
149 EXPECT_CALL(*(fake_system_state_.mock_payload_state()), GetCurrentUrl())
150 .WillRepeatedly(Return(current_url));
151
152 auto response_handler_action =
153 std::make_unique<OmahaResponseHandlerAction>(&fake_system_state_);
154 if (!test_deadline_file.empty())
155 response_handler_action->deadline_file_ = test_deadline_file;
156
157 auto collector_action =
158 std::make_unique<ObjectCollectorAction<InstallPlan>>();
159
160 BondActions(feeder_action.get(), response_handler_action.get());
161 BondActions(response_handler_action.get(), collector_action.get());
162 processor.EnqueueAction(std::move(feeder_action));
163 processor.EnqueueAction(std::move(response_handler_action));
164 processor.EnqueueAction(std::move(collector_action));
165 processor.StartProcessing();
166 EXPECT_TRUE(!processor.IsRunning())
167 << "Update test to handle non-async actions";
168
169 if (out && delegate_.collector_action_install_plan_)
170 *out = *delegate_.collector_action_install_plan_;
171
172 EXPECT_TRUE(delegate_.code_set_);
173 action_result_code_ = delegate_.code_;
174 return delegate_.code_ == ErrorCode::kSuccess;
175 }
176
TEST_F(OmahaResponseHandlerActionTest,SimpleTest)177 TEST_F(OmahaResponseHandlerActionTest, SimpleTest) {
178 test_utils::ScopedTempFile test_deadline_file(
179 "omaha_response_handler_action_unittest-XXXXXX");
180 {
181 OmahaResponse in;
182 in.update_exists = true;
183 in.version = "a.b.c.d";
184 in.packages.push_back(
185 {.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
186 .size = 12,
187 .hash = kPayloadHashHex});
188 in.more_info_url = "http://more/info";
189 in.prompt = false;
190 in.deadline = "20101020";
191 InstallPlan install_plan;
192 EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
193 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
194 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
195 EXPECT_EQ(1U, install_plan.target_slot);
196 string deadline;
197 EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline));
198 EXPECT_EQ("20101020", deadline);
199 struct stat deadline_stat;
200 EXPECT_EQ(0, stat(test_deadline_file.path().c_str(), &deadline_stat));
201 EXPECT_EQ(
202 static_cast<mode_t>(S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),
203 deadline_stat.st_mode);
204 EXPECT_EQ(in.version, install_plan.version);
205 }
206 {
207 OmahaResponse in;
208 in.update_exists = true;
209 in.version = "a.b.c.d";
210 in.packages.push_back(
211 {.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
212 .size = 12,
213 .hash = kPayloadHashHex});
214 in.more_info_url = "http://more/info";
215 in.prompt = true;
216 InstallPlan install_plan;
217 // Set the other slot as current.
218 fake_system_state_.fake_boot_control()->SetCurrentSlot(1);
219 EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
220 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
221 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
222 EXPECT_EQ(0U, install_plan.target_slot);
223 string deadline;
224 EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline) &&
225 deadline.empty());
226 EXPECT_EQ(in.version, install_plan.version);
227 }
228 {
229 OmahaResponse in;
230 in.update_exists = true;
231 in.version = "a.b.c.d";
232 in.packages.push_back(
233 {.payload_urls = {kLongName}, .size = 12, .hash = kPayloadHashHex});
234 in.more_info_url = "http://more/info";
235 in.prompt = true;
236 in.deadline = "some-deadline";
237 InstallPlan install_plan;
238 fake_system_state_.fake_boot_control()->SetCurrentSlot(0);
239 // Because rollback happened, the deadline shouldn't be written into the
240 // file.
241 EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
242 GetRollbackHappened())
243 .WillOnce(Return(true));
244 EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
245 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
246 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
247 EXPECT_EQ(1U, install_plan.target_slot);
248 string deadline;
249 EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline));
250 EXPECT_TRUE(deadline.empty());
251 EXPECT_EQ(in.version, install_plan.version);
252 }
253 {
254 OmahaResponse in;
255 in.update_exists = true;
256 in.version = "a.b.c.d";
257 in.packages.push_back(
258 {.payload_urls = {kLongName}, .size = 12, .hash = kPayloadHashHex});
259 in.more_info_url = "http://more/info";
260 in.prompt = true;
261 in.deadline = "some-deadline";
262 InstallPlan install_plan;
263 fake_system_state_.fake_boot_control()->SetCurrentSlot(0);
264 EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
265 GetRollbackHappened())
266 .WillOnce(Return(false));
267 EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
268 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
269 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
270 EXPECT_EQ(1U, install_plan.target_slot);
271 string deadline;
272 EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline));
273 EXPECT_EQ("some-deadline", deadline);
274 EXPECT_EQ(in.version, install_plan.version);
275 }
276 }
277
TEST_F(OmahaResponseHandlerActionTest,NoUpdatesTest)278 TEST_F(OmahaResponseHandlerActionTest, NoUpdatesTest) {
279 OmahaResponse in;
280 in.update_exists = false;
281 InstallPlan install_plan;
282 EXPECT_FALSE(DoTest(in, "", &install_plan));
283 EXPECT_TRUE(install_plan.partitions.empty());
284 }
285
TEST_F(OmahaResponseHandlerActionTest,InstallTest)286 TEST_F(OmahaResponseHandlerActionTest, InstallTest) {
287 OmahaResponse in;
288 in.update_exists = true;
289 in.version = "a.b.c.d";
290 in.packages.push_back(
291 {.payload_urls = {kLongName}, .size = 1, .hash = kPayloadHashHex});
292 in.packages.push_back(
293 {.payload_urls = {kLongName}, .size = 2, .hash = kPayloadHashHex});
294 in.more_info_url = "http://more/info";
295
296 OmahaRequestParams params(&fake_system_state_);
297 params.set_is_install(true);
298
299 fake_system_state_.set_request_params(¶ms);
300 InstallPlan install_plan;
301 EXPECT_TRUE(DoTest(in, "", &install_plan));
302 EXPECT_EQ(install_plan.source_slot, UINT_MAX);
303 }
304
TEST_F(OmahaResponseHandlerActionTest,MultiPackageTest)305 TEST_F(OmahaResponseHandlerActionTest, MultiPackageTest) {
306 OmahaResponse in;
307 in.update_exists = true;
308 in.version = "a.b.c.d";
309 in.packages.push_back({.payload_urls = {"http://package/1"},
310 .size = 1,
311 .hash = kPayloadHashHex});
312 in.packages.push_back({.payload_urls = {"http://package/2"},
313 .size = 2,
314 .hash = kPayloadHashHex});
315 in.more_info_url = "http://more/info";
316 InstallPlan install_plan;
317 EXPECT_TRUE(DoTest(in, "", &install_plan));
318 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
319 EXPECT_EQ(2u, install_plan.payloads.size());
320 EXPECT_EQ(in.packages[0].size, install_plan.payloads[0].size);
321 EXPECT_EQ(in.packages[1].size, install_plan.payloads[1].size);
322 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
323 EXPECT_EQ(expected_hash_, install_plan.payloads[1].hash);
324 EXPECT_EQ(in.version, install_plan.version);
325 }
326
TEST_F(OmahaResponseHandlerActionTest,HashChecksForHttpTest)327 TEST_F(OmahaResponseHandlerActionTest, HashChecksForHttpTest) {
328 OmahaResponse in;
329 in.update_exists = true;
330 in.version = "a.b.c.d";
331 in.packages.push_back(
332 {.payload_urls = {"http://test.should/need/hash.checks.signed"},
333 .size = 12,
334 .hash = kPayloadHashHex});
335 in.more_info_url = "http://more/info";
336 // Hash checks are always skipped for non-official update URLs.
337 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
338 IsUpdateUrlOfficial())
339 .WillRepeatedly(Return(true));
340 InstallPlan install_plan;
341 EXPECT_TRUE(DoTest(in, "", &install_plan));
342 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
343 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
344 EXPECT_TRUE(install_plan.hash_checks_mandatory);
345 EXPECT_EQ(in.version, install_plan.version);
346 }
347
TEST_F(OmahaResponseHandlerActionTest,HashChecksForUnofficialUpdateUrl)348 TEST_F(OmahaResponseHandlerActionTest, HashChecksForUnofficialUpdateUrl) {
349 OmahaResponse in;
350 in.update_exists = true;
351 in.version = "a.b.c.d";
352 in.packages.push_back(
353 {.payload_urls = {"http://url.normally/needs/hash.checks.signed"},
354 .size = 12,
355 .hash = kPayloadHashHex});
356 in.more_info_url = "http://more/info";
357 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
358 IsUpdateUrlOfficial())
359 .WillRepeatedly(Return(false));
360 InstallPlan install_plan;
361 EXPECT_TRUE(DoTest(in, "", &install_plan));
362 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
363 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
364 EXPECT_FALSE(install_plan.hash_checks_mandatory);
365 EXPECT_EQ(in.version, install_plan.version);
366 }
367
TEST_F(OmahaResponseHandlerActionTest,HashChecksForOfficialUrlUnofficialBuildTest)368 TEST_F(OmahaResponseHandlerActionTest,
369 HashChecksForOfficialUrlUnofficialBuildTest) {
370 // Official URLs for unofficial builds (dev/test images) don't require hash.
371 OmahaResponse in;
372 in.update_exists = true;
373 in.version = "a.b.c.d";
374 in.packages.push_back(
375 {.payload_urls = {"http://url.normally/needs/hash.checks.signed"},
376 .size = 12,
377 .hash = kPayloadHashHex});
378 in.more_info_url = "http://more/info";
379 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
380 IsUpdateUrlOfficial())
381 .WillRepeatedly(Return(true));
382 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
383 InstallPlan install_plan;
384 EXPECT_TRUE(DoTest(in, "", &install_plan));
385 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
386 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
387 EXPECT_FALSE(install_plan.hash_checks_mandatory);
388 EXPECT_EQ(in.version, install_plan.version);
389 }
390
TEST_F(OmahaResponseHandlerActionTest,HashChecksForHttpsTest)391 TEST_F(OmahaResponseHandlerActionTest, HashChecksForHttpsTest) {
392 OmahaResponse in;
393 in.update_exists = true;
394 in.version = "a.b.c.d";
395 in.packages.push_back(
396 {.payload_urls = {"https://test.should/need/hash.checks.signed"},
397 .size = 12,
398 .hash = kPayloadHashHex});
399 in.more_info_url = "http://more/info";
400 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
401 IsUpdateUrlOfficial())
402 .WillRepeatedly(Return(true));
403 InstallPlan install_plan;
404 EXPECT_TRUE(DoTest(in, "", &install_plan));
405 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
406 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
407 EXPECT_TRUE(install_plan.hash_checks_mandatory);
408 EXPECT_EQ(in.version, install_plan.version);
409 }
410
TEST_F(OmahaResponseHandlerActionTest,HashChecksForBothHttpAndHttpsTest)411 TEST_F(OmahaResponseHandlerActionTest, HashChecksForBothHttpAndHttpsTest) {
412 OmahaResponse in;
413 in.update_exists = true;
414 in.version = "a.b.c.d";
415 in.packages.push_back(
416 {.payload_urls = {"http://test.should.still/need/hash.checks",
417 "https://test.should.still/need/hash.checks"},
418 .size = 12,
419 .hash = kPayloadHashHex});
420 in.more_info_url = "http://more/info";
421 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
422 IsUpdateUrlOfficial())
423 .WillRepeatedly(Return(true));
424 InstallPlan install_plan;
425 EXPECT_TRUE(DoTest(in, "", &install_plan));
426 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
427 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
428 EXPECT_TRUE(install_plan.hash_checks_mandatory);
429 EXPECT_EQ(in.version, install_plan.version);
430 }
431
TEST_F(OmahaResponseHandlerActionTest,ChangeToMoreStableChannelTest)432 TEST_F(OmahaResponseHandlerActionTest, ChangeToMoreStableChannelTest) {
433 OmahaResponse in;
434 in.update_exists = true;
435 in.version = "a.b.c.d";
436 in.packages.push_back({.payload_urls = {"https://MoreStableChannelTest"},
437 .size = 1,
438 .hash = kPayloadHashHex});
439 in.more_info_url = "http://more/info";
440
441 // Create a uniquely named test directory.
442 base::ScopedTempDir tempdir;
443 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
444
445 OmahaRequestParams params(&fake_system_state_);
446 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
447 params.set_root(tempdir.GetPath().value());
448 params.set_current_channel("canary-channel");
449 // The ImageProperties in Android uses prefs to store MutableImageProperties.
450 #ifdef __ANDROID__
451 EXPECT_CALL(*fake_system_state_.mock_prefs(), SetBoolean(_, true))
452 .WillOnce(Return(true));
453 #endif // __ANDROID__
454 EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
455 params.UpdateDownloadChannel();
456 EXPECT_TRUE(params.ShouldPowerwash());
457
458 fake_system_state_.set_request_params(¶ms);
459 InstallPlan install_plan;
460 EXPECT_TRUE(DoTest(in, "", &install_plan));
461 EXPECT_TRUE(install_plan.powerwash_required);
462 }
463
TEST_F(OmahaResponseHandlerActionTest,ChangeToLessStableChannelTest)464 TEST_F(OmahaResponseHandlerActionTest, ChangeToLessStableChannelTest) {
465 OmahaResponse in;
466 in.update_exists = true;
467 in.version = "a.b.c.d";
468 in.packages.push_back({.payload_urls = {"https://LessStableChannelTest"},
469 .size = 15,
470 .hash = kPayloadHashHex});
471 in.more_info_url = "http://more/info";
472
473 // Create a uniquely named test directory.
474 base::ScopedTempDir tempdir;
475 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
476
477 OmahaRequestParams params(&fake_system_state_);
478 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
479 params.set_root(tempdir.GetPath().value());
480 params.set_current_channel("stable-channel");
481 // The ImageProperties in Android uses prefs to store MutableImageProperties.
482 #ifdef __ANDROID__
483 EXPECT_CALL(*fake_system_state_.mock_prefs(), SetBoolean(_, false))
484 .WillOnce(Return(true));
485 #endif // __ANDROID__
486 EXPECT_TRUE(params.SetTargetChannel("canary-channel", false, nullptr));
487 params.UpdateDownloadChannel();
488 EXPECT_FALSE(params.ShouldPowerwash());
489
490 fake_system_state_.set_request_params(¶ms);
491 InstallPlan install_plan;
492 EXPECT_TRUE(DoTest(in, "", &install_plan));
493 EXPECT_FALSE(install_plan.powerwash_required);
494 }
495
TEST_F(OmahaResponseHandlerActionTest,P2PUrlIsUsedAndHashChecksMandatory)496 TEST_F(OmahaResponseHandlerActionTest, P2PUrlIsUsedAndHashChecksMandatory) {
497 OmahaResponse in;
498 in.update_exists = true;
499 in.version = "a.b.c.d";
500 in.packages.push_back(
501 {.payload_urls = {"https://would.not/cause/hash/checks"},
502 .size = 12,
503 .hash = kPayloadHashHex});
504 in.more_info_url = "http://more/info";
505
506 OmahaRequestParams params(&fake_system_state_);
507 // We're using a real OmahaRequestParams object here so we can't mock
508 // IsUpdateUrlOfficial(), but setting the update URL to the AutoUpdate test
509 // server will cause IsUpdateUrlOfficial() to return true.
510 params.set_update_url(constants::kOmahaDefaultAUTestURL);
511 fake_system_state_.set_request_params(¶ms);
512
513 EXPECT_CALL(*fake_system_state_.mock_payload_state(),
514 SetUsingP2PForDownloading(true));
515
516 string p2p_url = "http://9.8.7.6/p2p";
517 EXPECT_CALL(*fake_system_state_.mock_payload_state(), GetP2PUrl())
518 .WillRepeatedly(Return(p2p_url));
519 EXPECT_CALL(*fake_system_state_.mock_payload_state(),
520 GetUsingP2PForDownloading())
521 .WillRepeatedly(Return(true));
522
523 InstallPlan install_plan;
524 EXPECT_TRUE(DoTest(in, "", &install_plan));
525 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
526 EXPECT_EQ(p2p_url, install_plan.download_url);
527 EXPECT_TRUE(install_plan.hash_checks_mandatory);
528 }
529
TEST_F(OmahaResponseHandlerActionTest,RollbackTest)530 TEST_F(OmahaResponseHandlerActionTest, RollbackTest) {
531 OmahaResponse in;
532 in.update_exists = true;
533 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
534 .size = 1,
535 .hash = kPayloadHashHex});
536 in.is_rollback = true;
537 in.rollback_key_version.kernel = 1;
538 in.rollback_key_version.kernel = 2;
539 in.rollback_key_version.firmware_key = 3;
540 in.rollback_key_version.firmware = 4;
541
542 fake_system_state_.fake_hardware()->SetMinKernelKeyVersion(0x00010002);
543 fake_system_state_.fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
544
545 OmahaRequestParams params(&fake_system_state_);
546 params.set_rollback_allowed(true);
547
548 fake_system_state_.set_request_params(¶ms);
549 InstallPlan install_plan;
550 EXPECT_TRUE(DoTest(in, "", &install_plan));
551 EXPECT_TRUE(install_plan.is_rollback);
552 }
553
TEST_F(OmahaResponseHandlerActionTest,RollbackKernelVersionErrorTest)554 TEST_F(OmahaResponseHandlerActionTest, RollbackKernelVersionErrorTest) {
555 OmahaResponse in;
556 in.update_exists = true;
557 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
558 .size = 1,
559 .hash = kPayloadHashHex});
560 in.is_rollback = true;
561 in.rollback_key_version.kernel_key = 1;
562 in.rollback_key_version.kernel = 1; // This is lower than the minimum.
563 in.rollback_key_version.firmware_key = 3;
564 in.rollback_key_version.firmware = 4;
565
566 fake_system_state_.fake_hardware()->SetMinKernelKeyVersion(0x00010002);
567 fake_system_state_.fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
568
569 OmahaRequestParams params(&fake_system_state_);
570 params.set_rollback_allowed(true);
571
572 fake_system_state_.set_request_params(¶ms);
573 InstallPlan install_plan;
574 EXPECT_FALSE(DoTest(in, "", &install_plan));
575 }
576
TEST_F(OmahaResponseHandlerActionTest,RollbackFirmwareVersionErrorTest)577 TEST_F(OmahaResponseHandlerActionTest, RollbackFirmwareVersionErrorTest) {
578 OmahaResponse in;
579 in.update_exists = true;
580 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
581 .size = 1,
582 .hash = kPayloadHashHex});
583 in.is_rollback = true;
584 in.rollback_key_version.kernel_key = 1;
585 in.rollback_key_version.kernel = 2;
586 in.rollback_key_version.firmware_key = 3;
587 in.rollback_key_version.firmware = 3; // This is lower than the minimum.
588
589 fake_system_state_.fake_hardware()->SetMinKernelKeyVersion(0x00010002);
590 fake_system_state_.fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
591
592 OmahaRequestParams params(&fake_system_state_);
593 params.set_rollback_allowed(true);
594
595 fake_system_state_.set_request_params(¶ms);
596 InstallPlan install_plan;
597 EXPECT_FALSE(DoTest(in, "", &install_plan));
598 }
599
TEST_F(OmahaResponseHandlerActionTest,RollbackNotRollbackTest)600 TEST_F(OmahaResponseHandlerActionTest, RollbackNotRollbackTest) {
601 OmahaResponse in;
602 in.update_exists = true;
603 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
604 .size = 1,
605 .hash = kPayloadHashHex});
606 in.is_rollback = false;
607
608 OmahaRequestParams params(&fake_system_state_);
609 params.set_rollback_allowed(true);
610
611 fake_system_state_.set_request_params(¶ms);
612 InstallPlan install_plan;
613 EXPECT_TRUE(DoTest(in, "", &install_plan));
614 EXPECT_FALSE(install_plan.is_rollback);
615 }
616
TEST_F(OmahaResponseHandlerActionTest,RollbackNotAllowedTest)617 TEST_F(OmahaResponseHandlerActionTest, RollbackNotAllowedTest) {
618 OmahaResponse in;
619 in.update_exists = true;
620 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
621 .size = 1,
622 .hash = kPayloadHashHex});
623 in.is_rollback = true;
624
625 OmahaRequestParams params(&fake_system_state_);
626 params.set_rollback_allowed(false);
627
628 fake_system_state_.set_request_params(¶ms);
629 InstallPlan install_plan;
630 EXPECT_FALSE(DoTest(in, "", &install_plan));
631 }
632
TEST_F(OmahaResponseHandlerActionTest,SystemVersionTest)633 TEST_F(OmahaResponseHandlerActionTest, SystemVersionTest) {
634 OmahaResponse in;
635 in.update_exists = true;
636 in.version = "a.b.c.d";
637 in.system_version = "b.c.d.e";
638 in.packages.push_back({.payload_urls = {"http://package/1"},
639 .size = 1,
640 .hash = kPayloadHashHex});
641 in.packages.push_back({.payload_urls = {"http://package/2"},
642 .size = 2,
643 .hash = kPayloadHashHex});
644 in.more_info_url = "http://more/info";
645 InstallPlan install_plan;
646 EXPECT_TRUE(DoTest(in, "", &install_plan));
647 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
648 EXPECT_EQ(2u, install_plan.payloads.size());
649 EXPECT_EQ(in.packages[0].size, install_plan.payloads[0].size);
650 EXPECT_EQ(in.packages[1].size, install_plan.payloads[1].size);
651 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
652 EXPECT_EQ(expected_hash_, install_plan.payloads[1].hash);
653 EXPECT_EQ(in.version, install_plan.version);
654 EXPECT_EQ(in.system_version, install_plan.system_version);
655 }
656
TEST_F(OmahaResponseHandlerActionTest,TestDeferredByPolicy)657 TEST_F(OmahaResponseHandlerActionTest, TestDeferredByPolicy) {
658 OmahaResponse in;
659 in.update_exists = true;
660 in.version = "a.b.c.d";
661 in.packages.push_back({.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
662 .size = 12,
663 .hash = kPayloadHashHex});
664 // Setup the UpdateManager to disallow the update.
665 FakeClock fake_clock;
666 MockPolicy* mock_policy = new MockPolicy(&fake_clock);
667 FakeUpdateManager* fake_update_manager =
668 fake_system_state_.fake_update_manager();
669 fake_update_manager->set_policy(mock_policy);
670 EXPECT_CALL(*mock_policy, UpdateCanBeApplied(_, _, _, _, _))
671 .WillOnce(
672 DoAll(SetArgPointee<3>(ErrorCode::kOmahaUpdateDeferredPerPolicy),
673 Return(EvalStatus::kSucceeded)));
674 // Perform the Action. It should "fail" with kOmahaUpdateDeferredPerPolicy.
675 InstallPlan install_plan;
676 EXPECT_FALSE(DoTest(in, "", &install_plan));
677 EXPECT_EQ(ErrorCode::kOmahaUpdateDeferredPerPolicy, action_result_code_);
678 // Verify that DoTest() didn't set the output install plan.
679 EXPECT_EQ("", install_plan.version);
680 // Now verify the InstallPlan that was generated.
681 install_plan = *delegate_.response_handler_action_install_plan_;
682 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
683 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
684 EXPECT_EQ(1U, install_plan.target_slot);
685 EXPECT_EQ(in.version, install_plan.version);
686 }
687
688 } // namespace chromeos_update_engine
689