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/cros/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/cros/fake_system_state.h"
33 #include "update_engine/cros/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::kRollforwardInfinity;
42 using chromeos_update_manager::MockPolicy;
43 using std::string;
44 using testing::_;
45 using testing::DoAll;
46 using testing::Return;
47 using testing::SetArgPointee;
48
49 namespace chromeos_update_engine {
50
51 class OmahaResponseHandlerActionProcessorDelegate
52 : public ActionProcessorDelegate {
53 public:
OmahaResponseHandlerActionProcessorDelegate()54 OmahaResponseHandlerActionProcessorDelegate()
55 : code_(ErrorCode::kError), code_set_(false) {}
ActionCompleted(ActionProcessor * processor,AbstractAction * action,ErrorCode code)56 void ActionCompleted(ActionProcessor* processor,
57 AbstractAction* action,
58 ErrorCode code) {
59 if (action->Type() == OmahaResponseHandlerAction::StaticType()) {
60 auto response_handler_action =
61 static_cast<OmahaResponseHandlerAction*>(action);
62 code_ = code;
63 code_set_ = true;
64 response_handler_action_install_plan_.reset(
65 new InstallPlan(response_handler_action->install_plan_));
66 } else if (action->Type() ==
67 ObjectCollectorAction<InstallPlan>::StaticType()) {
68 auto collector_action =
69 static_cast<ObjectCollectorAction<InstallPlan>*>(action);
70 collector_action_install_plan_.reset(
71 new InstallPlan(collector_action->object()));
72 }
73 }
74 ErrorCode code_;
75 bool code_set_;
76 std::unique_ptr<InstallPlan> collector_action_install_plan_;
77 std::unique_ptr<InstallPlan> response_handler_action_install_plan_;
78 };
79
80 class OmahaResponseHandlerActionTest : public ::testing::Test {
81 protected:
SetUp()82 void SetUp() override {
83 FakeSystemState::CreateInstance();
84 // Enable MockPrefs;
85 FakeSystemState::Get()->set_prefs(nullptr);
86 FakeBootControl* fake_boot_control =
87 FakeSystemState::Get()->fake_boot_control();
88 fake_boot_control->SetPartitionDevice(kPartitionNameKernel, 0, "/dev/sdz2");
89 fake_boot_control->SetPartitionDevice(kPartitionNameRoot, 0, "/dev/sdz3");
90 fake_boot_control->SetPartitionDevice(kPartitionNameKernel, 1, "/dev/sdz4");
91 fake_boot_control->SetPartitionDevice(kPartitionNameRoot, 1, "/dev/sdz5");
92 }
93
94 // Return true iff the OmahaResponseHandlerAction succeeded.
95 // If out is non-null, it's set w/ the response from the action.
96 bool DoTest(const OmahaResponse& in,
97 const string& deadline_file,
98 InstallPlan* out);
99
100 // Delegate passed to the ActionProcessor.
101 OmahaResponseHandlerActionProcessorDelegate delegate_;
102
103 // Captures the action's result code, for tests that need to directly verify
104 // it in non-success cases.
105 ErrorCode action_result_code_;
106
107 // "Hash+"
108 const brillo::Blob expected_hash_ = {0x48, 0x61, 0x73, 0x68, 0x2b};
109 };
110
111 namespace {
112 const char* const kLongName =
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 "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";
121 const char* const kBadVersion = "don't update me";
122 const char* const kPayloadHashHex = "486173682b";
123 const char* const kPayloadFp1 = "1.755aff78ec73dfc7f590893ac";
124 const char* const kPayloadFp2 = "1.98ba213e0ccec0d0e8cdc74a5";
125 const char* const kPayloadAppId = "test_app_id";
126 } // namespace
127
DoTest(const OmahaResponse & in,const string & test_deadline_file,InstallPlan * out)128 bool OmahaResponseHandlerActionTest::DoTest(const OmahaResponse& in,
129 const string& test_deadline_file,
130 InstallPlan* out) {
131 brillo::FakeMessageLoop loop(nullptr);
132 loop.SetAsCurrent();
133 ActionProcessor processor;
134 processor.set_delegate(&delegate_);
135
136 auto feeder_action = std::make_unique<ObjectFeederAction<OmahaResponse>>();
137 feeder_action->set_obj(in);
138 if (in.update_exists && in.version != kBadVersion) {
139 string expected_hash;
140 for (const auto& package : in.packages)
141 expected_hash += package.hash + ":";
142 EXPECT_CALL(*(FakeSystemState::Get()->mock_prefs()),
143 SetString(kPrefsUpdateCheckResponseHash, expected_hash))
144 .WillOnce(Return(true));
145
146 int slot =
147 FakeSystemState::Get()->request_params()->is_install()
148 ? FakeSystemState::Get()->fake_boot_control()->GetCurrentSlot()
149 : 1 - FakeSystemState::Get()->fake_boot_control()->GetCurrentSlot();
150 string key = kPrefsChannelOnSlotPrefix + std::to_string(slot);
151 EXPECT_CALL(*(FakeSystemState::Get()->mock_prefs()),
152 SetString(key, testing::_))
153 .WillOnce(Return(true));
154 }
155
156 string current_url = in.packages.size() ? in.packages[0].payload_urls[0] : "";
157 EXPECT_CALL(*(FakeSystemState::Get()->mock_payload_state()), GetCurrentUrl())
158 .WillRepeatedly(Return(current_url));
159
160 auto response_handler_action = std::make_unique<OmahaResponseHandlerAction>();
161 if (!test_deadline_file.empty())
162 response_handler_action->deadline_file_ = test_deadline_file;
163
164 auto collector_action =
165 std::make_unique<ObjectCollectorAction<InstallPlan>>();
166
167 BondActions(feeder_action.get(), response_handler_action.get());
168 BondActions(response_handler_action.get(), collector_action.get());
169 processor.EnqueueAction(std::move(feeder_action));
170 processor.EnqueueAction(std::move(response_handler_action));
171 processor.EnqueueAction(std::move(collector_action));
172 processor.StartProcessing();
173 EXPECT_TRUE(!processor.IsRunning())
174 << "Update test to handle non-async actions";
175
176 if (out && delegate_.collector_action_install_plan_)
177 *out = *delegate_.collector_action_install_plan_;
178
179 EXPECT_TRUE(delegate_.code_set_);
180 action_result_code_ = delegate_.code_;
181 return delegate_.code_ == ErrorCode::kSuccess;
182 }
183
TEST_F(OmahaResponseHandlerActionTest,SimpleTest)184 TEST_F(OmahaResponseHandlerActionTest, SimpleTest) {
185 ScopedTempFile test_deadline_file(
186 "omaha_response_handler_action_unittest-XXXXXX");
187 {
188 OmahaResponse in;
189 in.update_exists = true;
190 in.version = "a.b.c.d";
191 in.packages.push_back(
192 {.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
193 .size = 12,
194 .hash = kPayloadHashHex,
195 .app_id = kPayloadAppId,
196 .fp = kPayloadFp1});
197 in.more_info_url = "http://more/info";
198 in.prompt = false;
199 in.deadline = "20101020";
200 InstallPlan install_plan;
201 EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
202 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
203 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
204 EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
205 EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
206 EXPECT_EQ(1U, install_plan.target_slot);
207 string deadline;
208 EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline));
209 EXPECT_EQ("20101020", deadline);
210 struct stat deadline_stat;
211 EXPECT_EQ(0, stat(test_deadline_file.path().c_str(), &deadline_stat));
212 EXPECT_EQ(
213 static_cast<mode_t>(S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),
214 deadline_stat.st_mode);
215 EXPECT_EQ(in.version, install_plan.version);
216 }
217 {
218 OmahaResponse in;
219 in.update_exists = true;
220 in.version = "a.b.c.d";
221 in.packages.push_back(
222 {.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
223 .size = 12,
224 .hash = kPayloadHashHex,
225 .app_id = kPayloadAppId,
226 .fp = kPayloadFp1});
227 in.more_info_url = "http://more/info";
228 in.prompt = true;
229 InstallPlan install_plan;
230 // Set the other slot as current.
231 FakeSystemState::Get()->fake_boot_control()->SetCurrentSlot(1);
232 EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
233 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
234 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
235 EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
236 EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
237 EXPECT_EQ(0U, install_plan.target_slot);
238 string deadline;
239 EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline) &&
240 deadline.empty());
241 EXPECT_EQ(in.version, install_plan.version);
242 }
243 {
244 OmahaResponse in;
245 in.update_exists = true;
246 in.version = "a.b.c.d";
247 in.packages.push_back({.payload_urls = {kLongName},
248 .size = 12,
249 .hash = kPayloadHashHex,
250 .app_id = kPayloadAppId,
251 .fp = kPayloadFp1});
252 in.more_info_url = "http://more/info";
253 in.prompt = true;
254 in.deadline = "some-deadline";
255 InstallPlan install_plan;
256 FakeSystemState::Get()->fake_boot_control()->SetCurrentSlot(0);
257 // Because rollback happened, the deadline shouldn't be written into the
258 // file.
259 EXPECT_CALL(*(FakeSystemState::Get()->mock_payload_state()),
260 GetRollbackHappened())
261 .WillOnce(Return(true));
262 EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
263 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
264 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
265 EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
266 EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
267 EXPECT_EQ(1U, install_plan.target_slot);
268 string deadline;
269 EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline));
270 EXPECT_TRUE(deadline.empty());
271 EXPECT_EQ(in.version, install_plan.version);
272 }
273 {
274 OmahaResponse in;
275 in.update_exists = true;
276 in.version = "a.b.c.d";
277 in.packages.push_back({.payload_urls = {kLongName},
278 .size = 12,
279 .hash = kPayloadHashHex,
280 .app_id = kPayloadAppId,
281 .fp = kPayloadFp1});
282 in.more_info_url = "http://more/info";
283 in.prompt = true;
284 in.deadline = "some-deadline";
285 InstallPlan install_plan;
286 FakeSystemState::Get()->fake_boot_control()->SetCurrentSlot(0);
287 EXPECT_CALL(*(FakeSystemState::Get()->mock_payload_state()),
288 GetRollbackHappened())
289 .WillOnce(Return(false));
290 EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
291 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
292 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
293 EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
294 EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
295 EXPECT_EQ(1U, install_plan.target_slot);
296 string deadline;
297 EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline));
298 EXPECT_EQ("some-deadline", deadline);
299 EXPECT_EQ(in.version, install_plan.version);
300 }
301 }
302
TEST_F(OmahaResponseHandlerActionTest,NoUpdatesTest)303 TEST_F(OmahaResponseHandlerActionTest, NoUpdatesTest) {
304 OmahaResponse in;
305 in.update_exists = false;
306 InstallPlan install_plan;
307 EXPECT_FALSE(DoTest(in, "", &install_plan));
308 EXPECT_TRUE(install_plan.partitions.empty());
309 }
310
TEST_F(OmahaResponseHandlerActionTest,InstallTest)311 TEST_F(OmahaResponseHandlerActionTest, InstallTest) {
312 OmahaResponse in;
313 in.update_exists = true;
314 in.version = "a.b.c.d";
315 in.packages.push_back(
316 {.payload_urls = {kLongName}, .size = 1, .hash = kPayloadHashHex});
317 in.packages.push_back(
318 {.payload_urls = {kLongName}, .size = 2, .hash = kPayloadHashHex});
319 in.more_info_url = "http://more/info";
320
321 OmahaRequestParams params;
322 params.set_is_install(true);
323
324 FakeSystemState::Get()->set_request_params(¶ms);
325 InstallPlan install_plan;
326 EXPECT_TRUE(DoTest(in, "", &install_plan));
327 EXPECT_EQ(install_plan.source_slot, UINT_MAX);
328 }
329
TEST_F(OmahaResponseHandlerActionTest,MultiPackageTest)330 TEST_F(OmahaResponseHandlerActionTest, MultiPackageTest) {
331 OmahaResponse in;
332 in.update_exists = true;
333 in.version = "a.b.c.d";
334 in.packages.push_back({.payload_urls = {"http://package/1"},
335 .size = 1,
336 .hash = kPayloadHashHex,
337 .app_id = kPayloadAppId,
338 .fp = kPayloadFp1});
339 in.packages.push_back({.payload_urls = {"http://package/2"},
340 .size = 2,
341 .hash = kPayloadHashHex,
342 .app_id = kPayloadAppId,
343 .fp = kPayloadFp2});
344 in.more_info_url = "http://more/info";
345 InstallPlan install_plan;
346 EXPECT_TRUE(DoTest(in, "", &install_plan));
347 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
348 EXPECT_EQ(2u, install_plan.payloads.size());
349 EXPECT_EQ(in.packages[0].size, install_plan.payloads[0].size);
350 EXPECT_EQ(in.packages[1].size, install_plan.payloads[1].size);
351 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
352 EXPECT_EQ(expected_hash_, install_plan.payloads[1].hash);
353 EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
354 EXPECT_EQ(in.packages[1].app_id, install_plan.payloads[1].app_id);
355 EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
356 EXPECT_EQ(in.packages[1].fp, install_plan.payloads[1].fp);
357 EXPECT_EQ(in.version, install_plan.version);
358 }
359
TEST_F(OmahaResponseHandlerActionTest,HashChecksForHttpTest)360 TEST_F(OmahaResponseHandlerActionTest, HashChecksForHttpTest) {
361 OmahaResponse in;
362 in.update_exists = true;
363 in.version = "a.b.c.d";
364 in.packages.push_back(
365 {.payload_urls = {"http://test.should/need/hash.checks.signed"},
366 .size = 12,
367 .hash = kPayloadHashHex,
368 .app_id = kPayloadAppId,
369 .fp = kPayloadFp1});
370 in.more_info_url = "http://more/info";
371 // Hash checks are always skipped for non-official update URLs.
372 EXPECT_CALL(*(FakeSystemState::Get()->mock_request_params()),
373 IsUpdateUrlOfficial())
374 .WillRepeatedly(Return(true));
375 InstallPlan install_plan;
376 EXPECT_TRUE(DoTest(in, "", &install_plan));
377 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
378 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
379 EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
380 EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
381 EXPECT_TRUE(install_plan.hash_checks_mandatory);
382 EXPECT_EQ(in.version, install_plan.version);
383 }
384
TEST_F(OmahaResponseHandlerActionTest,HashChecksForUnofficialUpdateUrl)385 TEST_F(OmahaResponseHandlerActionTest, HashChecksForUnofficialUpdateUrl) {
386 OmahaResponse in;
387 in.update_exists = true;
388 in.version = "a.b.c.d";
389 in.packages.push_back(
390 {.payload_urls = {"http://url.normally/needs/hash.checks.signed"},
391 .size = 12,
392 .hash = kPayloadHashHex,
393 .app_id = kPayloadAppId,
394 .fp = kPayloadFp1});
395 in.more_info_url = "http://more/info";
396 EXPECT_CALL(*(FakeSystemState::Get()->mock_request_params()),
397 IsUpdateUrlOfficial())
398 .WillRepeatedly(Return(false));
399 InstallPlan install_plan;
400 EXPECT_TRUE(DoTest(in, "", &install_plan));
401 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
402 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
403 EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
404 EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
405 EXPECT_FALSE(install_plan.hash_checks_mandatory);
406 EXPECT_EQ(in.version, install_plan.version);
407 }
408
TEST_F(OmahaResponseHandlerActionTest,HashChecksForOfficialUrlUnofficialBuildTest)409 TEST_F(OmahaResponseHandlerActionTest,
410 HashChecksForOfficialUrlUnofficialBuildTest) {
411 // Official URLs for unofficial builds (dev/test images) don't require hash.
412 OmahaResponse in;
413 in.update_exists = true;
414 in.version = "a.b.c.d";
415 in.packages.push_back(
416 {.payload_urls = {"http://url.normally/needs/hash.checks.signed"},
417 .size = 12,
418 .hash = kPayloadHashHex,
419 .app_id = kPayloadAppId,
420 .fp = kPayloadFp1});
421 in.more_info_url = "http://more/info";
422 EXPECT_CALL(*(FakeSystemState::Get()->mock_request_params()),
423 IsUpdateUrlOfficial())
424 .WillRepeatedly(Return(true));
425 FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(false);
426 InstallPlan install_plan;
427 EXPECT_TRUE(DoTest(in, "", &install_plan));
428 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
429 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
430 EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
431 EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
432 EXPECT_FALSE(install_plan.hash_checks_mandatory);
433 EXPECT_EQ(in.version, install_plan.version);
434 }
435
TEST_F(OmahaResponseHandlerActionTest,HashChecksForHttpsTest)436 TEST_F(OmahaResponseHandlerActionTest, HashChecksForHttpsTest) {
437 OmahaResponse in;
438 in.update_exists = true;
439 in.version = "a.b.c.d";
440 in.packages.push_back(
441 {.payload_urls = {"https://test.should/need/hash.checks.signed"},
442 .size = 12,
443 .hash = kPayloadHashHex,
444 .app_id = kPayloadAppId,
445 .fp = kPayloadFp1});
446 in.more_info_url = "http://more/info";
447 EXPECT_CALL(*(FakeSystemState::Get()->mock_request_params()),
448 IsUpdateUrlOfficial())
449 .WillRepeatedly(Return(true));
450 InstallPlan install_plan;
451 EXPECT_TRUE(DoTest(in, "", &install_plan));
452 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
453 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
454 EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
455 EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
456 EXPECT_TRUE(install_plan.hash_checks_mandatory);
457 EXPECT_EQ(in.version, install_plan.version);
458 }
459
TEST_F(OmahaResponseHandlerActionTest,HashChecksForBothHttpAndHttpsTest)460 TEST_F(OmahaResponseHandlerActionTest, HashChecksForBothHttpAndHttpsTest) {
461 OmahaResponse in;
462 in.update_exists = true;
463 in.version = "a.b.c.d";
464 in.packages.push_back(
465 {.payload_urls = {"http://test.should.still/need/hash.checks",
466 "https://test.should.still/need/hash.checks"},
467 .size = 12,
468 .hash = kPayloadHashHex,
469 .app_id = kPayloadAppId,
470 .fp = kPayloadFp1});
471 in.more_info_url = "http://more/info";
472 EXPECT_CALL(*(FakeSystemState::Get()->mock_request_params()),
473 IsUpdateUrlOfficial())
474 .WillRepeatedly(Return(true));
475 InstallPlan install_plan;
476 EXPECT_TRUE(DoTest(in, "", &install_plan));
477 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
478 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
479 EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
480 EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
481 EXPECT_TRUE(install_plan.hash_checks_mandatory);
482 EXPECT_EQ(in.version, install_plan.version);
483 }
484
TEST_F(OmahaResponseHandlerActionTest,ChangeToMoreStableVersionAndChannelTest)485 TEST_F(OmahaResponseHandlerActionTest,
486 ChangeToMoreStableVersionAndChannelTest) {
487 OmahaResponse in;
488 in.update_exists = true;
489 in.version = "1.0.0.0";
490 in.packages.push_back({.payload_urls = {"https://MoreStableChannelTest"},
491 .size = 1,
492 .hash = kPayloadHashHex});
493 in.more_info_url = "http://more/info";
494
495 // Create a uniquely named test directory.
496 base::ScopedTempDir tempdir;
497 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
498
499 OmahaRequestParams params;
500 FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(false);
501 params.set_root(tempdir.GetPath().value());
502 params.set_current_channel("canary-channel");
503 EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
504 params.UpdateDownloadChannel();
505 params.set_app_version("2.0.0.0");
506
507 FakeSystemState::Get()->set_request_params(¶ms);
508 InstallPlan install_plan;
509 EXPECT_TRUE(DoTest(in, "", &install_plan));
510 EXPECT_TRUE(install_plan.powerwash_required);
511 }
512
TEST_F(OmahaResponseHandlerActionTest,ChangeToMoreStableVersionAndChannelPowerwashNotAllowedTest)513 TEST_F(OmahaResponseHandlerActionTest,
514 ChangeToMoreStableVersionAndChannelPowerwashNotAllowedTest) {
515 OmahaResponse in;
516 in.update_exists = true;
517 in.version = "1.0.0.0";
518 in.packages.push_back({.payload_urls = {"https://MoreStableChannelTest"},
519 .size = 1,
520 .hash = kPayloadHashHex});
521 in.more_info_url = "http://more/info";
522
523 // Create a uniquely named test directory.
524 base::ScopedTempDir tempdir;
525 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
526
527 OmahaRequestParams params;
528 FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(false);
529 params.set_root(tempdir.GetPath().value());
530 params.set_current_channel("canary-channel");
531 EXPECT_TRUE(params.SetTargetChannel("stable-channel", false, nullptr));
532 params.UpdateDownloadChannel();
533 params.set_app_version("2.0.0.0");
534
535 FakeSystemState::Get()->set_request_params(¶ms);
536 InstallPlan install_plan;
537 EXPECT_TRUE(DoTest(in, "", &install_plan));
538 EXPECT_FALSE(install_plan.powerwash_required);
539 }
540
TEST_F(OmahaResponseHandlerActionTest,ChangeToMoreStableChannelButNewerVersionTest)541 TEST_F(OmahaResponseHandlerActionTest,
542 ChangeToMoreStableChannelButNewerVersionTest) {
543 OmahaResponse in;
544 in.update_exists = true;
545 in.version = "12345.96.0.0";
546 in.packages.push_back({.payload_urls = {"https://ChannelDownVersionUp"},
547 .size = 1,
548 .hash = kPayloadHashHex});
549 in.more_info_url = "http://more/info";
550
551 // Create a uniquely named test directory.
552 base::ScopedTempDir tempdir;
553 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
554
555 OmahaRequestParams params;
556 FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(false);
557 params.set_root(tempdir.GetPath().value());
558 params.set_current_channel("beta-channel");
559 EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
560 params.UpdateDownloadChannel();
561 params.set_app_version("12345.48.0.0");
562
563 FakeSystemState::Get()->set_request_params(¶ms);
564 InstallPlan install_plan;
565 EXPECT_TRUE(DoTest(in, "", &install_plan));
566 EXPECT_FALSE(install_plan.powerwash_required);
567 }
568
TEST_F(OmahaResponseHandlerActionTest,ChangeToMoreStableChannelButSameVersionTest)569 TEST_F(OmahaResponseHandlerActionTest,
570 ChangeToMoreStableChannelButSameVersionTest) {
571 OmahaResponse in;
572 in.update_exists = true;
573 in.version = "12345.0.0.0";
574 in.packages.push_back({.payload_urls = {"https://ChannelDownVersionUp"},
575 .size = 1,
576 .hash = kPayloadHashHex});
577 in.more_info_url = "http://more/info";
578
579 // Create a uniquely named test directory.
580 base::ScopedTempDir tempdir;
581 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
582
583 OmahaRequestParams params;
584 FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(false);
585 params.set_root(tempdir.GetPath().value());
586 params.set_current_channel("beta-channel");
587 EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
588 params.UpdateDownloadChannel();
589 params.set_app_version("12345.0.0.0");
590
591 FakeSystemState::Get()->set_request_params(¶ms);
592 InstallPlan install_plan;
593 EXPECT_TRUE(DoTest(in, "", &install_plan));
594 EXPECT_FALSE(install_plan.powerwash_required);
595 EXPECT_FALSE(install_plan.rollback_data_save_requested);
596 }
597
598 // On an enrolled device, the rollback data restore should be attempted when
599 // doing a powerwash and channel downgrade.
TEST_F(OmahaResponseHandlerActionTest,ChangeToMoreStableChannelEnrolledDataRestore)600 TEST_F(OmahaResponseHandlerActionTest,
601 ChangeToMoreStableChannelEnrolledDataRestore) {
602 OmahaResponse in;
603 in.update_exists = true;
604 in.version = "12345.96.0.0";
605 in.packages.push_back({.payload_urls = {"https://ChannelDownEnrolled"},
606 .size = 1,
607 .hash = kPayloadHashHex});
608 in.more_info_url = "http://more/info";
609
610 // Create a uniquely named test directory.
611 base::ScopedTempDir tempdir;
612 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
613
614 OmahaRequestParams params;
615 FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(true);
616 params.set_root(tempdir.GetPath().value());
617 params.set_current_channel("beta-channel");
618 EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
619 params.UpdateDownloadChannel();
620 params.set_app_version("12347.48.0.0");
621
622 testing::NiceMock<policy::MockDevicePolicy> mock_device_policy;
623 EXPECT_CALL(mock_device_policy, IsEnterpriseEnrolled())
624 .WillOnce(Return(true));
625 FakeSystemState::Get()->set_device_policy(&mock_device_policy);
626
627 FakeSystemState::Get()->set_request_params(¶ms);
628 InstallPlan install_plan;
629 EXPECT_TRUE(DoTest(in, "", &install_plan));
630 EXPECT_TRUE(install_plan.rollback_data_save_requested);
631 }
632
633 // Never attempt rollback data restore if the device is not enrolled.
TEST_F(OmahaResponseHandlerActionTest,ChangeToMoreStableChannelUnenrolledNoDataRestore)634 TEST_F(OmahaResponseHandlerActionTest,
635 ChangeToMoreStableChannelUnenrolledNoDataRestore) {
636 OmahaResponse in;
637 in.update_exists = true;
638 in.version = "12345.96.0.0";
639 in.packages.push_back({.payload_urls = {"https://ChannelDownEnrolled"},
640 .size = 1,
641 .hash = kPayloadHashHex});
642 in.more_info_url = "http://more/info";
643
644 // Create a uniquely named test directory.
645 base::ScopedTempDir tempdir;
646 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
647
648 OmahaRequestParams params;
649 FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(true);
650 params.set_root(tempdir.GetPath().value());
651 params.set_current_channel("beta-channel");
652 EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
653 params.UpdateDownloadChannel();
654 params.set_app_version("12347.48.0.0");
655
656 testing::NiceMock<policy::MockDevicePolicy> mock_device_policy;
657 EXPECT_CALL(mock_device_policy, IsEnterpriseEnrolled())
658 .WillOnce(Return(false));
659 FakeSystemState::Get()->set_device_policy(&mock_device_policy);
660
661 FakeSystemState::Get()->set_request_params(¶ms);
662 InstallPlan install_plan;
663 EXPECT_TRUE(DoTest(in, "", &install_plan));
664 EXPECT_FALSE(install_plan.rollback_data_save_requested);
665 }
666
667 // Never attempt rollback data restore if powerwash is not allowed.
TEST_F(OmahaResponseHandlerActionTest,ChangeToMoreStableChannelNoPowerwashNoDataRestore)668 TEST_F(OmahaResponseHandlerActionTest,
669 ChangeToMoreStableChannelNoPowerwashNoDataRestore) {
670 OmahaResponse in;
671 in.update_exists = true;
672 in.version = "12345.96.0.0";
673 in.packages.push_back(
674 {.payload_urls = {"https://URL"}, .size = 1, .hash = kPayloadHashHex});
675 in.more_info_url = "http://more/info";
676
677 // Create a uniquely named test directory.
678 base::ScopedTempDir tempdir;
679 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
680
681 OmahaRequestParams params;
682 FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(true);
683 params.set_root(tempdir.GetPath().value());
684 params.set_current_channel("beta-channel");
685 EXPECT_TRUE(params.SetTargetChannel("stable-channel", false, nullptr));
686 params.UpdateDownloadChannel();
687 params.set_app_version("12347.48.0.0");
688
689 FakeSystemState::Get()->set_request_params(¶ms);
690 InstallPlan install_plan;
691 EXPECT_TRUE(DoTest(in, "", &install_plan));
692 EXPECT_FALSE(install_plan.rollback_data_save_requested);
693 }
694
TEST_F(OmahaResponseHandlerActionTest,ChangeToLessStableVersionAndChannelTest)695 TEST_F(OmahaResponseHandlerActionTest,
696 ChangeToLessStableVersionAndChannelTest) {
697 OmahaResponse in;
698 in.update_exists = true;
699 in.version = "2.0.0.0";
700 in.packages.push_back({.payload_urls = {"https://LessStableChannelTest"},
701 .size = 15,
702 .hash = kPayloadHashHex});
703 in.more_info_url = "http://more/info";
704
705 // Create a uniquely named test directory.
706 base::ScopedTempDir tempdir;
707 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
708
709 OmahaRequestParams params;
710 FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(false);
711 params.set_root(tempdir.GetPath().value());
712 params.set_current_channel("stable-channel");
713 EXPECT_TRUE(params.SetTargetChannel("canary-channel", false, nullptr));
714 params.UpdateDownloadChannel();
715 params.set_app_version("1.0.0.0");
716
717 FakeSystemState::Get()->set_request_params(¶ms);
718 InstallPlan install_plan;
719 EXPECT_TRUE(DoTest(in, "", &install_plan));
720 EXPECT_FALSE(install_plan.powerwash_required);
721 }
722
TEST_F(OmahaResponseHandlerActionTest,P2PUrlIsUsedAndHashChecksMandatory)723 TEST_F(OmahaResponseHandlerActionTest, P2PUrlIsUsedAndHashChecksMandatory) {
724 OmahaResponse in;
725 in.update_exists = true;
726 in.version = "a.b.c.d";
727 in.packages.push_back(
728 {.payload_urls = {"https://would.not/cause/hash/checks"},
729 .size = 12,
730 .hash = kPayloadHashHex,
731 .app_id = kPayloadAppId,
732 .fp = kPayloadFp1});
733 in.more_info_url = "http://more/info";
734
735 OmahaRequestParams params;
736 // We're using a real OmahaRequestParams object here so we can't mock
737 // IsUpdateUrlOfficial(), but setting the update URL to the AutoUpdate test
738 // server will cause IsUpdateUrlOfficial() to return true.
739 params.set_update_url(constants::kOmahaDefaultAUTestURL);
740 FakeSystemState::Get()->set_request_params(¶ms);
741
742 EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(),
743 SetUsingP2PForDownloading(true));
744
745 string p2p_url = "http://9.8.7.6/p2p";
746 EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(), GetP2PUrl())
747 .WillRepeatedly(Return(p2p_url));
748 EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(),
749 GetUsingP2PForDownloading())
750 .WillRepeatedly(Return(true));
751
752 InstallPlan install_plan;
753 EXPECT_TRUE(DoTest(in, "", &install_plan));
754 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
755 EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
756 EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
757 EXPECT_EQ(p2p_url, install_plan.download_url);
758 EXPECT_TRUE(install_plan.hash_checks_mandatory);
759 }
760
TEST_F(OmahaResponseHandlerActionTest,RollbackTest)761 TEST_F(OmahaResponseHandlerActionTest, RollbackTest) {
762 OmahaResponse in;
763 in.update_exists = true;
764 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
765 .size = 1,
766 .hash = kPayloadHashHex});
767 in.is_rollback = true;
768
769 // The rollback payload is 2 versions behind stable.
770 in.rollback_key_version.kernel = 24;
771 in.rollback_key_version.kernel = 23;
772 in.rollback_key_version.firmware_key = 22;
773 in.rollback_key_version.firmware = 21;
774
775 OmahaResponse::RollbackKeyVersion m4;
776 m4.firmware_key = 16;
777 m4.firmware = 15;
778 m4.kernel_key = 14;
779 m4.kernel = 13;
780
781 in.past_rollback_key_version = m4;
782
783 FakeSystemState::Get()->fake_hardware()->SetMinKernelKeyVersion(0x00010002);
784 FakeSystemState::Get()->fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
785
786 FakeSystemState::Get()->fake_hardware()->SetMaxKernelKeyRollforward(
787 0xaaaaaaaa);
788 // TODO(crbug/783998): Add support for firmware when implemented.
789
790 OmahaRequestParams params;
791 params.set_rollback_allowed(true);
792 params.set_rollback_allowed_milestones(4);
793
794 FakeSystemState::Get()->set_request_params(¶ms);
795 InstallPlan install_plan;
796 EXPECT_TRUE(DoTest(in, "", &install_plan));
797 EXPECT_TRUE(install_plan.is_rollback);
798
799 // The max rollforward should be set the values of the image
800 // rollback_allowed_milestones (4 for this test) in the past.
801 const uint32_t expected_max_kernel_rollforward =
802 static_cast<uint32_t>(m4.kernel_key) << 16 |
803 static_cast<uint32_t>(m4.kernel);
804 EXPECT_EQ(
805 expected_max_kernel_rollforward,
806 FakeSystemState::Get()->fake_hardware()->GetMaxKernelKeyRollforward());
807 // TODO(crbug/783998): Add support for firmware when implemented.
808 }
809
TEST_F(OmahaResponseHandlerActionTest,RollbackKernelVersionErrorTest)810 TEST_F(OmahaResponseHandlerActionTest, RollbackKernelVersionErrorTest) {
811 OmahaResponse in;
812 in.update_exists = true;
813 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
814 .size = 1,
815 .hash = kPayloadHashHex});
816 in.is_rollback = true;
817 in.rollback_key_version.kernel_key = 1;
818 in.rollback_key_version.kernel = 1; // This is lower than the minimum.
819 in.rollback_key_version.firmware_key = 3;
820 in.rollback_key_version.firmware = 4;
821
822 OmahaResponse::RollbackKeyVersion m4;
823 m4.firmware_key = 16;
824 m4.firmware = 15;
825 m4.kernel_key = 14;
826 m4.kernel = 13;
827 in.past_rollback_key_version = m4;
828
829 FakeSystemState::Get()->fake_hardware()->SetMinKernelKeyVersion(0x00010002);
830 FakeSystemState::Get()->fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
831 const uint32_t current_kernel_max_rollforward = 0xaaaaaaaa;
832 FakeSystemState::Get()->fake_hardware()->SetMaxKernelKeyRollforward(
833 current_kernel_max_rollforward);
834
835 OmahaRequestParams params;
836 params.set_rollback_allowed(true);
837 params.set_rollback_allowed_milestones(4);
838
839 FakeSystemState::Get()->set_request_params(¶ms);
840 InstallPlan install_plan;
841 EXPECT_FALSE(DoTest(in, "", &install_plan));
842
843 // Max rollforward is not changed in error cases.
844 EXPECT_EQ(
845 current_kernel_max_rollforward,
846 FakeSystemState::Get()->fake_hardware()->GetMaxKernelKeyRollforward());
847 // TODO(crbug/783998): Add support for firmware when implemented.
848 }
849
TEST_F(OmahaResponseHandlerActionTest,RollbackFirmwareVersionErrorTest)850 TEST_F(OmahaResponseHandlerActionTest, RollbackFirmwareVersionErrorTest) {
851 // TODO(crbug/783998): Add handling for max_firmware_rollforward when
852 // implemented.
853 OmahaResponse in;
854 in.update_exists = true;
855 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
856 .size = 1,
857 .hash = kPayloadHashHex});
858 in.is_rollback = true;
859 in.rollback_key_version.kernel_key = 1;
860 in.rollback_key_version.kernel = 2;
861 in.rollback_key_version.firmware_key = 3;
862 in.rollback_key_version.firmware = 3; // This is lower than the minimum.
863
864 FakeSystemState::Get()->fake_hardware()->SetMinKernelKeyVersion(0x00010002);
865 FakeSystemState::Get()->fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
866
867 OmahaRequestParams params;
868 params.set_rollback_allowed(true);
869 params.set_rollback_allowed_milestones(4);
870
871 FakeSystemState::Get()->set_request_params(¶ms);
872 InstallPlan install_plan;
873 EXPECT_FALSE(DoTest(in, "", &install_plan));
874 }
875
TEST_F(OmahaResponseHandlerActionTest,RollbackNotRollbackTest)876 TEST_F(OmahaResponseHandlerActionTest, RollbackNotRollbackTest) {
877 OmahaResponse in;
878 in.update_exists = true;
879 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
880 .size = 1,
881 .hash = kPayloadHashHex});
882 in.is_rollback = false;
883
884 const uint32_t current_kernel_max_rollforward = 0xaaaaaaaa;
885 FakeSystemState::Get()->fake_hardware()->SetMaxKernelKeyRollforward(
886 current_kernel_max_rollforward);
887
888 OmahaRequestParams params;
889 params.set_rollback_allowed(true);
890 params.set_rollback_allowed_milestones(4);
891
892 FakeSystemState::Get()->set_request_params(¶ms);
893 InstallPlan install_plan;
894 EXPECT_TRUE(DoTest(in, "", &install_plan));
895 EXPECT_FALSE(install_plan.is_rollback);
896
897 // Max rollforward is not changed for non-rollback cases.
898 EXPECT_EQ(
899 current_kernel_max_rollforward,
900 FakeSystemState::Get()->fake_hardware()->GetMaxKernelKeyRollforward());
901 // TODO(crbug/783998): Add support for firmware when implemented.
902 }
903
TEST_F(OmahaResponseHandlerActionTest,RollbackNotAllowedTest)904 TEST_F(OmahaResponseHandlerActionTest, RollbackNotAllowedTest) {
905 OmahaResponse in;
906 in.update_exists = true;
907 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
908 .size = 1,
909 .hash = kPayloadHashHex});
910 in.is_rollback = true;
911
912 OmahaRequestParams params;
913 params.set_rollback_allowed(false);
914 params.set_rollback_allowed_milestones(4);
915
916 const uint32_t current_kernel_max_rollforward = 0xaaaaaaaa;
917 FakeSystemState::Get()->fake_hardware()->SetMaxKernelKeyRollforward(
918 current_kernel_max_rollforward);
919
920 FakeSystemState::Get()->set_request_params(¶ms);
921 InstallPlan install_plan;
922 EXPECT_FALSE(DoTest(in, "", &install_plan));
923
924 // This case generates an error so, do not update max rollforward.
925 EXPECT_EQ(
926 current_kernel_max_rollforward,
927 FakeSystemState::Get()->fake_hardware()->GetMaxKernelKeyRollforward());
928 // TODO(crbug/783998): Add support for firmware when implemented.
929 }
930
TEST_F(OmahaResponseHandlerActionTest,NormalUpdateWithZeroMilestonesAllowed)931 TEST_F(OmahaResponseHandlerActionTest, NormalUpdateWithZeroMilestonesAllowed) {
932 OmahaResponse in;
933 in.update_exists = true;
934 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
935 .size = 1,
936 .hash = kPayloadHashHex});
937 in.is_rollback = false;
938
939 OmahaRequestParams params;
940 params.set_rollback_allowed(true);
941 params.set_rollback_allowed_milestones(0);
942
943 const uint32_t current_kernel_max_rollforward = 0xaaaaaaaa;
944 FakeSystemState::Get()->fake_hardware()->SetMaxKernelKeyRollforward(
945 current_kernel_max_rollforward);
946
947 FakeSystemState::Get()->set_request_params(¶ms);
948 InstallPlan install_plan;
949 EXPECT_TRUE(DoTest(in, "", &install_plan));
950
951 // When allowed_milestones is 0, this is set to infinity.
952 EXPECT_EQ(
953 kRollforwardInfinity,
954 FakeSystemState::Get()->fake_hardware()->GetMaxKernelKeyRollforward());
955 // TODO(crbug/783998): Add support for firmware when implemented.
956 }
957
TEST_F(OmahaResponseHandlerActionTest,SystemVersionTest)958 TEST_F(OmahaResponseHandlerActionTest, SystemVersionTest) {
959 OmahaResponse in;
960 in.update_exists = true;
961 in.version = "a.b.c.d";
962 in.packages.push_back({.payload_urls = {"http://package/1"},
963 .size = 1,
964 .hash = kPayloadHashHex,
965 .app_id = kPayloadAppId,
966 .fp = kPayloadFp1});
967 in.packages.push_back({.payload_urls = {"http://package/2"},
968 .size = 2,
969 .hash = kPayloadHashHex,
970 .app_id = kPayloadAppId,
971 .fp = kPayloadFp2});
972 in.more_info_url = "http://more/info";
973 InstallPlan install_plan;
974 EXPECT_TRUE(DoTest(in, "", &install_plan));
975 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
976 EXPECT_EQ(2u, install_plan.payloads.size());
977 EXPECT_EQ(in.packages[0].size, install_plan.payloads[0].size);
978 EXPECT_EQ(in.packages[1].size, install_plan.payloads[1].size);
979 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
980 EXPECT_EQ(expected_hash_, install_plan.payloads[1].hash);
981 EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
982 EXPECT_EQ(in.packages[1].app_id, install_plan.payloads[1].app_id);
983 EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
984 EXPECT_EQ(in.packages[1].fp, install_plan.payloads[1].fp);
985 EXPECT_EQ(in.version, install_plan.version);
986 }
987
TEST_F(OmahaResponseHandlerActionTest,TestDeferredByPolicy)988 TEST_F(OmahaResponseHandlerActionTest, TestDeferredByPolicy) {
989 OmahaResponse in;
990 in.update_exists = true;
991 in.version = "a.b.c.d";
992 in.packages.push_back({.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
993 .size = 12,
994 .hash = kPayloadHashHex,
995 .app_id = kPayloadAppId,
996 .fp = kPayloadFp1});
997 // Setup the UpdateManager to disallow the update.
998 MockPolicy* mock_policy = new MockPolicy();
999 FakeUpdateManager* fake_update_manager =
1000 FakeSystemState::Get()->fake_update_manager();
1001 fake_update_manager->set_policy(mock_policy);
1002 EXPECT_CALL(*mock_policy, UpdateCanBeApplied(_, _, _, _, _))
1003 .WillOnce(
1004 DoAll(SetArgPointee<3>(ErrorCode::kOmahaUpdateDeferredPerPolicy),
1005 Return(EvalStatus::kSucceeded)));
1006 // Perform the Action. It should "fail" with kOmahaUpdateDeferredPerPolicy.
1007 InstallPlan install_plan;
1008 EXPECT_FALSE(DoTest(in, "", &install_plan));
1009 EXPECT_EQ(ErrorCode::kOmahaUpdateDeferredPerPolicy, action_result_code_);
1010 // Verify that DoTest() didn't set the output install plan.
1011 EXPECT_EQ("", install_plan.version);
1012 // Now verify the InstallPlan that was generated.
1013 install_plan = *delegate_.response_handler_action_install_plan_;
1014 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
1015 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
1016 EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
1017 EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
1018 EXPECT_EQ(1U, install_plan.target_slot);
1019 EXPECT_EQ(in.version, install_plan.version);
1020 }
1021
1022 } // namespace chromeos_update_engine
1023