blob: 5c40fb3f14a8c19a4b9672a4ceaa4cd5dccd2128 [file] [log] [blame]
Mike Frysinger8155d082012-04-06 15:23:18 -04001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
adlr@google.com3defe6a2009-12-04 20:57:17 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Deymoaab50e32014-11-10 19:55:35 -08005#include "update_engine/filesystem_copier_action.h"
6
Darin Petkov698d0412010-10-13 10:59:44 -07007#include <fcntl.h>
8
adlr@google.com3defe6a2009-12-04 20:57:17 +00009#include <set>
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080010#include <string>
adlr@google.com3defe6a2009-12-04 20:57:17 +000011#include <vector>
Darin Petkov698d0412010-10-13 10:59:44 -070012
Chris Sosafc661a12013-02-26 14:43:21 -080013#include <base/posix/eintr_wrapper.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070014#include <base/strings/string_util.h>
15#include <base/strings/stringprintf.h>
Darin Petkov698d0412010-10-13 10:59:44 -070016#include <glib.h>
Don Garrett83692e42013-11-08 10:11:30 -080017#include <gmock/gmock.h>
adlr@google.com3defe6a2009-12-04 20:57:17 +000018#include <gtest/gtest.h>
Darin Petkov698d0412010-10-13 10:59:44 -070019
Gilad Arnold5bb4c902014-04-10 12:32:13 -070020#include "update_engine/fake_system_state.h"
Don Garrett6646b442013-11-13 15:29:11 -080021#include "update_engine/mock_hardware.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000022#include "update_engine/omaha_hash_calculator.h"
23#include "update_engine/test_utils.h"
24#include "update_engine/utils.h"
25
26using std::set;
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080027using std::string;
adlr@google.com3defe6a2009-12-04 20:57:17 +000028using std::vector;
29
30namespace chromeos_update_engine {
31
32class FilesystemCopierActionTest : public ::testing::Test {
33 protected:
Darin Petkov3aefa862010-12-07 14:45:00 -080034 // |verify_hash|: 0 - no hash verification, 1 -- successful hash verification,
35 // 2 -- hash verification failure.
Gilad Arnoldae236702012-05-17 09:33:20 -070036 // Returns true iff test has completed successfully.
Gilad Arnoldae236702012-05-17 09:33:20 -070037 bool DoTest(bool run_out_of_space,
Andrew de los Reyesf9185172010-05-03 11:07:05 -070038 bool terminate_early,
Darin Petkov3aefa862010-12-07 14:45:00 -080039 bool use_kernel_partition,
Gilad Arnold6dbbd392012-07-10 16:19:11 -070040 int verify_hash);
adlr@google.com3defe6a2009-12-04 20:57:17 +000041 void SetUp() {
adlr@google.com3defe6a2009-12-04 20:57:17 +000042 }
43 void TearDown() {
adlr@google.com3defe6a2009-12-04 20:57:17 +000044 }
Don Garrett6646b442013-11-13 15:29:11 -080045
Gilad Arnold5bb4c902014-04-10 12:32:13 -070046 FakeSystemState fake_system_state_;
adlr@google.com3defe6a2009-12-04 20:57:17 +000047};
48
49class FilesystemCopierActionTestDelegate : public ActionProcessorDelegate {
50 public:
Ben Chan2add7d72012-10-08 19:28:37 -070051 FilesystemCopierActionTestDelegate(GMainLoop* loop,
52 FilesystemCopierAction* action)
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -070053 : loop_(loop), action_(action), ran_(false), code_(ErrorCode::kError) {}
Andrew de los Reyesc7020782010-04-28 10:46:04 -070054 void ExitMainLoop() {
Ben Chan2add7d72012-10-08 19:28:37 -070055 GMainContext* context = g_main_loop_get_context(loop_);
56 // We cannot use g_main_context_pending() alone to determine if it is safe
Alex Vakulenko072359c2014-07-18 11:41:07 -070057 // to quit the main loop here because g_main_context_pending() may return
Ben Chan2add7d72012-10-08 19:28:37 -070058 // FALSE when g_input_stream_read_async() in FilesystemCopierAction has
59 // been cancelled but the callback has not yet been invoked.
60 while (g_main_context_pending(context) || action_->IsCleanupPending()) {
61 g_main_context_iteration(context, false);
62 g_usleep(100);
Andrew de los Reyesc7020782010-04-28 10:46:04 -070063 }
adlr@google.com3defe6a2009-12-04 20:57:17 +000064 g_main_loop_quit(loop_);
65 }
David Zeuthena99981f2013-04-29 13:42:47 -070066 void ProcessingDone(const ActionProcessor* processor, ErrorCode code) {
Andrew de los Reyesc7020782010-04-28 10:46:04 -070067 ExitMainLoop();
68 }
69 void ProcessingStopped(const ActionProcessor* processor) {
70 ExitMainLoop();
71 }
adlr@google.com3defe6a2009-12-04 20:57:17 +000072 void ActionCompleted(ActionProcessor* processor,
73 AbstractAction* action,
David Zeuthena99981f2013-04-29 13:42:47 -070074 ErrorCode code) {
adlr@google.com3defe6a2009-12-04 20:57:17 +000075 if (action->Type() == FilesystemCopierAction::StaticType()) {
76 ran_ = true;
Darin Petkovc1a8b422010-07-19 11:34:49 -070077 code_ = code;
adlr@google.com3defe6a2009-12-04 20:57:17 +000078 }
79 }
Ben Chan2add7d72012-10-08 19:28:37 -070080 bool ran() const { return ran_; }
David Zeuthena99981f2013-04-29 13:42:47 -070081 ErrorCode code() const { return code_; }
Alex Vakulenkod2779df2014-06-16 13:19:00 -070082
adlr@google.com3defe6a2009-12-04 20:57:17 +000083 private:
84 GMainLoop* loop_;
Ben Chan2add7d72012-10-08 19:28:37 -070085 FilesystemCopierAction* action_;
adlr@google.com3defe6a2009-12-04 20:57:17 +000086 bool ran_;
David Zeuthena99981f2013-04-29 13:42:47 -070087 ErrorCode code_;
adlr@google.com3defe6a2009-12-04 20:57:17 +000088};
89
Andrew de los Reyesc7020782010-04-28 10:46:04 -070090struct StartProcessorCallbackArgs {
91 ActionProcessor* processor;
92 FilesystemCopierAction* filesystem_copier_action;
93 bool terminate_early;
94};
95
adlr@google.com3defe6a2009-12-04 20:57:17 +000096gboolean StartProcessorInRunLoop(gpointer data) {
Andrew de los Reyesc7020782010-04-28 10:46:04 -070097 StartProcessorCallbackArgs* args =
98 reinterpret_cast<StartProcessorCallbackArgs*>(data);
99 ActionProcessor* processor = args->processor;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000100 processor->StartProcessing();
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700101 if (args->terminate_early) {
102 EXPECT_TRUE(args->filesystem_copier_action);
103 args->processor->StopProcessing();
104 }
adlr@google.com3defe6a2009-12-04 20:57:17 +0000105 return FALSE;
106}
107
Gilad Arnold581c2ea2012-07-19 12:33:49 -0700108// TODO(garnold) Temporarily disabling this test, see chromium-os:31082 for
109// details; still trying to track down the root cause for these rare write
110// failures and whether or not they are due to the test setup or an inherent
Alex Vakulenko072359c2014-07-18 11:41:07 -0700111// issue with the chroot environment, library versions we use, etc.
Gilad Arnold581c2ea2012-07-19 12:33:49 -0700112TEST_F(FilesystemCopierActionTest, DISABLED_RunAsRootSimpleTest) {
adlr@google.com3defe6a2009-12-04 20:57:17 +0000113 ASSERT_EQ(0, getuid());
Don Garrett83692e42013-11-08 10:11:30 -0800114 bool test = DoTest(false, false, true, 0);
Gilad Arnold581c2ea2012-07-19 12:33:49 -0700115 EXPECT_TRUE(test);
116 if (!test)
117 return;
Don Garrett83692e42013-11-08 10:11:30 -0800118 test = DoTest(false, false, false, 0);
Gilad Arnold581c2ea2012-07-19 12:33:49 -0700119 EXPECT_TRUE(test);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000120}
Darin Petkov3aefa862010-12-07 14:45:00 -0800121
Gilad Arnoldae236702012-05-17 09:33:20 -0700122bool FilesystemCopierActionTest::DoTest(bool run_out_of_space,
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700123 bool terminate_early,
Darin Petkov3aefa862010-12-07 14:45:00 -0800124 bool use_kernel_partition,
Gilad Arnold6dbbd392012-07-10 16:19:11 -0700125 int verify_hash) {
Don Garrett6646b442013-11-13 15:29:11 -0800126 // We need MockHardware to verify MarkUnbootable calls, but don't want
127 // warnings about other usages.
128 testing::NiceMock<MockHardware> mock_hardware;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700129 fake_system_state_.set_hardware(&mock_hardware);
Don Garrett83692e42013-11-08 10:11:30 -0800130
adlr@google.com3defe6a2009-12-04 20:57:17 +0000131 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
132
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700133 string a_loop_file;
134 string b_loop_file;
Darin Petkovc1a8b422010-07-19 11:34:49 -0700135
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700136 if (!(utils::MakeTempFile("a_loop_file.XXXXXX", &a_loop_file, nullptr) &&
137 utils::MakeTempFile("b_loop_file.XXXXXX", &b_loop_file, nullptr))) {
Gilad Arnoldae236702012-05-17 09:33:20 -0700138 ADD_FAILURE();
139 return false;
140 }
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700141 ScopedPathUnlinker a_loop_file_unlinker(a_loop_file);
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700142 ScopedPathUnlinker b_loop_file_unlinker(b_loop_file);
Darin Petkovc1a8b422010-07-19 11:34:49 -0700143
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700144 // Make random data for a, zero filled data for b.
Gilad Arnold6dbbd392012-07-10 16:19:11 -0700145 const size_t kLoopFileSize = 10 * 1024 * 1024 + 512;
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700146 vector<char> a_loop_data(kLoopFileSize);
Alex Deymo10875d92014-11-10 21:52:57 -0800147 test_utils::FillWithData(&a_loop_data);
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700148 vector<char> b_loop_data(run_out_of_space ?
149 (kLoopFileSize - 1) :
150 kLoopFileSize,
151 '\0'); // Fill with 0s
adlr@google.com3defe6a2009-12-04 20:57:17 +0000152
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700153 // Write data to disk
Alex Deymo10875d92014-11-10 21:52:57 -0800154 if (!(test_utils::WriteFileVector(a_loop_file, a_loop_data) &&
155 test_utils::WriteFileVector(b_loop_file, b_loop_data))) {
Gilad Arnoldae236702012-05-17 09:33:20 -0700156 ADD_FAILURE();
157 return false;
158 }
adlr@google.com3defe6a2009-12-04 20:57:17 +0000159
Don Garrett58e8b1f2012-01-31 16:38:16 -0800160 // Attach loop devices to the files
161 string a_dev;
162 string b_dev;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000163
Alex Deymo10875d92014-11-10 21:52:57 -0800164 test_utils::ScopedLoopbackDeviceBinder a_dev_releaser(a_loop_file, &a_dev);
165 test_utils::ScopedLoopbackDeviceBinder b_dev_releaser(b_loop_file, &b_dev);
Gilad Arnoldc33faeb2012-07-24 15:11:11 -0700166 if (!(a_dev_releaser.is_bound() && b_dev_releaser.is_bound())) {
167 ADD_FAILURE();
168 return false;
169 }
adlr@google.com3defe6a2009-12-04 20:57:17 +0000170
Gilad Arnoldc33faeb2012-07-24 15:11:11 -0700171 LOG(INFO) << "copying: "
172 << a_loop_file << " (" << a_dev << ") -> "
173 << b_loop_file << " (" << b_dev << ", "
174 << kLoopFileSize << " bytes";
Gilad Arnoldae236702012-05-17 09:33:20 -0700175 bool success = true;
176
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700177 // Set up the action objects
adlr@google.com3defe6a2009-12-04 20:57:17 +0000178 InstallPlan install_plan;
Darin Petkov3aefa862010-12-07 14:45:00 -0800179 if (verify_hash) {
180 if (use_kernel_partition) {
181 install_plan.kernel_install_path = a_dev;
182 install_plan.kernel_size =
183 kLoopFileSize - ((verify_hash == 2) ? 1 : 0);
Gilad Arnoldae236702012-05-17 09:33:20 -0700184 if (!OmahaHashCalculator::RawHashOfData(a_loop_data,
185 &install_plan.kernel_hash)) {
186 ADD_FAILURE();
187 success = false;
188 }
Darin Petkov3aefa862010-12-07 14:45:00 -0800189 } else {
190 install_plan.install_path = a_dev;
191 install_plan.rootfs_size =
192 kLoopFileSize - ((verify_hash == 2) ? 1 : 0);
Gilad Arnoldae236702012-05-17 09:33:20 -0700193 if (!OmahaHashCalculator::RawHashOfData(a_loop_data,
194 &install_plan.rootfs_hash)) {
195 ADD_FAILURE();
196 success = false;
197 }
Darin Petkov3aefa862010-12-07 14:45:00 -0800198 }
199 } else {
200 if (use_kernel_partition) {
201 install_plan.kernel_install_path = b_dev;
202 } else {
203 install_plan.install_path = b_dev;
204 }
205 }
adlr@google.com3defe6a2009-12-04 20:57:17 +0000206
Don Garrett6646b442013-11-13 15:29:11 -0800207 EXPECT_CALL(mock_hardware,
Don Garrett83692e42013-11-08 10:11:30 -0800208 MarkKernelUnbootable(a_dev)).Times(use_kernel_partition ? 1 : 0);
209
adlr@google.com3defe6a2009-12-04 20:57:17 +0000210 ActionProcessor processor;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000211
212 ObjectFeederAction<InstallPlan> feeder_action;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700213 FilesystemCopierAction copier_action(&fake_system_state_,
Alex Deymo42432912013-07-12 20:21:15 -0700214 use_kernel_partition,
Gilad Arnold581c2ea2012-07-19 12:33:49 -0700215 verify_hash != 0);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000216 ObjectCollectorAction<InstallPlan> collector_action;
217
218 BondActions(&feeder_action, &copier_action);
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700219 BondActions(&copier_action, &collector_action);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000220
Ben Chan2add7d72012-10-08 19:28:37 -0700221 FilesystemCopierActionTestDelegate delegate(loop, &copier_action);
222 processor.set_delegate(&delegate);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000223 processor.EnqueueAction(&feeder_action);
224 processor.EnqueueAction(&copier_action);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000225 processor.EnqueueAction(&collector_action);
226
Darin Petkov3aefa862010-12-07 14:45:00 -0800227 if (!verify_hash) {
228 copier_action.set_copy_source(a_dev);
229 }
adlr@google.com3defe6a2009-12-04 20:57:17 +0000230 feeder_action.set_obj(install_plan);
231
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700232 StartProcessorCallbackArgs start_callback_args;
233 start_callback_args.processor = &processor;
234 start_callback_args.filesystem_copier_action = &copier_action;
235 start_callback_args.terminate_early = terminate_early;
236
237 g_timeout_add(0, &StartProcessorInRunLoop, &start_callback_args);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000238 g_main_loop_run(loop);
239 g_main_loop_unref(loop);
240
Gilad Arnoldae236702012-05-17 09:33:20 -0700241 if (!terminate_early) {
242 bool is_delegate_ran = delegate.ran();
243 EXPECT_TRUE(is_delegate_ran);
244 success = success && is_delegate_ran;
245 }
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700246 if (run_out_of_space || terminate_early) {
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700247 EXPECT_EQ(ErrorCode::kError, delegate.code());
248 return (ErrorCode::kError == delegate.code());
adlr@google.com3defe6a2009-12-04 20:57:17 +0000249 }
Darin Petkov3aefa862010-12-07 14:45:00 -0800250 if (verify_hash == 2) {
David Zeuthena99981f2013-04-29 13:42:47 -0700251 ErrorCode expected_exit_code =
Gilad Arnoldae236702012-05-17 09:33:20 -0700252 (use_kernel_partition ?
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700253 ErrorCode::kNewKernelVerificationError :
254 ErrorCode::kNewRootfsVerificationError);
Gilad Arnoldae236702012-05-17 09:33:20 -0700255 EXPECT_EQ(expected_exit_code, delegate.code());
256 return (expected_exit_code == delegate.code());
Darin Petkov3aefa862010-12-07 14:45:00 -0800257 }
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700258 EXPECT_EQ(ErrorCode::kSuccess, delegate.code());
adlr@google.com3defe6a2009-12-04 20:57:17 +0000259
adlr@google.com3defe6a2009-12-04 20:57:17 +0000260 // Make sure everything in the out_image is there
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700261 vector<char> a_out;
Gilad Arnoldae236702012-05-17 09:33:20 -0700262 if (!utils::ReadFile(a_dev, &a_out)) {
263 ADD_FAILURE();
264 return false;
265 }
Alex Deymo10875d92014-11-10 21:52:57 -0800266 const bool is_a_file_reading_eq =
267 test_utils::ExpectVectorsEq(a_loop_data, a_out);
Gilad Arnold308b85e2012-06-07 15:50:16 -0700268 EXPECT_TRUE(is_a_file_reading_eq);
269 success = success && is_a_file_reading_eq;
Darin Petkov3aefa862010-12-07 14:45:00 -0800270 if (!verify_hash) {
271 vector<char> b_out;
Gilad Arnoldae236702012-05-17 09:33:20 -0700272 if (!utils::ReadFile(b_dev, &b_out)) {
273 ADD_FAILURE();
274 return false;
275 }
Alex Deymo10875d92014-11-10 21:52:57 -0800276 const bool is_b_file_reading_eq = test_utils::ExpectVectorsEq(a_out, b_out);
Gilad Arnold308b85e2012-06-07 15:50:16 -0700277 EXPECT_TRUE(is_b_file_reading_eq);
278 success = success && is_b_file_reading_eq;
Darin Petkov3aefa862010-12-07 14:45:00 -0800279 }
adlr@google.com3defe6a2009-12-04 20:57:17 +0000280
Gilad Arnoldae236702012-05-17 09:33:20 -0700281 bool is_install_plan_eq = (collector_action.object() == install_plan);
282 EXPECT_TRUE(is_install_plan_eq);
283 success = success && is_install_plan_eq;
284
Don Garrett83692e42013-11-08 10:11:30 -0800285 LOG(INFO) << "Verifying bootable flag on: " << a_dev;
286 bool bootable;
Don Garrett6646b442013-11-13 15:29:11 -0800287 EXPECT_TRUE(mock_hardware.fake().IsKernelBootable(a_dev, &bootable));
Don Garrett83692e42013-11-08 10:11:30 -0800288 // We should always mark a partition as unbootable if it's a kernel
289 // partition, but never if it's anything else.
290 EXPECT_EQ(bootable, !use_kernel_partition);
291
Gilad Arnoldae236702012-05-17 09:33:20 -0700292 return success;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000293}
294
295class FilesystemCopierActionTest2Delegate : public ActionProcessorDelegate {
296 public:
297 void ActionCompleted(ActionProcessor* processor,
298 AbstractAction* action,
David Zeuthena99981f2013-04-29 13:42:47 -0700299 ErrorCode code) {
adlr@google.com3defe6a2009-12-04 20:57:17 +0000300 if (action->Type() == FilesystemCopierAction::StaticType()) {
301 ran_ = true;
Darin Petkovc1a8b422010-07-19 11:34:49 -0700302 code_ = code;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000303 }
304 }
305 GMainLoop *loop_;
306 bool ran_;
David Zeuthena99981f2013-04-29 13:42:47 -0700307 ErrorCode code_;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000308};
309
310TEST_F(FilesystemCopierActionTest, MissingInputObjectTest) {
311 ActionProcessor processor;
312 FilesystemCopierActionTest2Delegate delegate;
313
314 processor.set_delegate(&delegate);
315
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700316 FilesystemCopierAction copier_action(&fake_system_state_, false, false);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000317 ObjectCollectorAction<InstallPlan> collector_action;
318
319 BondActions(&copier_action, &collector_action);
320
321 processor.EnqueueAction(&copier_action);
322 processor.EnqueueAction(&collector_action);
323 processor.StartProcessing();
324 EXPECT_FALSE(processor.IsRunning());
325 EXPECT_TRUE(delegate.ran_);
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700326 EXPECT_EQ(ErrorCode::kError, delegate.code_);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000327}
328
Darin Petkov9b230572010-10-08 10:20:09 -0700329TEST_F(FilesystemCopierActionTest, ResumeTest) {
330 ActionProcessor processor;
331 FilesystemCopierActionTest2Delegate delegate;
332
333 processor.set_delegate(&delegate);
334
335 ObjectFeederAction<InstallPlan> feeder_action;
336 const char* kUrl = "http://some/url";
David Zeuthene7f89172013-10-31 10:21:04 -0700337 InstallPlan install_plan(false, true, kUrl, 0, "", 0, "", "", "", "");
Darin Petkov9b230572010-10-08 10:20:09 -0700338 feeder_action.set_obj(install_plan);
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700339 FilesystemCopierAction copier_action(&fake_system_state_, false, false);
Darin Petkov9b230572010-10-08 10:20:09 -0700340 ObjectCollectorAction<InstallPlan> collector_action;
341
342 BondActions(&feeder_action, &copier_action);
343 BondActions(&copier_action, &collector_action);
344
345 processor.EnqueueAction(&feeder_action);
346 processor.EnqueueAction(&copier_action);
347 processor.EnqueueAction(&collector_action);
348 processor.StartProcessing();
349 EXPECT_FALSE(processor.IsRunning());
350 EXPECT_TRUE(delegate.ran_);
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700351 EXPECT_EQ(ErrorCode::kSuccess, delegate.code_);
Darin Petkov9b230572010-10-08 10:20:09 -0700352 EXPECT_EQ(kUrl, collector_action.object().download_url);
353}
354
adlr@google.com3defe6a2009-12-04 20:57:17 +0000355TEST_F(FilesystemCopierActionTest, NonExistentDriveTest) {
356 ActionProcessor processor;
357 FilesystemCopierActionTest2Delegate delegate;
358
359 processor.set_delegate(&delegate);
360
361 ObjectFeederAction<InstallPlan> feeder_action;
Darin Petkov0406e402010-10-06 21:33:11 -0700362 InstallPlan install_plan(false,
Gilad Arnold21504f02013-05-24 08:51:22 -0700363 false,
Darin Petkov0406e402010-10-06 21:33:11 -0700364 "",
365 0,
366 "",
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700367 0,
368 "",
Darin Petkov0406e402010-10-06 21:33:11 -0700369 "/no/such/file",
David Zeuthene7f89172013-10-31 10:21:04 -0700370 "/no/such/file",
371 "");
adlr@google.com3defe6a2009-12-04 20:57:17 +0000372 feeder_action.set_obj(install_plan);
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700373 FilesystemCopierAction copier_action(&fake_system_state_, false, false);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000374 ObjectCollectorAction<InstallPlan> collector_action;
375
376 BondActions(&copier_action, &collector_action);
377
378 processor.EnqueueAction(&feeder_action);
379 processor.EnqueueAction(&copier_action);
380 processor.EnqueueAction(&collector_action);
381 processor.StartProcessing();
382 EXPECT_FALSE(processor.IsRunning());
383 EXPECT_TRUE(delegate.ran_);
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700384 EXPECT_EQ(ErrorCode::kError, delegate.code_);
adlr@google.com3defe6a2009-12-04 20:57:17 +0000385}
386
Darin Petkov3aefa862010-12-07 14:45:00 -0800387TEST_F(FilesystemCopierActionTest, RunAsRootVerifyHashTest) {
388 ASSERT_EQ(0, getuid());
Gilad Arnoldae236702012-05-17 09:33:20 -0700389 EXPECT_TRUE(DoTest(false, false, false, 1));
390 EXPECT_TRUE(DoTest(false, false, true, 1));
Darin Petkov3aefa862010-12-07 14:45:00 -0800391}
392
393TEST_F(FilesystemCopierActionTest, RunAsRootVerifyHashFailTest) {
394 ASSERT_EQ(0, getuid());
Gilad Arnoldae236702012-05-17 09:33:20 -0700395 EXPECT_TRUE(DoTest(false, false, false, 2));
396 EXPECT_TRUE(DoTest(false, false, true, 2));
Darin Petkov3aefa862010-12-07 14:45:00 -0800397}
398
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700399TEST_F(FilesystemCopierActionTest, RunAsRootNoSpaceTest) {
adlr@google.com3defe6a2009-12-04 20:57:17 +0000400 ASSERT_EQ(0, getuid());
Gilad Arnoldae236702012-05-17 09:33:20 -0700401 EXPECT_TRUE(DoTest(true, false, false, 0));
adlr@google.com3defe6a2009-12-04 20:57:17 +0000402}
403
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700404TEST_F(FilesystemCopierActionTest, RunAsRootTerminateEarlyTest) {
adlr@google.com3defe6a2009-12-04 20:57:17 +0000405 ASSERT_EQ(0, getuid());
Gilad Arnoldae236702012-05-17 09:33:20 -0700406 EXPECT_TRUE(DoTest(false, true, false, 0));
adlr@google.com3defe6a2009-12-04 20:57:17 +0000407}
408
Darin Petkov698d0412010-10-13 10:59:44 -0700409TEST_F(FilesystemCopierActionTest, RunAsRootDetermineFilesystemSizeTest) {
410 string img;
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700411 EXPECT_TRUE(utils::MakeTempFile("img.XXXXXX", &img, nullptr));
Darin Petkov698d0412010-10-13 10:59:44 -0700412 ScopedPathUnlinker img_unlinker(img);
Alex Deymo10875d92014-11-10 21:52:57 -0800413 test_utils::CreateExtImageAtPath(img, nullptr);
Darin Petkov698d0412010-10-13 10:59:44 -0700414 // Extend the "partition" holding the file system from 10MiB to 20MiB.
Alex Deymo10875d92014-11-10 21:52:57 -0800415 EXPECT_EQ(0, test_utils::System(base::StringPrintf(
Darin Petkov698d0412010-10-13 10:59:44 -0700416 "dd if=/dev/zero of=%s seek=20971519 bs=1 count=1",
417 img.c_str())));
418 EXPECT_EQ(20 * 1024 * 1024, utils::FileSize(img));
419
420 for (int i = 0; i < 2; ++i) {
421 bool is_kernel = i == 1;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700422 FilesystemCopierAction action(&fake_system_state_, is_kernel, false);
Darin Petkov698d0412010-10-13 10:59:44 -0700423 EXPECT_EQ(kint64max, action.filesystem_size_);
424 {
425 int fd = HANDLE_EINTR(open(img.c_str(), O_RDONLY));
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700426 EXPECT_GT(fd, 0);
Darin Petkov698d0412010-10-13 10:59:44 -0700427 ScopedFdCloser fd_closer(&fd);
428 action.DetermineFilesystemSize(fd);
429 }
430 EXPECT_EQ(is_kernel ? kint64max : 10 * 1024 * 1024,
431 action.filesystem_size_);
432 }
433}
434
435
adlr@google.com3defe6a2009-12-04 20:57:17 +0000436} // namespace chromeos_update_engine