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(&params);
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(&params);
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(&params);
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(&params);
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(&params);
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(&params);
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(&params);
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(&params);
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(&params);
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(&params);
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(&params);
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(&params);
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(&params);
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(&params);
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(&params);
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(&params);
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