blob: 50b096242aee777b24532abc2997f2b515dc3889 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2012 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//
rspangler@google.com49fdf182009-10-10 00:57:34 +000016
Alex Deymo39910dc2015-11-09 17:04:30 -080017#include "update_engine/common/test_utils.h"
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070018
Alex Deymo6b9e38e2015-06-05 00:26:37 +020019#include <dirent.h>
adlr@google.comc98a7ed2009-12-04 18:54:03 +000020#include <errno.h>
Alex Deymocbc22742016-03-04 17:53:02 -080021#include <fcntl.h>
22#include <linux/loop.h>
23#include <linux/major.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +000024#include <stdio.h>
25#include <stdlib.h>
Alex Deymocbc22742016-03-04 17:53:02 -080026#include <sys/ioctl.h>
Sen Jiangd37c81f2017-11-02 18:35:56 -070027#include <sys/mount.h>
Alex Deymo161c4a12014-05-16 15:56:21 -070028#include <sys/stat.h>
Elliott Hughesce7b5692017-05-18 16:44:49 -070029#include <sys/sysmacros.h>
Alex Deymo161c4a12014-05-16 15:56:21 -070030#include <sys/types.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +000031#include <unistd.h>
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070032
adlr@google.comc98a7ed2009-12-04 18:54:03 +000033#include <set>
rspangler@google.com49fdf182009-10-10 00:57:34 +000034#include <string>
35#include <vector>
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070036
Alex Deymo2b19cfb2015-03-26 00:35:07 -070037#include <base/files/file_util.h>
Alex Deymo161c4a12014-05-16 15:56:21 -070038#include <base/logging.h>
Alex Deymo161c4a12014-05-16 15:56:21 -070039
Alex Deymo64d98782016-02-05 18:03:48 -080040#include "update_engine/common/error_code_utils.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080041#include "update_engine/common/utils.h"
42#include "update_engine/payload_consumer/file_writer.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000043
adlr@google.comc98a7ed2009-12-04 18:54:03 +000044using std::set;
rspangler@google.com49fdf182009-10-10 00:57:34 +000045using std::string;
46using std::vector;
47
Sen Jiangc01f41a2018-11-16 17:19:40 -080048namespace {
49
50#ifdef __ANDROID__
51#define kLoopDevicePrefix "/dev/block/loop"
52#else
53#define kLoopDevicePrefix "/dev/loop"
54#endif // __ANDROID__
55
56} // namespace
57
rspangler@google.com49fdf182009-10-10 00:57:34 +000058namespace chromeos_update_engine {
59
Alex Deymo52490e72015-06-04 14:53:44 +020060void PrintTo(const Extent& extent, ::std::ostream* os) {
61 *os << "(" << extent.start_block() << ", " << extent.num_blocks() << ")";
62}
63
Alex Deymo64d98782016-02-05 18:03:48 -080064void PrintTo(const ErrorCode& error_code, ::std::ostream* os) {
65 *os << utils::ErrorCodeToString(error_code);
66}
67
Alex Deymo10875d92014-11-10 21:52:57 -080068namespace test_utils {
69
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080070const uint8_t kRandomString[] = {
Amin Hassanib2689592019-01-13 17:04:28 -080071 0xf2, 0xb7, 0x55, 0x92, 0xea, 0xa6, 0xc9, 0x57, 0xe0, 0xf8, 0xeb, 0x34,
72 0x93, 0xd9, 0xc4, 0x8f, 0xcb, 0x20, 0xfa, 0x37, 0x4b, 0x40, 0xcf, 0xdc,
73 0xa5, 0x08, 0x70, 0x89, 0x79, 0x35, 0xe2, 0x3d, 0x56, 0xa4, 0x75, 0x73,
74 0xa3, 0x6d, 0xd1, 0xd5, 0x26, 0xbb, 0x9c, 0x60, 0xbd, 0x2f, 0x5a, 0xfa,
75 0xb7, 0xd4, 0x3a, 0x50, 0xa7, 0x6b, 0x3e, 0xfd, 0x61, 0x2b, 0x3a, 0x31,
76 0x30, 0x13, 0x33, 0x53, 0xdb, 0xd0, 0x32, 0x71, 0x5c, 0x39, 0xed, 0xda,
77 0xb4, 0x84, 0xca, 0xbc, 0xbd, 0x78, 0x1c, 0x0c, 0xd8, 0x0b, 0x41, 0xe8,
78 0xe1, 0xe0, 0x41, 0xad, 0x03, 0x12, 0xd3, 0x3d, 0xb8, 0x75, 0x9b, 0xe6,
79 0xd9, 0x01, 0xd0, 0x87, 0xf4, 0x36, 0xfa, 0xa7, 0x0a, 0xfa, 0xc5, 0x87,
80 0x65, 0xab, 0x9a, 0x7b, 0xeb, 0x58, 0x23, 0xf0, 0xa8, 0x0a, 0xf2, 0x33,
81 0x3a, 0xe2, 0xe3, 0x35, 0x74, 0x95, 0xdd, 0x3c, 0x59, 0x5a, 0xd9, 0x52,
82 0x3a, 0x3c, 0xac, 0xe5, 0x15, 0x87, 0x6d, 0x82, 0xbc, 0xf8, 0x7d, 0xbe,
83 0xca, 0xd3, 0x2c, 0xd6, 0xec, 0x38, 0xeb, 0xe4, 0x53, 0xb0, 0x4c, 0x3f,
84 0x39, 0x29, 0xf7, 0xa4, 0x73, 0xa8, 0xcb, 0x32, 0x50, 0x05, 0x8c, 0x1c,
85 0x1c, 0xca, 0xc9, 0x76, 0x0b, 0x8f, 0x6b, 0x57, 0x1f, 0x24, 0x2b, 0xba,
86 0x82, 0xba, 0xed, 0x58, 0xd8, 0xbf, 0xec, 0x06, 0x64, 0x52, 0x6a, 0x3f,
87 0xe4, 0xad, 0xce, 0x84, 0xb4, 0x27, 0x55, 0x14, 0xe3, 0x75, 0x59, 0x73,
88 0x71, 0x51, 0xea, 0xe8, 0xcc, 0xda, 0x4f, 0x09, 0xaf, 0xa4, 0xbc, 0x0e,
89 0xa6, 0x1f, 0xe2, 0x3a, 0xf8, 0x96, 0x7d, 0x30, 0x23, 0xc5, 0x12, 0xb5,
90 0xd8, 0x73, 0x6b, 0x71, 0xab, 0xf1, 0xd7, 0x43, 0x58, 0xa7, 0xc9, 0xf0,
91 0xe4, 0x85, 0x1c, 0xd6, 0x92, 0x50, 0x2c, 0x98, 0x36, 0xfe, 0x87, 0xaf,
92 0x43, 0x8f, 0x8f, 0xf5, 0x88, 0x48, 0x18, 0x42, 0xcf, 0x42, 0xc1, 0xa8,
93 0xe8, 0x05, 0x08, 0xa1, 0x45, 0x70, 0x5b, 0x8c, 0x39, 0x28, 0xab, 0xe9,
94 0x6b, 0x51, 0xd2, 0xcb, 0x30, 0x04, 0xea, 0x7d, 0x2f, 0x6e, 0x6c, 0x3b,
95 0x5f, 0x82, 0xd9, 0x5b, 0x89, 0x37, 0x65, 0x65, 0xbe, 0x9f, 0xa3, 0x5d,
Alex Deymo10875d92014-11-10 21:52:57 -080096};
97
Alex Deymod15c5462016-03-09 18:11:12 -080098string Readlink(const string& path) {
99 vector<char> buf(PATH_MAX + 1);
100 ssize_t r = readlink(path.c_str(), buf.data(), buf.size());
101 if (r < 0)
102 return "";
103 CHECK_LT(r, static_cast<ssize_t>(buf.size()));
104 return string(buf.begin(), buf.begin() + r);
105}
106
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700107bool WriteFileVector(const string& path, const brillo::Blob& data) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800108 return utils::WriteFile(path.c_str(), data.data(), data.size());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000109}
110
Alex Deymof329b932014-10-30 01:37:48 -0700111bool WriteFileString(const string& path, const string& data) {
Andrew de los Reyes970bb282009-12-09 16:34:04 -0800112 return utils::WriteFile(path.c_str(), data.data(), data.size());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000113}
114
Alex Deymocbc22742016-03-04 17:53:02 -0800115bool BindToUnusedLoopDevice(const string& filename,
116 bool writable,
117 string* out_lo_dev_name) {
118 CHECK(out_lo_dev_name);
119 // Get the next available loop-device.
120 int control_fd =
121 HANDLE_EINTR(open("/dev/loop-control", O_RDWR | O_LARGEFILE));
122 TEST_AND_RETURN_FALSE_ERRNO(control_fd >= 0);
123 int loop_number = ioctl(control_fd, LOOP_CTL_GET_FREE);
124 IGNORE_EINTR(close(control_fd));
Sen Jiangc01f41a2018-11-16 17:19:40 -0800125 *out_lo_dev_name = kLoopDevicePrefix + std::to_string(loop_number);
Don Garrett58e8b1f2012-01-31 16:38:16 -0800126
Alex Deymocbc22742016-03-04 17:53:02 -0800127 // Double check that the loop exists and is free.
128 int loop_device_fd =
129 HANDLE_EINTR(open(out_lo_dev_name->c_str(), O_RDWR | O_LARGEFILE));
130 if (loop_device_fd == -1 && errno == ENOENT) {
131 // Workaround the case when the loop device doesn't exist.
132 TEST_AND_RETURN_FALSE_ERRNO(mknod(out_lo_dev_name->c_str(),
133 S_IFBLK | 0660,
134 makedev(LOOP_MAJOR, loop_number)) == 0);
135 loop_device_fd =
136 HANDLE_EINTR(open(out_lo_dev_name->c_str(), O_RDWR | O_LARGEFILE));
137 }
138 TEST_AND_RETURN_FALSE_ERRNO(loop_device_fd != -1);
139 ScopedFdCloser loop_device_fd_closer(&loop_device_fd);
140
141 struct loop_info64 device_info;
142 if (ioctl(loop_device_fd, LOOP_GET_STATUS64, &device_info) != -1 ||
143 errno != ENXIO) {
144 PLOG(ERROR) << "Loop device " << out_lo_dev_name->c_str()
145 << " already in use";
Gilad Arnold19a45f02012-07-19 12:36:10 -0700146 return false;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000147 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000148
Alex Deymocbc22742016-03-04 17:53:02 -0800149 // Open our data file and assign it to the loop device.
150 int data_fd = open(filename.c_str(),
151 (writable ? O_RDWR : O_RDONLY) | O_LARGEFILE | O_CLOEXEC);
152 TEST_AND_RETURN_FALSE_ERRNO(data_fd >= 0);
153 ScopedFdCloser data_fd_closer(&data_fd);
154 TEST_AND_RETURN_FALSE_ERRNO(ioctl(loop_device_fd, LOOP_SET_FD, data_fd) == 0);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000155
Alex Deymocbc22742016-03-04 17:53:02 -0800156 memset(&device_info, 0, sizeof(device_info));
157 device_info.lo_offset = 0;
158 device_info.lo_sizelimit = 0; // 0 means whole file.
159 device_info.lo_flags = (writable ? 0 : LO_FLAGS_READ_ONLY);
160 device_info.lo_number = loop_number;
161 strncpy(reinterpret_cast<char*>(device_info.lo_file_name),
162 base::FilePath(filename).BaseName().value().c_str(),
163 LO_NAME_SIZE - 1);
164 device_info.lo_file_name[LO_NAME_SIZE - 1] = '\0';
165 TEST_AND_RETURN_FALSE_ERRNO(
166 ioctl(loop_device_fd, LOOP_SET_STATUS64, &device_info) == 0);
Sen Jiangd37c81f2017-11-02 18:35:56 -0700167 if (writable) {
168 // Make sure loop device isn't read only.
169 int ro = 0;
170 if (ioctl(loop_device_fd, BLKROSET, &ro) != 0) {
171 PLOG(WARNING) << "Failed to mark loop device writable.";
172 }
173 }
Alex Deymocbc22742016-03-04 17:53:02 -0800174 return true;
175}
176
177bool UnbindLoopDevice(const string& lo_dev_name) {
178 int loop_device_fd =
179 HANDLE_EINTR(open(lo_dev_name.c_str(), O_RDWR | O_LARGEFILE));
180 if (loop_device_fd == -1 && errno == ENOENT)
181 return true;
182 TEST_AND_RETURN_FALSE_ERRNO(loop_device_fd != -1);
183 ScopedFdCloser loop_device_fd_closer(&loop_device_fd);
184
185 struct loop_info64 device_info;
186 // Check if the device is bound before trying to unbind it.
187 int get_stat_err = ioctl(loop_device_fd, LOOP_GET_STATUS64, &device_info);
188 if (get_stat_err == -1 && errno == ENXIO)
189 return true;
190
191 TEST_AND_RETURN_FALSE_ERRNO(ioctl(loop_device_fd, LOOP_CLR_FD) == 0);
Gilad Arnold19a45f02012-07-19 12:36:10 -0700192 return true;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000193}
194
Amin Hassanib2689592019-01-13 17:04:28 -0800195bool ExpectVectorsEq(const brillo::Blob& expected, const brillo::Blob& actual) {
Andrew de los Reyes80061062010-02-04 14:25:00 -0800196 EXPECT_EQ(expected.size(), actual.size());
197 if (expected.size() != actual.size())
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000198 return false;
Gilad Arnold617bbc22012-05-15 08:48:13 -0700199 bool is_all_eq = true;
Andrew de los Reyes80061062010-02-04 14:25:00 -0800200 for (unsigned int i = 0; i < expected.size(); i++) {
201 EXPECT_EQ(expected[i], actual[i]) << "offset: " << i;
Gilad Arnold617bbc22012-05-15 08:48:13 -0700202 is_all_eq = is_all_eq && (expected[i] == actual[i]);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000203 }
Gilad Arnold617bbc22012-05-15 08:48:13 -0700204 return is_all_eq;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000205}
206
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700207void FillWithData(brillo::Blob* buffer) {
Andrew de los Reyes80061062010-02-04 14:25:00 -0800208 size_t input_counter = 0;
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800209 for (uint8_t& b : *buffer) {
210 b = kRandomString[input_counter];
Andrew de los Reyes80061062010-02-04 14:25:00 -0800211 input_counter++;
212 input_counter %= sizeof(kRandomString);
213 }
214}
215
Don Garrett58e8b1f2012-01-31 16:38:16 -0800216ScopedLoopMounter::ScopedLoopMounter(const string& file_path,
217 string* mnt_path,
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700218 unsigned long flags) { // NOLINT - long
Sen Jiang371615b2016-04-13 15:54:29 -0700219 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
Hidehiko Abe2b9d2412017-12-13 18:56:18 +0900220 *mnt_path = temp_dir_.GetPath().value();
Thieu Le5c7d9752010-12-15 16:09:28 -0800221
Don Garrett58e8b1f2012-01-31 16:38:16 -0800222 string loop_dev;
Alex Deymocbc22742016-03-04 17:53:02 -0800223 loop_binder_.reset(
224 new ScopedLoopbackDeviceBinder(file_path, true, &loop_dev));
Thieu Le5c7d9752010-12-15 16:09:28 -0800225
Sen Jiang2c413572016-03-07 12:55:09 -0800226 EXPECT_TRUE(utils::MountFilesystem(loop_dev, *mnt_path, flags, "", ""));
Thieu Le5c7d9752010-12-15 16:09:28 -0800227 unmounter_.reset(new ScopedFilesystemUnmounter(*mnt_path));
228}
229
Alex Deymo2b19cfb2015-03-26 00:35:07 -0700230base::FilePath GetBuildArtifactsPath() {
231 base::FilePath exe_path;
232 base::ReadSymbolicLink(base::FilePath("/proc/self/exe"), &exe_path);
233 return exe_path.DirName();
234}
235
Sen Jiang260f03b2016-03-21 15:34:58 -0700236string GetBuildArtifactsPath(const string& relative_path) {
237 return GetBuildArtifactsPath().Append(relative_path).value();
238}
239
Alex Deymo10875d92014-11-10 21:52:57 -0800240} // namespace test_utils
rspangler@google.com49fdf182009-10-10 00:57:34 +0000241} // namespace chromeos_update_engine