blob: 85f78f90703e827083e39cc5f35f3fdd68fe6bb1 [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>
Alex Deymo6f20dd42015-08-18 16:42:46 -070031#include <sys/xattr.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +000032#include <unistd.h>
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070033
adlr@google.comc98a7ed2009-12-04 18:54:03 +000034#include <set>
rspangler@google.com49fdf182009-10-10 00:57:34 +000035#include <string>
36#include <vector>
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070037
Alex Deymo2b19cfb2015-03-26 00:35:07 -070038#include <base/files/file_util.h>
Alex Deymoc00c98a2015-03-17 17:38:00 -070039#include <base/format_macros.h>
Alex Deymo161c4a12014-05-16 15:56:21 -070040#include <base/logging.h>
Alex Deymo2b19cfb2015-03-26 00:35:07 -070041#include <base/strings/string_util.h>
Alex Deymo30534502015-07-20 15:06:33 -070042#include <base/strings/stringprintf.h>
Alex Deymo161c4a12014-05-16 15:56:21 -070043
Alex Deymo64d98782016-02-05 18:03:48 -080044#include "update_engine/common/error_code_utils.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080045#include "update_engine/common/utils.h"
46#include "update_engine/payload_consumer/file_writer.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000047
Alex Deymo161c4a12014-05-16 15:56:21 -070048using base::StringPrintf;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000049using std::set;
rspangler@google.com49fdf182009-10-10 00:57:34 +000050using std::string;
51using std::vector;
52
53namespace chromeos_update_engine {
54
Alex Deymo52490e72015-06-04 14:53:44 +020055void PrintTo(const Extent& extent, ::std::ostream* os) {
56 *os << "(" << extent.start_block() << ", " << extent.num_blocks() << ")";
57}
58
Alex Deymo64d98782016-02-05 18:03:48 -080059void PrintTo(const ErrorCode& error_code, ::std::ostream* os) {
60 *os << utils::ErrorCodeToString(error_code);
61}
62
Alex Deymo10875d92014-11-10 21:52:57 -080063namespace test_utils {
64
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080065const uint8_t kRandomString[] = {
Alex Deymo10875d92014-11-10 21:52:57 -080066 0xf2, 0xb7, 0x55, 0x92, 0xea, 0xa6, 0xc9, 0x57,
67 0xe0, 0xf8, 0xeb, 0x34, 0x93, 0xd9, 0xc4, 0x8f,
68 0xcb, 0x20, 0xfa, 0x37, 0x4b, 0x40, 0xcf, 0xdc,
69 0xa5, 0x08, 0x70, 0x89, 0x79, 0x35, 0xe2, 0x3d,
70 0x56, 0xa4, 0x75, 0x73, 0xa3, 0x6d, 0xd1, 0xd5,
71 0x26, 0xbb, 0x9c, 0x60, 0xbd, 0x2f, 0x5a, 0xfa,
72 0xb7, 0xd4, 0x3a, 0x50, 0xa7, 0x6b, 0x3e, 0xfd,
73 0x61, 0x2b, 0x3a, 0x31, 0x30, 0x13, 0x33, 0x53,
74 0xdb, 0xd0, 0x32, 0x71, 0x5c, 0x39, 0xed, 0xda,
75 0xb4, 0x84, 0xca, 0xbc, 0xbd, 0x78, 0x1c, 0x0c,
76 0xd8, 0x0b, 0x41, 0xe8, 0xe1, 0xe0, 0x41, 0xad,
77 0x03, 0x12, 0xd3, 0x3d, 0xb8, 0x75, 0x9b, 0xe6,
78 0xd9, 0x01, 0xd0, 0x87, 0xf4, 0x36, 0xfa, 0xa7,
79 0x0a, 0xfa, 0xc5, 0x87, 0x65, 0xab, 0x9a, 0x7b,
80 0xeb, 0x58, 0x23, 0xf0, 0xa8, 0x0a, 0xf2, 0x33,
81 0x3a, 0xe2, 0xe3, 0x35, 0x74, 0x95, 0xdd, 0x3c,
82 0x59, 0x5a, 0xd9, 0x52, 0x3a, 0x3c, 0xac, 0xe5,
83 0x15, 0x87, 0x6d, 0x82, 0xbc, 0xf8, 0x7d, 0xbe,
84 0xca, 0xd3, 0x2c, 0xd6, 0xec, 0x38, 0xeb, 0xe4,
85 0x53, 0xb0, 0x4c, 0x3f, 0x39, 0x29, 0xf7, 0xa4,
86 0x73, 0xa8, 0xcb, 0x32, 0x50, 0x05, 0x8c, 0x1c,
87 0x1c, 0xca, 0xc9, 0x76, 0x0b, 0x8f, 0x6b, 0x57,
88 0x1f, 0x24, 0x2b, 0xba, 0x82, 0xba, 0xed, 0x58,
89 0xd8, 0xbf, 0xec, 0x06, 0x64, 0x52, 0x6a, 0x3f,
90 0xe4, 0xad, 0xce, 0x84, 0xb4, 0x27, 0x55, 0x14,
91 0xe3, 0x75, 0x59, 0x73, 0x71, 0x51, 0xea, 0xe8,
92 0xcc, 0xda, 0x4f, 0x09, 0xaf, 0xa4, 0xbc, 0x0e,
93 0xa6, 0x1f, 0xe2, 0x3a, 0xf8, 0x96, 0x7d, 0x30,
94 0x23, 0xc5, 0x12, 0xb5, 0xd8, 0x73, 0x6b, 0x71,
95 0xab, 0xf1, 0xd7, 0x43, 0x58, 0xa7, 0xc9, 0xf0,
96 0xe4, 0x85, 0x1c, 0xd6, 0x92, 0x50, 0x2c, 0x98,
97 0x36, 0xfe, 0x87, 0xaf, 0x43, 0x8f, 0x8f, 0xf5,
98 0x88, 0x48, 0x18, 0x42, 0xcf, 0x42, 0xc1, 0xa8,
99 0xe8, 0x05, 0x08, 0xa1, 0x45, 0x70, 0x5b, 0x8c,
100 0x39, 0x28, 0xab, 0xe9, 0x6b, 0x51, 0xd2, 0xcb,
101 0x30, 0x04, 0xea, 0x7d, 0x2f, 0x6e, 0x6c, 0x3b,
102 0x5f, 0x82, 0xd9, 0x5b, 0x89, 0x37, 0x65, 0x65,
103 0xbe, 0x9f, 0xa3, 0x5d,
104};
105
Alex Deymod15c5462016-03-09 18:11:12 -0800106string Readlink(const string& path) {
107 vector<char> buf(PATH_MAX + 1);
108 ssize_t r = readlink(path.c_str(), buf.data(), buf.size());
109 if (r < 0)
110 return "";
111 CHECK_LT(r, static_cast<ssize_t>(buf.size()));
112 return string(buf.begin(), buf.begin() + r);
113}
114
Alex Deymo10875d92014-11-10 21:52:57 -0800115bool IsXAttrSupported(const base::FilePath& dir_path) {
116 char *path = strdup(dir_path.Append("xattr_test_XXXXXX").value().c_str());
117
118 int fd = mkstemp(path);
119 if (fd == -1) {
120 PLOG(ERROR) << "Error creating temporary file in " << dir_path.value();
121 free(path);
122 return false;
123 }
124
125 if (unlink(path) != 0) {
126 PLOG(ERROR) << "Error unlinking temporary file " << path;
127 close(fd);
128 free(path);
129 return false;
130 }
131
132 int xattr_res = fsetxattr(fd, "user.xattr-test", "value", strlen("value"), 0);
133 if (xattr_res != 0) {
134 if (errno == ENOTSUP) {
135 // Leave it to call-sites to warn about non-support.
136 } else {
137 PLOG(ERROR) << "Error setting xattr on " << path;
138 }
139 }
140 close(fd);
141 free(path);
142 return xattr_res == 0;
143}
144
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700145bool WriteFileVector(const string& path, const brillo::Blob& data) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800146 return utils::WriteFile(path.c_str(), data.data(), data.size());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000147}
148
Alex Deymof329b932014-10-30 01:37:48 -0700149bool WriteFileString(const string& path, const string& data) {
Andrew de los Reyes970bb282009-12-09 16:34:04 -0800150 return utils::WriteFile(path.c_str(), data.data(), data.size());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000151}
152
Alex Deymocbc22742016-03-04 17:53:02 -0800153bool BindToUnusedLoopDevice(const string& filename,
154 bool writable,
155 string* out_lo_dev_name) {
156 CHECK(out_lo_dev_name);
157 // Get the next available loop-device.
158 int control_fd =
159 HANDLE_EINTR(open("/dev/loop-control", O_RDWR | O_LARGEFILE));
160 TEST_AND_RETURN_FALSE_ERRNO(control_fd >= 0);
161 int loop_number = ioctl(control_fd, LOOP_CTL_GET_FREE);
162 IGNORE_EINTR(close(control_fd));
163 *out_lo_dev_name = StringPrintf("/dev/loop%d", loop_number);
Don Garrett58e8b1f2012-01-31 16:38:16 -0800164
Alex Deymocbc22742016-03-04 17:53:02 -0800165 // Double check that the loop exists and is free.
166 int loop_device_fd =
167 HANDLE_EINTR(open(out_lo_dev_name->c_str(), O_RDWR | O_LARGEFILE));
168 if (loop_device_fd == -1 && errno == ENOENT) {
169 // Workaround the case when the loop device doesn't exist.
170 TEST_AND_RETURN_FALSE_ERRNO(mknod(out_lo_dev_name->c_str(),
171 S_IFBLK | 0660,
172 makedev(LOOP_MAJOR, loop_number)) == 0);
173 loop_device_fd =
174 HANDLE_EINTR(open(out_lo_dev_name->c_str(), O_RDWR | O_LARGEFILE));
175 }
176 TEST_AND_RETURN_FALSE_ERRNO(loop_device_fd != -1);
177 ScopedFdCloser loop_device_fd_closer(&loop_device_fd);
178
179 struct loop_info64 device_info;
180 if (ioctl(loop_device_fd, LOOP_GET_STATUS64, &device_info) != -1 ||
181 errno != ENXIO) {
182 PLOG(ERROR) << "Loop device " << out_lo_dev_name->c_str()
183 << " already in use";
Gilad Arnold19a45f02012-07-19 12:36:10 -0700184 return false;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000185 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000186
Alex Deymocbc22742016-03-04 17:53:02 -0800187 // Open our data file and assign it to the loop device.
188 int data_fd = open(filename.c_str(),
189 (writable ? O_RDWR : O_RDONLY) | O_LARGEFILE | O_CLOEXEC);
190 TEST_AND_RETURN_FALSE_ERRNO(data_fd >= 0);
191 ScopedFdCloser data_fd_closer(&data_fd);
192 TEST_AND_RETURN_FALSE_ERRNO(ioctl(loop_device_fd, LOOP_SET_FD, data_fd) == 0);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000193
Alex Deymocbc22742016-03-04 17:53:02 -0800194 memset(&device_info, 0, sizeof(device_info));
195 device_info.lo_offset = 0;
196 device_info.lo_sizelimit = 0; // 0 means whole file.
197 device_info.lo_flags = (writable ? 0 : LO_FLAGS_READ_ONLY);
198 device_info.lo_number = loop_number;
199 strncpy(reinterpret_cast<char*>(device_info.lo_file_name),
200 base::FilePath(filename).BaseName().value().c_str(),
201 LO_NAME_SIZE - 1);
202 device_info.lo_file_name[LO_NAME_SIZE - 1] = '\0';
203 TEST_AND_RETURN_FALSE_ERRNO(
204 ioctl(loop_device_fd, LOOP_SET_STATUS64, &device_info) == 0);
Sen Jiangd37c81f2017-11-02 18:35:56 -0700205 if (writable) {
206 // Make sure loop device isn't read only.
207 int ro = 0;
208 if (ioctl(loop_device_fd, BLKROSET, &ro) != 0) {
209 PLOG(WARNING) << "Failed to mark loop device writable.";
210 }
211 }
Alex Deymocbc22742016-03-04 17:53:02 -0800212 return true;
213}
214
215bool UnbindLoopDevice(const string& lo_dev_name) {
216 int loop_device_fd =
217 HANDLE_EINTR(open(lo_dev_name.c_str(), O_RDWR | O_LARGEFILE));
218 if (loop_device_fd == -1 && errno == ENOENT)
219 return true;
220 TEST_AND_RETURN_FALSE_ERRNO(loop_device_fd != -1);
221 ScopedFdCloser loop_device_fd_closer(&loop_device_fd);
222
223 struct loop_info64 device_info;
224 // Check if the device is bound before trying to unbind it.
225 int get_stat_err = ioctl(loop_device_fd, LOOP_GET_STATUS64, &device_info);
226 if (get_stat_err == -1 && errno == ENXIO)
227 return true;
228
229 TEST_AND_RETURN_FALSE_ERRNO(ioctl(loop_device_fd, LOOP_CLR_FD) == 0);
Gilad Arnold19a45f02012-07-19 12:36:10 -0700230 return true;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000231}
232
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700233bool ExpectVectorsEq(const brillo::Blob& expected,
234 const brillo::Blob& actual) {
Andrew de los Reyes80061062010-02-04 14:25:00 -0800235 EXPECT_EQ(expected.size(), actual.size());
236 if (expected.size() != actual.size())
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000237 return false;
Gilad Arnold617bbc22012-05-15 08:48:13 -0700238 bool is_all_eq = true;
Andrew de los Reyes80061062010-02-04 14:25:00 -0800239 for (unsigned int i = 0; i < expected.size(); i++) {
240 EXPECT_EQ(expected[i], actual[i]) << "offset: " << i;
Gilad Arnold617bbc22012-05-15 08:48:13 -0700241 is_all_eq = is_all_eq && (expected[i] == actual[i]);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000242 }
Gilad Arnold617bbc22012-05-15 08:48:13 -0700243 return is_all_eq;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000244}
245
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700246void FillWithData(brillo::Blob* buffer) {
Andrew de los Reyes80061062010-02-04 14:25:00 -0800247 size_t input_counter = 0;
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800248 for (uint8_t& b : *buffer) {
249 b = kRandomString[input_counter];
Andrew de los Reyes80061062010-02-04 14:25:00 -0800250 input_counter++;
251 input_counter %= sizeof(kRandomString);
252 }
253}
254
Don Garrett58e8b1f2012-01-31 16:38:16 -0800255ScopedLoopMounter::ScopedLoopMounter(const string& file_path,
256 string* mnt_path,
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700257 unsigned long flags) { // NOLINT - long
Sen Jiang371615b2016-04-13 15:54:29 -0700258 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
Hidehiko Abe2b9d2412017-12-13 18:56:18 +0900259 *mnt_path = temp_dir_.GetPath().value();
Thieu Le5c7d9752010-12-15 16:09:28 -0800260
Don Garrett58e8b1f2012-01-31 16:38:16 -0800261 string loop_dev;
Alex Deymocbc22742016-03-04 17:53:02 -0800262 loop_binder_.reset(
263 new ScopedLoopbackDeviceBinder(file_path, true, &loop_dev));
Thieu Le5c7d9752010-12-15 16:09:28 -0800264
Sen Jiang2c413572016-03-07 12:55:09 -0800265 EXPECT_TRUE(utils::MountFilesystem(loop_dev, *mnt_path, flags, "", ""));
Thieu Le5c7d9752010-12-15 16:09:28 -0800266 unmounter_.reset(new ScopedFilesystemUnmounter(*mnt_path));
267}
268
Alex Deymo2b19cfb2015-03-26 00:35:07 -0700269base::FilePath GetBuildArtifactsPath() {
270 base::FilePath exe_path;
271 base::ReadSymbolicLink(base::FilePath("/proc/self/exe"), &exe_path);
272 return exe_path.DirName();
273}
274
Sen Jiang260f03b2016-03-21 15:34:58 -0700275string GetBuildArtifactsPath(const string& relative_path) {
276 return GetBuildArtifactsPath().Append(relative_path).value();
277}
278
Alex Deymo10875d92014-11-10 21:52:57 -0800279} // namespace test_utils
rspangler@google.com49fdf182009-10-10 00:57:34 +0000280} // namespace chromeos_update_engine