blob: 5281c88a626ad949c4d56840513f6a3c29a97658 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2011 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
adlr@google.com3defe6a2009-12-04 20:57:17 +000016
Alex Deymoaab50e32014-11-10 19:55:35 -080017#include "update_engine/omaha_response_handler_action.h"
18
Aaron Woodc73fdc12017-12-06 11:09:15 -080019#include <memory>
adlr@google.com3defe6a2009-12-04 20:57:17 +000020#include <string>
Amin Hassanid3f4bea2018-04-30 14:52:40 -070021#include <utility>
Darin Petkov73058b42010-10-06 16:32:19 -070022
Alex Deymo110e0302015-10-19 20:35:21 -070023#include <base/files/file_util.h>
Sen Jiang297e5832016-03-17 14:45:51 -070024#include <base/files/scoped_temp_dir.h>
Aaron Wood23bd3392017-10-06 14:48:25 -070025#include <brillo/message_loops/fake_message_loop.h>
adlr@google.com3defe6a2009-12-04 20:57:17 +000026#include <gtest/gtest.h>
Darin Petkov73058b42010-10-06 16:32:19 -070027
Alex Deymo39910dc2015-11-09 17:04:30 -080028#include "update_engine/common/constants.h"
29#include "update_engine/common/platform_constants.h"
30#include "update_engine/common/test_utils.h"
31#include "update_engine/common/utils.h"
Gilad Arnold5bb4c902014-04-10 12:32:13 -070032#include "update_engine/fake_system_state.h"
Gilad Arnold74b5f552014-10-07 08:17:16 -070033#include "update_engine/mock_payload_state.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080034#include "update_engine/payload_consumer/payload_constants.h"
Aaron Wood23bd3392017-10-06 14:48:25 -070035#include "update_engine/update_manager/mock_policy.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000036
Alex Deymo10875d92014-11-10 21:52:57 -080037using chromeos_update_engine::test_utils::System;
38using chromeos_update_engine::test_utils::WriteFileString;
Aaron Wood23bd3392017-10-06 14:48:25 -070039using chromeos_update_manager::EvalStatus;
40using chromeos_update_manager::FakeUpdateManager;
41using chromeos_update_manager::MockPolicy;
adlr@google.com3defe6a2009-12-04 20:57:17 +000042using std::string;
Aaron Woodc73fdc12017-12-06 11:09:15 -080043using testing::_;
Aaron Wood23bd3392017-10-06 14:48:25 -070044using testing::DoAll;
Darin Petkov73058b42010-10-06 16:32:19 -070045using testing::Return;
Aaron Wood23bd3392017-10-06 14:48:25 -070046using testing::SetArgPointee;
adlr@google.com3defe6a2009-12-04 20:57:17 +000047
48namespace chromeos_update_engine {
49
Amin Hassanid3f4bea2018-04-30 14:52:40 -070050class OmahaResponseHandlerActionProcessorDelegate
51 : public ActionProcessorDelegate {
52 public:
53 OmahaResponseHandlerActionProcessorDelegate()
54 : code_(ErrorCode::kError), code_set_(false) {}
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
adlr@google.com3defe6a2009-12-04 20:57:17 +000079class OmahaResponseHandlerActionTest : public ::testing::Test {
Alex Deymo763e7db2015-08-27 21:08:08 -070080 protected:
81 void SetUp() override {
82 FakeBootControl* fake_boot_control = fake_system_state_.fake_boot_control();
83 fake_boot_control->SetPartitionDevice(
Tudor Brindusdda79e22018-06-28 18:03:21 -070084 kPartitionNameKernel, 0, "/dev/sdz2");
Alex Deymo763e7db2015-08-27 21:08:08 -070085 fake_boot_control->SetPartitionDevice(
Tudor Brindusdda79e22018-06-28 18:03:21 -070086 kPartitionNameRoot, 0, "/dev/sdz3");
Alex Deymo763e7db2015-08-27 21:08:08 -070087 fake_boot_control->SetPartitionDevice(
Tudor Brindusdda79e22018-06-28 18:03:21 -070088 kPartitionNameKernel, 1, "/dev/sdz4");
Alex Deymo763e7db2015-08-27 21:08:08 -070089 fake_boot_control->SetPartitionDevice(
Tudor Brindusdda79e22018-06-28 18:03:21 -070090 kPartitionNameRoot, 1, "/dev/sdz5");
Alex Deymo763e7db2015-08-27 21:08:08 -070091 }
92
adlr@google.com3defe6a2009-12-04 20:57:17 +000093 // Return true iff the OmahaResponseHandlerAction succeeded.
Alex Vakulenko88b591f2014-08-28 16:48:57 -070094 // If out is non-null, it's set w/ the response from the action.
Darin Petkov6a5b3222010-07-13 14:55:28 -070095 bool DoTest(const OmahaResponse& in,
Gilad Arnold4dbd47e2013-07-22 05:39:26 -070096 const string& deadline_file,
adlr@google.com3defe6a2009-12-04 20:57:17 +000097 InstallPlan* out);
Alex Deymo763e7db2015-08-27 21:08:08 -070098
Amin Hassanid3f4bea2018-04-30 14:52:40 -070099 // Delegate passed to the ActionProcessor.
100 OmahaResponseHandlerActionProcessorDelegate delegate_;
101
Aaron Wood23bd3392017-10-06 14:48:25 -0700102 // Captures the action's result code, for tests that need to directly verify
103 // it in non-success cases.
104 ErrorCode action_result_code_;
105
Alex Deymo763e7db2015-08-27 21:08:08 -0700106 FakeSystemState fake_system_state_;
Sen Jiang2703ef42017-03-16 13:36:21 -0700107 // "Hash+"
108 const brillo::Blob expected_hash_ = {0x48, 0x61, 0x73, 0x68, 0x2b};
adlr@google.com3defe6a2009-12-04 20:57:17 +0000109};
110
adlr@google.com3defe6a2009-12-04 20:57:17 +0000111namespace {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700112const char* const kLongName =
adlr@google.com3defe6a2009-12-04 20:57:17 +0000113 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
114 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
115 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
116 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
117 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
118 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
119 "very_long_name_and_no_slashes-very_long_name_and_no_slashes"
120 "-the_update_a.b.c.d_DELTA_.tgz";
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700121const char* const kBadVersion = "don't update me";
Sen Jiang2703ef42017-03-16 13:36:21 -0700122const char* const kPayloadHashHex = "486173682b";
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700123} // namespace
adlr@google.com3defe6a2009-12-04 20:57:17 +0000124
Aaron Woodc73fdc12017-12-06 11:09:15 -0800125bool OmahaResponseHandlerActionTest::DoTest(const OmahaResponse& in,
126 const string& test_deadline_file,
127 InstallPlan* out) {
Aaron Wood23bd3392017-10-06 14:48:25 -0700128 brillo::FakeMessageLoop loop(nullptr);
129 loop.SetAsCurrent();
adlr@google.com3defe6a2009-12-04 20:57:17 +0000130 ActionProcessor processor;
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700131 processor.set_delegate(&delegate_);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000132
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700133 auto feeder_action = std::make_unique<ObjectFeederAction<OmahaResponse>>();
134 feeder_action->set_obj(in);
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700135 if (in.update_exists && in.version != kBadVersion) {
Sen Jiang0affc2c2017-02-10 15:55:05 -0800136 string expected_hash;
137 for (const auto& package : in.packages)
138 expected_hash += package.hash + ":";
Alex Deymo763e7db2015-08-27 21:08:08 -0700139 EXPECT_CALL(*(fake_system_state_.mock_prefs()),
Sen Jiang0affc2c2017-02-10 15:55:05 -0800140 SetString(kPrefsUpdateCheckResponseHash, expected_hash))
Darin Petkov73058b42010-10-06 16:32:19 -0700141 .WillOnce(Return(true));
Alex Deymo85616652015-10-15 18:48:31 -0700142
Xiaochu Liu88d90382018-08-29 16:09:11 -0700143 int slot =
144 fake_system_state_.request_params()->is_install()
145 ? fake_system_state_.fake_boot_control()->GetCurrentSlot()
146 : 1 - fake_system_state_.fake_boot_control()->GetCurrentSlot();
Alex Deymo85616652015-10-15 18:48:31 -0700147 string key = kPrefsChannelOnSlotPrefix + std::to_string(slot);
148 EXPECT_CALL(*(fake_system_state_.mock_prefs()), SetString(key, testing::_))
149 .WillOnce(Return(true));
Darin Petkov73058b42010-10-06 16:32:19 -0700150 }
Jay Srinivasan53173b92013-05-17 17:13:01 -0700151
Sen Jiang0affc2c2017-02-10 15:55:05 -0800152 string current_url = in.packages.size() ? in.packages[0].payload_urls[0] : "";
Alex Deymo763e7db2015-08-27 21:08:08 -0700153 EXPECT_CALL(*(fake_system_state_.mock_payload_state()), GetCurrentUrl())
Jay Srinivasan53173b92013-05-17 17:13:01 -0700154 .WillRepeatedly(Return(current_url));
155
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700156 auto response_handler_action =
157 std::make_unique<OmahaResponseHandlerAction>(&fake_system_state_);
158 if (!test_deadline_file.empty())
159 response_handler_action->deadline_file_ = test_deadline_file;
160
161 auto collector_action =
162 std::make_unique<ObjectCollectorAction<InstallPlan>>();
163
164 BondActions(feeder_action.get(), response_handler_action.get());
165 BondActions(response_handler_action.get(), collector_action.get());
166 processor.EnqueueAction(std::move(feeder_action));
167 processor.EnqueueAction(std::move(response_handler_action));
168 processor.EnqueueAction(std::move(collector_action));
adlr@google.com3defe6a2009-12-04 20:57:17 +0000169 processor.StartProcessing();
170 EXPECT_TRUE(!processor.IsRunning())
Alex Vakulenko072359c2014-07-18 11:41:07 -0700171 << "Update test to handle non-async actions";
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700172
173 if (out && delegate_.collector_action_install_plan_)
174 *out = *delegate_.collector_action_install_plan_;
175
176 EXPECT_TRUE(delegate_.code_set_);
177 action_result_code_ = delegate_.code_;
178 return delegate_.code_ == ErrorCode::kSuccess;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000179}
180
181TEST_F(OmahaResponseHandlerActionTest, SimpleTest) {
Gilad Arnold4dbd47e2013-07-22 05:39:26 -0700182 string test_deadline_file;
Aaron Woodc73fdc12017-12-06 11:09:15 -0800183 CHECK(utils::MakeTempFile("omaha_response_handler_action_unittest-XXXXXX",
184 &test_deadline_file,
185 nullptr));
Gilad Arnold4dbd47e2013-07-22 05:39:26 -0700186 ScopedPathUnlinker deadline_unlinker(test_deadline_file);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000187 {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700188 OmahaResponse in;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000189 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700190 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800191 in.packages.push_back(
192 {.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
193 .size = 12,
194 .hash = kPayloadHashHex});
adlr@google.com3defe6a2009-12-04 20:57:17 +0000195 in.more_info_url = "http://more/info";
adlr@google.com3defe6a2009-12-04 20:57:17 +0000196 in.prompt = false;
Darin Petkov6c118642010-10-21 12:06:30 -0700197 in.deadline = "20101020";
adlr@google.com3defe6a2009-12-04 20:57:17 +0000198 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700199 EXPECT_TRUE(DoTest(in, test_deadline_file, &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800200 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
201 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Alex Deymo80f70ff2016-02-10 16:08:11 -0800202 EXPECT_EQ(1U, install_plan.target_slot);
Darin Petkov6c118642010-10-21 12:06:30 -0700203 string deadline;
Gilad Arnold4dbd47e2013-07-22 05:39:26 -0700204 EXPECT_TRUE(utils::ReadFile(test_deadline_file, &deadline));
Darin Petkov6c118642010-10-21 12:06:30 -0700205 EXPECT_EQ("20101020", deadline);
206 struct stat deadline_stat;
Gilad Arnold4dbd47e2013-07-22 05:39:26 -0700207 EXPECT_EQ(0, stat(test_deadline_file.c_str(), &deadline_stat));
Alex Deymo80f70ff2016-02-10 16:08:11 -0800208 EXPECT_EQ(
209 static_cast<mode_t>(S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),
210 deadline_stat.st_mode);
Chris Sosafb1020e2013-07-29 17:27:33 -0700211 EXPECT_EQ(in.version, install_plan.version);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000212 }
213 {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700214 OmahaResponse in;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000215 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700216 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800217 in.packages.push_back(
218 {.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
219 .size = 12,
220 .hash = kPayloadHashHex});
adlr@google.com3defe6a2009-12-04 20:57:17 +0000221 in.more_info_url = "http://more/info";
adlr@google.com3defe6a2009-12-04 20:57:17 +0000222 in.prompt = true;
223 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700224 // Set the other slot as current.
225 fake_system_state_.fake_boot_control()->SetCurrentSlot(1);
226 EXPECT_TRUE(DoTest(in, test_deadline_file, &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800227 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
228 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Alex Deymo80f70ff2016-02-10 16:08:11 -0800229 EXPECT_EQ(0U, install_plan.target_slot);
Darin Petkov6c118642010-10-21 12:06:30 -0700230 string deadline;
Gilad Arnold4dbd47e2013-07-22 05:39:26 -0700231 EXPECT_TRUE(utils::ReadFile(test_deadline_file, &deadline) &&
232 deadline.empty());
Chris Sosafb1020e2013-07-29 17:27:33 -0700233 EXPECT_EQ(in.version, install_plan.version);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000234 }
235 {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700236 OmahaResponse in;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000237 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700238 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800239 in.packages.push_back(
240 {.payload_urls = {kLongName}, .size = 12, .hash = kPayloadHashHex});
adlr@google.com3defe6a2009-12-04 20:57:17 +0000241 in.more_info_url = "http://more/info";
adlr@google.com3defe6a2009-12-04 20:57:17 +0000242 in.prompt = true;
Darin Petkov6c118642010-10-21 12:06:30 -0700243 in.deadline = "some-deadline";
adlr@google.com3defe6a2009-12-04 20:57:17 +0000244 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700245 fake_system_state_.fake_boot_control()->SetCurrentSlot(0);
Marton Hunyadye58bddb2018-04-10 20:27:26 +0200246 // Because rollback happened, the deadline shouldn't be written into the
247 // file.
248 EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
249 GetRollbackHappened())
250 .WillOnce(Return(true));
251 EXPECT_TRUE(DoTest(in, test_deadline_file, &install_plan));
252 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
253 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
254 EXPECT_EQ(1U, install_plan.target_slot);
255 string deadline;
256 EXPECT_TRUE(utils::ReadFile(test_deadline_file, &deadline));
257 EXPECT_TRUE(deadline.empty());
258 EXPECT_EQ(in.version, install_plan.version);
259 }
260 {
261 OmahaResponse in;
262 in.update_exists = true;
263 in.version = "a.b.c.d";
264 in.packages.push_back(
265 {.payload_urls = {kLongName}, .size = 12, .hash = kPayloadHashHex});
266 in.more_info_url = "http://more/info";
267 in.prompt = true;
268 in.deadline = "some-deadline";
269 InstallPlan install_plan;
270 fake_system_state_.fake_boot_control()->SetCurrentSlot(0);
271 EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
272 GetRollbackHappened())
273 .WillOnce(Return(false));
Alex Deymo763e7db2015-08-27 21:08:08 -0700274 EXPECT_TRUE(DoTest(in, test_deadline_file, &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800275 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
276 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Alex Deymo80f70ff2016-02-10 16:08:11 -0800277 EXPECT_EQ(1U, install_plan.target_slot);
Darin Petkov6c118642010-10-21 12:06:30 -0700278 string deadline;
Gilad Arnold4dbd47e2013-07-22 05:39:26 -0700279 EXPECT_TRUE(utils::ReadFile(test_deadline_file, &deadline));
Darin Petkov6c118642010-10-21 12:06:30 -0700280 EXPECT_EQ("some-deadline", deadline);
Chris Sosafb1020e2013-07-29 17:27:33 -0700281 EXPECT_EQ(in.version, install_plan.version);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000282 }
283}
284
285TEST_F(OmahaResponseHandlerActionTest, NoUpdatesTest) {
Darin Petkov6a5b3222010-07-13 14:55:28 -0700286 OmahaResponse in;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000287 in.update_exists = false;
288 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700289 EXPECT_FALSE(DoTest(in, "", &install_plan));
Alex Deymoe5e5fe92015-10-05 09:28:19 -0700290 EXPECT_TRUE(install_plan.partitions.empty());
adlr@google.com3defe6a2009-12-04 20:57:17 +0000291}
292
Xiaochu Liu88d90382018-08-29 16:09:11 -0700293TEST_F(OmahaResponseHandlerActionTest, InstallTest) {
294 OmahaResponse in;
295 in.update_exists = true;
296 in.version = "a.b.c.d";
297 in.packages.push_back(
298 {.payload_urls = {kLongName}, .size = 1, .hash = kPayloadHashHex});
299 in.packages.push_back(
300 {.payload_urls = {kLongName}, .size = 2, .hash = kPayloadHashHex});
301 in.more_info_url = "http://more/info";
302
303 OmahaRequestParams params(&fake_system_state_);
304 params.set_is_install(true);
305
306 fake_system_state_.set_request_params(&params);
307 InstallPlan install_plan;
308 EXPECT_TRUE(DoTest(in, "", &install_plan));
309 EXPECT_EQ(install_plan.source_slot, UINT_MAX);
310}
311
Sen Jiang0affc2c2017-02-10 15:55:05 -0800312TEST_F(OmahaResponseHandlerActionTest, MultiPackageTest) {
313 OmahaResponse in;
314 in.update_exists = true;
315 in.version = "a.b.c.d";
316 in.packages.push_back({.payload_urls = {"http://package/1"},
317 .size = 1,
318 .hash = kPayloadHashHex});
319 in.packages.push_back({.payload_urls = {"http://package/2"},
320 .size = 2,
321 .hash = kPayloadHashHex});
322 in.more_info_url = "http://more/info";
323 InstallPlan install_plan;
324 EXPECT_TRUE(DoTest(in, "", &install_plan));
325 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
326 EXPECT_EQ(2u, install_plan.payloads.size());
327 EXPECT_EQ(in.packages[0].size, install_plan.payloads[0].size);
328 EXPECT_EQ(in.packages[1].size, install_plan.payloads[1].size);
329 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
330 EXPECT_EQ(expected_hash_, install_plan.payloads[1].hash);
331 EXPECT_EQ(in.version, install_plan.version);
332}
333
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800334TEST_F(OmahaResponseHandlerActionTest, HashChecksForHttpTest) {
335 OmahaResponse in;
336 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700337 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800338 in.packages.push_back(
339 {.payload_urls = {"http://test.should/need/hash.checks.signed"},
340 .size = 12,
341 .hash = kPayloadHashHex});
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800342 in.more_info_url = "http://more/info";
David Pursell02c18642014-11-06 11:26:11 -0800343 // Hash checks are always skipped for non-official update URLs.
Alex Deymo763e7db2015-08-27 21:08:08 -0700344 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
David Pursell02c18642014-11-06 11:26:11 -0800345 IsUpdateUrlOfficial())
346 .WillRepeatedly(Return(true));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800347 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700348 EXPECT_TRUE(DoTest(in, "", &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800349 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
350 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800351 EXPECT_TRUE(install_plan.hash_checks_mandatory);
Chris Sosafb1020e2013-07-29 17:27:33 -0700352 EXPECT_EQ(in.version, install_plan.version);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800353}
354
David Pursell02c18642014-11-06 11:26:11 -0800355TEST_F(OmahaResponseHandlerActionTest, HashChecksForUnofficialUpdateUrl) {
356 OmahaResponse in;
357 in.update_exists = true;
358 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800359 in.packages.push_back(
360 {.payload_urls = {"http://url.normally/needs/hash.checks.signed"},
361 .size = 12,
362 .hash = kPayloadHashHex});
David Pursell02c18642014-11-06 11:26:11 -0800363 in.more_info_url = "http://more/info";
Alex Deymo763e7db2015-08-27 21:08:08 -0700364 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
David Pursell02c18642014-11-06 11:26:11 -0800365 IsUpdateUrlOfficial())
366 .WillRepeatedly(Return(false));
367 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700368 EXPECT_TRUE(DoTest(in, "", &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800369 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
370 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
David Pursell02c18642014-11-06 11:26:11 -0800371 EXPECT_FALSE(install_plan.hash_checks_mandatory);
372 EXPECT_EQ(in.version, install_plan.version);
373}
374
David Pursell907b4fa2015-01-27 10:27:38 -0800375TEST_F(OmahaResponseHandlerActionTest,
376 HashChecksForOfficialUrlUnofficialBuildTest) {
377 // Official URLs for unofficial builds (dev/test images) don't require hash.
378 OmahaResponse in;
379 in.update_exists = true;
380 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800381 in.packages.push_back(
382 {.payload_urls = {"http://url.normally/needs/hash.checks.signed"},
383 .size = 12,
384 .hash = kPayloadHashHex});
David Pursell907b4fa2015-01-27 10:27:38 -0800385 in.more_info_url = "http://more/info";
Alex Deymo763e7db2015-08-27 21:08:08 -0700386 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
David Pursell907b4fa2015-01-27 10:27:38 -0800387 IsUpdateUrlOfficial())
388 .WillRepeatedly(Return(true));
Alex Deymo763e7db2015-08-27 21:08:08 -0700389 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
David Pursell907b4fa2015-01-27 10:27:38 -0800390 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700391 EXPECT_TRUE(DoTest(in, "", &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800392 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
393 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
David Pursell907b4fa2015-01-27 10:27:38 -0800394 EXPECT_FALSE(install_plan.hash_checks_mandatory);
395 EXPECT_EQ(in.version, install_plan.version);
396}
397
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800398TEST_F(OmahaResponseHandlerActionTest, HashChecksForHttpsTest) {
399 OmahaResponse in;
400 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700401 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800402 in.packages.push_back(
403 {.payload_urls = {"https://test.should/need/hash.checks.signed"},
404 .size = 12,
405 .hash = kPayloadHashHex});
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800406 in.more_info_url = "http://more/info";
Alex Deymo763e7db2015-08-27 21:08:08 -0700407 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
David Pursell02c18642014-11-06 11:26:11 -0800408 IsUpdateUrlOfficial())
409 .WillRepeatedly(Return(true));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800410 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700411 EXPECT_TRUE(DoTest(in, "", &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800412 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
413 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800414 EXPECT_FALSE(install_plan.hash_checks_mandatory);
Chris Sosafb1020e2013-07-29 17:27:33 -0700415 EXPECT_EQ(in.version, install_plan.version);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800416}
417
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800418TEST_F(OmahaResponseHandlerActionTest, HashChecksForBothHttpAndHttpsTest) {
419 OmahaResponse in;
420 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700421 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800422 in.packages.push_back(
423 {.payload_urls = {"http://test.should.still/need/hash.checks",
424 "https://test.should.still/need/hash.checks"},
425 .size = 12,
426 .hash = kPayloadHashHex});
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800427 in.more_info_url = "http://more/info";
Alex Deymo763e7db2015-08-27 21:08:08 -0700428 EXPECT_CALL(*(fake_system_state_.mock_request_params()),
David Pursell02c18642014-11-06 11:26:11 -0800429 IsUpdateUrlOfficial())
430 .WillRepeatedly(Return(true));
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800431 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700432 EXPECT_TRUE(DoTest(in, "", &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800433 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
434 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800435 EXPECT_TRUE(install_plan.hash_checks_mandatory);
Chris Sosafb1020e2013-07-29 17:27:33 -0700436 EXPECT_EQ(in.version, install_plan.version);
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800437}
438
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700439TEST_F(OmahaResponseHandlerActionTest, ChangeToMoreStableChannelTest) {
440 OmahaResponse in;
441 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700442 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800443 in.packages.push_back({.payload_urls = {"https://MoreStableChannelTest"},
444 .size = 1,
445 .hash = kPayloadHashHex});
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700446 in.more_info_url = "http://more/info";
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700447
Gilad Arnoldeff87cc2013-07-22 18:32:09 -0700448 // Create a uniquely named test directory.
Sen Jiang297e5832016-03-17 14:45:51 -0700449 base::ScopedTempDir tempdir;
450 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700451
Alex Deymo763e7db2015-08-27 21:08:08 -0700452 OmahaRequestParams params(&fake_system_state_);
Alex Deymo85616652015-10-15 18:48:31 -0700453 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
Hidehiko Abe2b9d2412017-12-13 18:56:18 +0900454 params.set_root(tempdir.GetPath().value());
Sen Jiang297e5832016-03-17 14:45:51 -0700455 params.set_current_channel("canary-channel");
456 // The ImageProperties in Android uses prefs to store MutableImageProperties.
457#ifdef __ANDROID__
Sen Jiang297e5832016-03-17 14:45:51 -0700458 EXPECT_CALL(*fake_system_state_.mock_prefs(), SetBoolean(_, true))
459 .WillOnce(Return(true));
460#endif // __ANDROID__
461 EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
462 params.UpdateDownloadChannel();
Sen Jiang8500d3a2018-02-08 12:04:05 -0800463 EXPECT_TRUE(params.ShouldPowerwash());
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700464
Alex Deymo763e7db2015-08-27 21:08:08 -0700465 fake_system_state_.set_request_params(&params);
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700466 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700467 EXPECT_TRUE(DoTest(in, "", &install_plan));
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700468 EXPECT_TRUE(install_plan.powerwash_required);
469}
470
471TEST_F(OmahaResponseHandlerActionTest, ChangeToLessStableChannelTest) {
472 OmahaResponse in;
473 in.update_exists = true;
Chris Sosa3b748432013-06-20 16:42:59 -0700474 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800475 in.packages.push_back({.payload_urls = {"https://LessStableChannelTest"},
476 .size = 15,
477 .hash = kPayloadHashHex});
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700478 in.more_info_url = "http://more/info";
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700479
Gilad Arnoldeff87cc2013-07-22 18:32:09 -0700480 // Create a uniquely named test directory.
Sen Jiang297e5832016-03-17 14:45:51 -0700481 base::ScopedTempDir tempdir;
482 ASSERT_TRUE(tempdir.CreateUniqueTempDir());
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700483
Alex Deymo763e7db2015-08-27 21:08:08 -0700484 OmahaRequestParams params(&fake_system_state_);
Alex Deymo85616652015-10-15 18:48:31 -0700485 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
Hidehiko Abe2b9d2412017-12-13 18:56:18 +0900486 params.set_root(tempdir.GetPath().value());
Sen Jiang297e5832016-03-17 14:45:51 -0700487 params.set_current_channel("stable-channel");
488 // The ImageProperties in Android uses prefs to store MutableImageProperties.
489#ifdef __ANDROID__
Sen Jiang297e5832016-03-17 14:45:51 -0700490 EXPECT_CALL(*fake_system_state_.mock_prefs(), SetBoolean(_, false))
491 .WillOnce(Return(true));
492#endif // __ANDROID__
493 EXPECT_TRUE(params.SetTargetChannel("canary-channel", false, nullptr));
494 params.UpdateDownloadChannel();
Sen Jiang8500d3a2018-02-08 12:04:05 -0800495 EXPECT_FALSE(params.ShouldPowerwash());
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700496
Alex Deymo763e7db2015-08-27 21:08:08 -0700497 fake_system_state_.set_request_params(&params);
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700498 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700499 EXPECT_TRUE(DoTest(in, "", &install_plan));
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700500 EXPECT_FALSE(install_plan.powerwash_required);
501}
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800502
David Zeuthen8f191b22013-08-06 12:27:50 -0700503TEST_F(OmahaResponseHandlerActionTest, P2PUrlIsUsedAndHashChecksMandatory) {
504 OmahaResponse in;
505 in.update_exists = true;
506 in.version = "a.b.c.d";
Sen Jiang0affc2c2017-02-10 15:55:05 -0800507 in.packages.push_back(
508 {.payload_urls = {"https://would.not/cause/hash/checks"},
509 .size = 12,
510 .hash = kPayloadHashHex});
David Zeuthen8f191b22013-08-06 12:27:50 -0700511 in.more_info_url = "http://more/info";
David Zeuthen8f191b22013-08-06 12:27:50 -0700512
Alex Deymo763e7db2015-08-27 21:08:08 -0700513 OmahaRequestParams params(&fake_system_state_);
David Pursell02c18642014-11-06 11:26:11 -0800514 // We're using a real OmahaRequestParams object here so we can't mock
515 // IsUpdateUrlOfficial(), but setting the update URL to the AutoUpdate test
516 // server will cause IsUpdateUrlOfficial() to return true.
Alex Deymoac41a822015-09-15 20:52:53 -0700517 params.set_update_url(constants::kOmahaDefaultAUTestURL);
Alex Deymo763e7db2015-08-27 21:08:08 -0700518 fake_system_state_.set_request_params(&params);
David Zeuthen8f191b22013-08-06 12:27:50 -0700519
Alex Deymo763e7db2015-08-27 21:08:08 -0700520 EXPECT_CALL(*fake_system_state_.mock_payload_state(),
David Zeuthenbb8bdc72013-09-03 13:43:48 -0700521 SetUsingP2PForDownloading(true));
522
David Zeuthen8f191b22013-08-06 12:27:50 -0700523 string p2p_url = "http://9.8.7.6/p2p";
Alex Deymo763e7db2015-08-27 21:08:08 -0700524 EXPECT_CALL(*fake_system_state_.mock_payload_state(), GetP2PUrl())
Gilad Arnold74b5f552014-10-07 08:17:16 -0700525 .WillRepeatedly(Return(p2p_url));
Alex Deymo763e7db2015-08-27 21:08:08 -0700526 EXPECT_CALL(*fake_system_state_.mock_payload_state(),
Aaron Woodc73fdc12017-12-06 11:09:15 -0800527 GetUsingP2PForDownloading())
528 .WillRepeatedly(Return(true));
David Zeuthen8f191b22013-08-06 12:27:50 -0700529
530 InstallPlan install_plan;
Alex Deymo763e7db2015-08-27 21:08:08 -0700531 EXPECT_TRUE(DoTest(in, "", &install_plan));
Sen Jiang0affc2c2017-02-10 15:55:05 -0800532 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
Sen Jiang2703ef42017-03-16 13:36:21 -0700533 EXPECT_EQ(p2p_url, install_plan.download_url);
David Zeuthen8f191b22013-08-06 12:27:50 -0700534 EXPECT_TRUE(install_plan.hash_checks_mandatory);
535}
536
Marton Hunyady199152d2018-05-07 19:08:48 +0200537TEST_F(OmahaResponseHandlerActionTest, RollbackTest) {
538 OmahaResponse in;
539 in.update_exists = true;
540 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
541 .size = 1,
542 .hash = kPayloadHashHex});
543 in.is_rollback = true;
Zentaro Kavanagh0ff621c2018-07-13 13:06:56 -0700544 in.rollback_key_version.kernel = 1;
545 in.rollback_key_version.kernel = 2;
546 in.rollback_key_version.firmware_key = 3;
547 in.rollback_key_version.firmware = 4;
Marton Hunyady199152d2018-05-07 19:08:48 +0200548
549 fake_system_state_.fake_hardware()->SetMinKernelKeyVersion(0x00010002);
550 fake_system_state_.fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
551
552 OmahaRequestParams params(&fake_system_state_);
553 params.set_rollback_allowed(true);
554
555 fake_system_state_.set_request_params(&params);
556 InstallPlan install_plan;
557 EXPECT_TRUE(DoTest(in, "", &install_plan));
558 EXPECT_TRUE(install_plan.is_rollback);
559}
560
561TEST_F(OmahaResponseHandlerActionTest, RollbackKernelVersionErrorTest) {
562 OmahaResponse in;
563 in.update_exists = true;
564 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
565 .size = 1,
566 .hash = kPayloadHashHex});
567 in.is_rollback = true;
Zentaro Kavanagh0ff621c2018-07-13 13:06:56 -0700568 in.rollback_key_version.kernel_key = 1;
569 in.rollback_key_version.kernel = 1; // This is lower than the minimum.
570 in.rollback_key_version.firmware_key = 3;
571 in.rollback_key_version.firmware = 4;
Marton Hunyady199152d2018-05-07 19:08:48 +0200572
573 fake_system_state_.fake_hardware()->SetMinKernelKeyVersion(0x00010002);
574 fake_system_state_.fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
575
576 OmahaRequestParams params(&fake_system_state_);
577 params.set_rollback_allowed(true);
578
579 fake_system_state_.set_request_params(&params);
580 InstallPlan install_plan;
581 EXPECT_FALSE(DoTest(in, "", &install_plan));
582}
583
584TEST_F(OmahaResponseHandlerActionTest, RollbackFirmwareVersionErrorTest) {
585 OmahaResponse in;
586 in.update_exists = true;
587 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
588 .size = 1,
589 .hash = kPayloadHashHex});
590 in.is_rollback = true;
Zentaro Kavanagh0ff621c2018-07-13 13:06:56 -0700591 in.rollback_key_version.kernel_key = 1;
592 in.rollback_key_version.kernel = 2;
593 in.rollback_key_version.firmware_key = 3;
594 in.rollback_key_version.firmware = 3; // This is lower than the minimum.
Marton Hunyady199152d2018-05-07 19:08:48 +0200595
596 fake_system_state_.fake_hardware()->SetMinKernelKeyVersion(0x00010002);
597 fake_system_state_.fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
598
599 OmahaRequestParams params(&fake_system_state_);
600 params.set_rollback_allowed(true);
601
602 fake_system_state_.set_request_params(&params);
603 InstallPlan install_plan;
604 EXPECT_FALSE(DoTest(in, "", &install_plan));
605}
606
607TEST_F(OmahaResponseHandlerActionTest, RollbackNotRollbackTest) {
608 OmahaResponse in;
609 in.update_exists = true;
610 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
611 .size = 1,
612 .hash = kPayloadHashHex});
613 in.is_rollback = false;
614
615 OmahaRequestParams params(&fake_system_state_);
616 params.set_rollback_allowed(true);
617
618 fake_system_state_.set_request_params(&params);
619 InstallPlan install_plan;
620 EXPECT_TRUE(DoTest(in, "", &install_plan));
621 EXPECT_FALSE(install_plan.is_rollback);
622}
623
624TEST_F(OmahaResponseHandlerActionTest, RollbackNotAllowedTest) {
625 OmahaResponse in;
626 in.update_exists = true;
627 in.packages.push_back({.payload_urls = {"https://RollbackTest"},
628 .size = 1,
629 .hash = kPayloadHashHex});
630 in.is_rollback = true;
631
632 OmahaRequestParams params(&fake_system_state_);
633 params.set_rollback_allowed(false);
634
635 fake_system_state_.set_request_params(&params);
636 InstallPlan install_plan;
637 EXPECT_FALSE(DoTest(in, "", &install_plan));
638}
639
Aaron Wood7dcdedf2017-09-06 17:17:41 -0700640TEST_F(OmahaResponseHandlerActionTest, SystemVersionTest) {
641 OmahaResponse in;
642 in.update_exists = true;
643 in.version = "a.b.c.d";
644 in.system_version = "b.c.d.e";
645 in.packages.push_back({.payload_urls = {"http://package/1"},
646 .size = 1,
647 .hash = kPayloadHashHex});
648 in.packages.push_back({.payload_urls = {"http://package/2"},
649 .size = 2,
650 .hash = kPayloadHashHex});
651 in.more_info_url = "http://more/info";
652 InstallPlan install_plan;
653 EXPECT_TRUE(DoTest(in, "", &install_plan));
654 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
655 EXPECT_EQ(2u, install_plan.payloads.size());
656 EXPECT_EQ(in.packages[0].size, install_plan.payloads[0].size);
657 EXPECT_EQ(in.packages[1].size, install_plan.payloads[1].size);
658 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
659 EXPECT_EQ(expected_hash_, install_plan.payloads[1].hash);
660 EXPECT_EQ(in.version, install_plan.version);
661 EXPECT_EQ(in.system_version, install_plan.system_version);
662}
663
Aaron Wood23bd3392017-10-06 14:48:25 -0700664TEST_F(OmahaResponseHandlerActionTest, TestDeferredByPolicy) {
665 OmahaResponse in;
666 in.update_exists = true;
667 in.version = "a.b.c.d";
668 in.packages.push_back({.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
669 .size = 12,
670 .hash = kPayloadHashHex});
671 // Setup the UpdateManager to disallow the update.
672 FakeClock fake_clock;
673 MockPolicy* mock_policy = new MockPolicy(&fake_clock);
674 FakeUpdateManager* fake_update_manager =
675 fake_system_state_.fake_update_manager();
676 fake_update_manager->set_policy(mock_policy);
677 EXPECT_CALL(*mock_policy, UpdateCanBeApplied(_, _, _, _, _))
678 .WillOnce(
679 DoAll(SetArgPointee<3>(ErrorCode::kOmahaUpdateDeferredPerPolicy),
680 Return(EvalStatus::kSucceeded)));
681 // Perform the Action. It should "fail" with kOmahaUpdateDeferredPerPolicy.
682 InstallPlan install_plan;
683 EXPECT_FALSE(DoTest(in, "", &install_plan));
684 EXPECT_EQ(ErrorCode::kOmahaUpdateDeferredPerPolicy, action_result_code_);
685 // Verify that DoTest() didn't set the output install plan.
686 EXPECT_EQ("", install_plan.version);
Aaron Wood23bd3392017-10-06 14:48:25 -0700687 // Now verify the InstallPlan that was generated.
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700688 install_plan = *delegate_.response_handler_action_install_plan_;
Aaron Wood23bd3392017-10-06 14:48:25 -0700689 EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
690 EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
691 EXPECT_EQ(1U, install_plan.target_slot);
692 EXPECT_EQ(in.version, install_plan.version);
693}
694
adlr@google.com3defe6a2009-12-04 20:57:17 +0000695} // namespace chromeos_update_engine