blob: fde89e82c0bcd47f3459a25d10366d98aeb15c71 [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//
adlr@google.com3defe6a2009-12-04 20:57:17 +000016
Alex Deymo39910dc2015-11-09 17:04:30 -080017#include "update_engine/common/utils.h"
Alex Deymo2c0db7b2014-11-04 12:23:39 -080018
Alex Vakulenko44cab302014-07-23 13:12:15 -070019#include <errno.h>
Ben Chan9abb7632014-08-07 00:10:53 -070020#include <stdint.h>
adlr@google.com3defe6a2009-12-04 20:57:17 +000021#include <sys/stat.h>
22#include <sys/types.h>
Darin Petkov5c0a8af2010-08-24 13:39:13 -070023
Andrew de los Reyescc92cd32010-10-05 16:56:14 -070024#include <map>
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080025#include <string>
adlr@google.com3defe6a2009-12-04 20:57:17 +000026#include <vector>
Darin Petkov5c0a8af2010-08-24 13:39:13 -070027
Alex Deymoc1711e22014-08-08 13:16:23 -070028#include <base/files/file_path.h>
Alex Deymo2c0db7b2014-11-04 12:23:39 -080029#include <base/files/file_util.h>
Allie Wood78750a42015-02-11 15:42:11 -080030#include <base/files/scoped_temp_dir.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070031#include <base/strings/string_util.h>
32#include <base/strings/stringprintf.h>
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070033#include <brillo/message_loops/fake_message_loop.h>
34#include <brillo/message_loops/message_loop_utils.h>
Darin Petkovd3f8c892010-10-12 21:38:45 -070035#include <gtest/gtest.h>
36
Alex Deymo39910dc2015-11-09 17:04:30 -080037#include "update_engine/common/test_utils.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000038
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070039using brillo::FakeMessageLoop;
Andrew de los Reyescc92cd32010-10-05 16:56:14 -070040using std::map;
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080041using std::string;
adlr@google.com3defe6a2009-12-04 20:57:17 +000042using std::vector;
43
44namespace chromeos_update_engine {
45
46class UtilsTest : public ::testing::Test { };
47
Chris Sosac1972482013-04-30 22:31:10 -070048TEST(UtilsTest, CanParseECVersion) {
Chris Sosac1972482013-04-30 22:31:10 -070049 // Should be able to parse and valid key value line.
J. Richard Barnette63137e52013-10-28 10:57:29 -070050 EXPECT_EQ("12345", utils::ParseECVersion("fw_version=12345"));
51 EXPECT_EQ("123456", utils::ParseECVersion(
52 "b=1231a fw_version=123456 a=fasd2"));
53 EXPECT_EQ("12345", utils::ParseECVersion("fw_version=12345"));
54 EXPECT_EQ("00VFA616", utils::ParseECVersion(
Chris Sosac1972482013-04-30 22:31:10 -070055 "vendor=\"sam\" fw_version=\"00VFA616\""));
56
57 // For invalid entries, should return the empty string.
J. Richard Barnette63137e52013-10-28 10:57:29 -070058 EXPECT_EQ("", utils::ParseECVersion("b=1231a fw_version a=fasd2"));
Chris Sosac1972482013-04-30 22:31:10 -070059}
60
adlr@google.com3defe6a2009-12-04 20:57:17 +000061TEST(UtilsTest, ReadFileFailure) {
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070062 brillo::Blob empty;
adlr@google.com3defe6a2009-12-04 20:57:17 +000063 EXPECT_FALSE(utils::ReadFile("/this/doesn't/exist", &empty));
64}
65
Darin Petkov8e447e02013-04-16 16:23:50 +020066TEST(UtilsTest, ReadFileChunk) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070067 base::FilePath file;
68 EXPECT_TRUE(base::CreateTemporaryFile(&file));
Darin Petkov8e447e02013-04-16 16:23:50 +020069 ScopedPathUnlinker unlinker(file.value());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070070 brillo::Blob data;
Darin Petkov8e447e02013-04-16 16:23:50 +020071 const size_t kSize = 1024 * 1024;
72 for (size_t i = 0; i < kSize; i++) {
73 data.push_back(i % 255);
74 }
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080075 EXPECT_TRUE(utils::WriteFile(file.value().c_str(), data.data(), data.size()));
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070076 brillo::Blob in_data;
Darin Petkov8e447e02013-04-16 16:23:50 +020077 EXPECT_TRUE(utils::ReadFileChunk(file.value().c_str(), kSize, 10, &in_data));
78 EXPECT_TRUE(in_data.empty());
79 EXPECT_TRUE(utils::ReadFileChunk(file.value().c_str(), 0, -1, &in_data));
80 EXPECT_TRUE(data == in_data);
81 in_data.clear();
82 EXPECT_TRUE(utils::ReadFileChunk(file.value().c_str(), 10, 20, &in_data));
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070083 EXPECT_TRUE(brillo::Blob(data.begin() + 10, data.begin() + 10 + 20) ==
Darin Petkov8e447e02013-04-16 16:23:50 +020084 in_data);
85}
86
adlr@google.com3defe6a2009-12-04 20:57:17 +000087TEST(UtilsTest, ErrnoNumberAsStringTest) {
88 EXPECT_EQ("No such file or directory", utils::ErrnoNumberAsString(ENOENT));
89}
90
Darin Petkov002b2fe2010-11-22 13:53:22 -080091TEST(UtilsTest, IsSymlinkTest) {
92 string temp_dir;
Gilad Arnolda6742b32014-01-11 00:18:34 -080093 EXPECT_TRUE(utils::MakeTempDirectory("symlink-test.XXXXXX", &temp_dir));
Alex Deymo8d925292014-05-21 19:15:25 -070094 string temp_file = temp_dir + "/temp-file";
Darin Petkov002b2fe2010-11-22 13:53:22 -080095 EXPECT_TRUE(utils::WriteFile(temp_file.c_str(), "", 0));
Alex Deymo8d925292014-05-21 19:15:25 -070096 string temp_symlink = temp_dir + "/temp-symlink";
Darin Petkov002b2fe2010-11-22 13:53:22 -080097 EXPECT_EQ(0, symlink(temp_file.c_str(), temp_symlink.c_str()));
98 EXPECT_FALSE(utils::IsSymlink(temp_dir.c_str()));
99 EXPECT_FALSE(utils::IsSymlink(temp_file.c_str()));
100 EXPECT_TRUE(utils::IsSymlink(temp_symlink.c_str()));
101 EXPECT_FALSE(utils::IsSymlink("/non/existent/path"));
Alex Deymo110e0302015-10-19 20:35:21 -0700102 EXPECT_TRUE(base::DeleteFile(base::FilePath(temp_dir), true));
Darin Petkov002b2fe2010-11-22 13:53:22 -0800103}
104
Alex Deymo763e7db2015-08-27 21:08:08 -0700105TEST(UtilsTest, SplitPartitionNameTest) {
106 string disk;
107 int part_num;
Darin Petkovf74eb652010-08-04 12:08:38 -0700108
Alex Deymo763e7db2015-08-27 21:08:08 -0700109 EXPECT_TRUE(utils::SplitPartitionName("/dev/sda3", &disk, &part_num));
110 EXPECT_EQ("/dev/sda", disk);
111 EXPECT_EQ(3, part_num);
Darin Petkovf74eb652010-08-04 12:08:38 -0700112
Alex Deymo763e7db2015-08-27 21:08:08 -0700113 EXPECT_TRUE(utils::SplitPartitionName("/dev/sdp1234", &disk, &part_num));
114 EXPECT_EQ("/dev/sdp", disk);
115 EXPECT_EQ(1234, part_num);
Andrew de los Reyesf9714432010-05-04 10:21:23 -0700116
Alex Deymo763e7db2015-08-27 21:08:08 -0700117 EXPECT_TRUE(utils::SplitPartitionName("/dev/mmcblk0p3", &disk, &part_num));
118 EXPECT_EQ("/dev/mmcblk0", disk);
119 EXPECT_EQ(3, part_num);
120
121 EXPECT_TRUE(utils::SplitPartitionName("/dev/ubiblock3_2", &disk, &part_num));
122 EXPECT_EQ("/dev/ubiblock", disk);
123 EXPECT_EQ(3, part_num);
124
125 EXPECT_TRUE(utils::SplitPartitionName("/dev/loop10", &disk, &part_num));
126 EXPECT_EQ("/dev/loop", disk);
127 EXPECT_EQ(10, part_num);
128
129 EXPECT_TRUE(utils::SplitPartitionName("/dev/loop28p11", &disk, &part_num));
130 EXPECT_EQ("/dev/loop28", disk);
131 EXPECT_EQ(11, part_num);
132
133 EXPECT_TRUE(utils::SplitPartitionName("/dev/loop10_0", &disk, &part_num));
134 EXPECT_EQ("/dev/loop", disk);
135 EXPECT_EQ(10, part_num);
136
137 EXPECT_TRUE(utils::SplitPartitionName("/dev/loop28p11_0", &disk, &part_num));
138 EXPECT_EQ("/dev/loop28", disk);
139 EXPECT_EQ(11, part_num);
140
141 EXPECT_FALSE(utils::SplitPartitionName("/dev/mmcblk0p", &disk, &part_num));
142 EXPECT_FALSE(utils::SplitPartitionName("/dev/sda", &disk, &part_num));
143 EXPECT_FALSE(utils::SplitPartitionName("/dev/foo/bar", &disk, &part_num));
144 EXPECT_FALSE(utils::SplitPartitionName("/", &disk, &part_num));
145 EXPECT_FALSE(utils::SplitPartitionName("", &disk, &part_num));
Andrew de los Reyesf9714432010-05-04 10:21:23 -0700146}
147
Alex Vakulenkof3f85bb2014-03-26 16:36:35 -0700148TEST(UtilsTest, MakePartitionNameTest) {
149 EXPECT_EQ("/dev/sda4", utils::MakePartitionName("/dev/sda", 4));
150 EXPECT_EQ("/dev/sda123", utils::MakePartitionName("/dev/sda", 123));
151 EXPECT_EQ("/dev/mmcblk2", utils::MakePartitionName("/dev/mmcblk", 2));
152 EXPECT_EQ("/dev/mmcblk0p2", utils::MakePartitionName("/dev/mmcblk0", 2));
153 EXPECT_EQ("/dev/loop8", utils::MakePartitionName("/dev/loop", 8));
154 EXPECT_EQ("/dev/loop12p2", utils::MakePartitionName("/dev/loop12", 2));
Nam T. Nguyena78b28c2015-03-06 22:30:12 -0800155 EXPECT_EQ("/dev/ubi5_0", utils::MakePartitionName("/dev/ubiblock", 5));
156 EXPECT_EQ("/dev/mtd4", utils::MakePartitionName("/dev/ubiblock", 4));
157 EXPECT_EQ("/dev/ubi3_0", utils::MakePartitionName("/dev/ubiblock", 3));
158 EXPECT_EQ("/dev/mtd2", utils::MakePartitionName("/dev/ubiblock", 2));
159 EXPECT_EQ("/dev/ubi1_0", utils::MakePartitionName("/dev/ubiblock", 1));
160}
161
162TEST(UtilsTest, MakePartitionNameForMountTest) {
163 EXPECT_EQ("/dev/sda4", utils::MakePartitionNameForMount("/dev/sda4"));
164 EXPECT_EQ("/dev/sda123", utils::MakePartitionNameForMount("/dev/sda123"));
165 EXPECT_EQ("/dev/mmcblk2", utils::MakePartitionNameForMount("/dev/mmcblk2"));
166 EXPECT_EQ("/dev/mmcblk0p2",
167 utils::MakePartitionNameForMount("/dev/mmcblk0p2"));
168 EXPECT_EQ("/dev/loop0", utils::MakePartitionNameForMount("/dev/loop0"));
169 EXPECT_EQ("/dev/loop8", utils::MakePartitionNameForMount("/dev/loop8"));
170 EXPECT_EQ("/dev/loop12p2",
171 utils::MakePartitionNameForMount("/dev/loop12p2"));
172 EXPECT_EQ("/dev/ubiblock5_0",
173 utils::MakePartitionNameForMount("/dev/ubiblock5_0"));
174 EXPECT_EQ("/dev/mtd4",
175 utils::MakePartitionNameForMount("/dev/ubi4_0"));
176 EXPECT_EQ("/dev/ubiblock3_0",
177 utils::MakePartitionNameForMount("/dev/ubiblock3"));
178 EXPECT_EQ("/dev/mtd2", utils::MakePartitionNameForMount("/dev/ubi2"));
179 EXPECT_EQ("/dev/ubi1_0",
180 utils::MakePartitionNameForMount("/dev/ubiblock1"));
Alex Vakulenkof3f85bb2014-03-26 16:36:35 -0700181}
182
Darin Petkov5c0a8af2010-08-24 13:39:13 -0700183TEST(UtilsTest, FuzzIntTest) {
184 static const unsigned int kRanges[] = { 0, 1, 2, 20 };
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800185 for (unsigned int range : kRanges) {
Darin Petkov5c0a8af2010-08-24 13:39:13 -0700186 const int kValue = 50;
187 for (int tries = 0; tries < 100; ++tries) {
188 int value = utils::FuzzInt(kValue, range);
189 EXPECT_GE(value, kValue - range / 2);
190 EXPECT_LE(value, kValue + range - range / 2);
191 }
192 }
193}
194
Darin Petkovd3f8c892010-10-12 21:38:45 -0700195TEST(UtilsTest, RunAsRootGetFilesystemSizeTest) {
196 string img;
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700197 EXPECT_TRUE(utils::MakeTempFile("img.XXXXXX", &img, nullptr));
Darin Petkovd3f8c892010-10-12 21:38:45 -0700198 ScopedPathUnlinker img_unlinker(img);
Alex Deymo10875d92014-11-10 21:52:57 -0800199 test_utils::CreateExtImageAtPath(img, nullptr);
Darin Petkovd3f8c892010-10-12 21:38:45 -0700200 // Extend the "partition" holding the file system from 10MiB to 20MiB.
Alex Deymo10875d92014-11-10 21:52:57 -0800201 EXPECT_EQ(0, test_utils::System(base::StringPrintf(
Alex Deymo1f93d032015-03-10 18:58:32 -0700202 "dd if=/dev/zero of=%s seek=20971519 bs=1 count=1 status=none",
Darin Petkovd3f8c892010-10-12 21:38:45 -0700203 img.c_str())));
204 EXPECT_EQ(20 * 1024 * 1024, utils::FileSize(img));
205 int block_count = 0;
206 int block_size = 0;
207 EXPECT_TRUE(utils::GetFilesystemSize(img, &block_count, &block_size));
208 EXPECT_EQ(4096, block_size);
209 EXPECT_EQ(10 * 1024 * 1024 / 4096, block_count);
210}
211
Alex Deymo192393b2014-11-10 15:58:38 -0800212// Squashfs example filesystem, generated with:
213// echo hola>hola
214// mksquashfs hola hola.sqfs -noappend -nopad
215// hexdump hola.sqfs -e '16/1 "%02x, " "\n"'
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800216const uint8_t kSquashfsFile[] = {
Alex Deymo192393b2014-11-10 15:58:38 -0800217 0x68, 0x73, 0x71, 0x73, 0x02, 0x00, 0x00, 0x00, // magic, inodes
218 0x3e, 0x49, 0x61, 0x54, 0x00, 0x00, 0x02, 0x00,
219 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00,
220 0xc0, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, // flags, noids, major, minor
221 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // root_inode
222 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // bytes_used
223 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
224 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
225 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
229 0x68, 0x6f, 0x6c, 0x61, 0x0a, 0x2c, 0x00, 0x78,
230 0xda, 0x63, 0x62, 0x58, 0xc2, 0xc8, 0xc0, 0xc0,
231 0xc8, 0xd0, 0x6b, 0x91, 0x18, 0x02, 0x64, 0xa0,
232 0x00, 0x56, 0x06, 0x90, 0xcc, 0x7f, 0xb0, 0xbc,
233 0x9d, 0x67, 0x62, 0x08, 0x13, 0x54, 0x1c, 0x44,
234 0x4b, 0x03, 0x31, 0x33, 0x10, 0x03, 0x00, 0xb5,
235 0x87, 0x04, 0x89, 0x16, 0x00, 0x78, 0xda, 0x63,
236 0x60, 0x80, 0x00, 0x46, 0x28, 0xcd, 0xc4, 0xc0,
237 0xcc, 0x90, 0x91, 0x9f, 0x93, 0x08, 0x00, 0x04,
238 0x70, 0x01, 0xab, 0x10, 0x80, 0x60, 0x00, 0x00,
239 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
240 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00,
241 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x78,
242 0xda, 0x63, 0x60, 0x80, 0x00, 0x05, 0x28, 0x0d,
243 0x00, 0x01, 0x10, 0x00, 0x21, 0xc5, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x99,
245 0xcd, 0x02, 0x00, 0x88, 0x13, 0x00, 0x00, 0xdd,
246 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
247};
248
249TEST(UtilsTest, GetSquashfs4Size) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800250 uint8_t buffer[sizeof(kSquashfsFile)];
Alex Deymo192393b2014-11-10 15:58:38 -0800251 memcpy(buffer, kSquashfsFile, sizeof(kSquashfsFile));
252
253 int block_count = -1;
254 int block_size = -1;
255 // Not enough bytes passed.
256 EXPECT_FALSE(utils::GetSquashfs4Size(buffer, 10, nullptr, nullptr));
257
258 // The whole file system is passed, which is enough for parsing.
259 EXPECT_TRUE(utils::GetSquashfs4Size(buffer, sizeof(kSquashfsFile),
260 &block_count, &block_size));
261 EXPECT_EQ(4096, block_size);
262 EXPECT_EQ(1, block_count);
263
264 // Modify the major version to 5.
265 uint16_t* s_major = reinterpret_cast<uint16_t*>(buffer + 0x1c);
266 *s_major = 5;
267 EXPECT_FALSE(utils::GetSquashfs4Size(buffer, 10, nullptr, nullptr));
268 memcpy(buffer, kSquashfsFile, sizeof(kSquashfsFile));
269
270 // Modify the bytes_used to have 6 blocks.
271 int64_t* bytes_used = reinterpret_cast<int64_t*>(buffer + 0x28);
272 *bytes_used = 4096 * 5 + 1; // 6 "blocks".
273 EXPECT_TRUE(utils::GetSquashfs4Size(buffer, sizeof(kSquashfsFile),
274 &block_count, &block_size));
275 EXPECT_EQ(4096, block_size);
276 EXPECT_EQ(6, block_count);
277}
278
Andrew de los Reyes712b3ac2011-01-07 13:47:52 -0800279namespace {
Alex Deymo032e7722014-03-25 17:53:56 -0700280void GetFileFormatTester(const string& expected,
Ben Chan9abb7632014-08-07 00:10:53 -0700281 const vector<uint8_t>& contents) {
Alex Deymo10875d92014-11-10 21:52:57 -0800282 test_utils::ScopedTempFile file;
Alex Deymo032e7722014-03-25 17:53:56 -0700283 ASSERT_TRUE(utils::WriteFile(file.GetPath().c_str(),
284 reinterpret_cast<const char*>(contents.data()),
285 contents.size()));
286 EXPECT_EQ(expected, utils::GetFileFormat(file.GetPath()));
287}
Alex Deymo10875d92014-11-10 21:52:57 -0800288} // namespace
Alex Deymo032e7722014-03-25 17:53:56 -0700289
290TEST(UtilsTest, GetFileFormatTest) {
291 EXPECT_EQ("File not found.", utils::GetFileFormat("/path/to/nowhere"));
Ben Chan9abb7632014-08-07 00:10:53 -0700292 GetFileFormatTester("data", vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8});
293 GetFileFormatTester("ELF", vector<uint8_t>{0x7f, 0x45, 0x4c, 0x46});
Alex Deymo032e7722014-03-25 17:53:56 -0700294
295 // Real tests from cros_installer on different boards.
296 // ELF 32-bit LSB executable, Intel 80386
297 GetFileFormatTester(
298 "ELF 32-bit little-endian x86",
Ben Chan9abb7632014-08-07 00:10:53 -0700299 vector<uint8_t>{0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
302 0x90, 0x83, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00});
Alex Deymo032e7722014-03-25 17:53:56 -0700303
Alex Deymoc1711e22014-08-08 13:16:23 -0700304 // ELF 32-bit LSB executable, MIPS
305 GetFileFormatTester(
306 "ELF 32-bit little-endian mips",
307 vector<uint8_t>{0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00,
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309 0x03, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
310 0xc0, 0x12, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00});
311
Alex Deymo032e7722014-03-25 17:53:56 -0700312 // ELF 32-bit LSB executable, ARM
313 GetFileFormatTester(
314 "ELF 32-bit little-endian arm",
Ben Chan9abb7632014-08-07 00:10:53 -0700315 vector<uint8_t>{0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
318 0x85, 0x8b, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00});
Alex Deymo032e7722014-03-25 17:53:56 -0700319
320 // ELF 64-bit LSB executable, x86-64
321 GetFileFormatTester(
322 "ELF 64-bit little-endian x86-64",
Ben Chan9abb7632014-08-07 00:10:53 -0700323 vector<uint8_t>{0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00,
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00,
326 0xb0, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00});
Alex Deymo032e7722014-03-25 17:53:56 -0700327}
328
Andrew de los Reyes712b3ac2011-01-07 13:47:52 -0800329TEST(UtilsTest, ScheduleCrashReporterUploadTest) {
330 // Not much to test. At least this tests for memory leaks, crashes,
331 // log errors.
Alex Deymo60ca1a72015-06-18 18:19:15 -0700332 FakeMessageLoop loop(nullptr);
333 loop.SetAsCurrent();
Andrew de los Reyes712b3ac2011-01-07 13:47:52 -0800334 utils::ScheduleCrashReporterUpload();
Alex Deymo60ca1a72015-06-18 18:19:15 -0700335 // Test that we scheduled one callback from the crash reporter.
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700336 EXPECT_EQ(1, brillo::MessageLoopRunMaxIterations(&loop, 100));
Alex Deymo60ca1a72015-06-18 18:19:15 -0700337 EXPECT_FALSE(loop.PendingTasks());
Andrew de los Reyes712b3ac2011-01-07 13:47:52 -0800338}
339
David Zeuthen674c3182013-04-18 14:05:20 -0700340TEST(UtilsTest, FormatTimeDeltaTest) {
341 // utils::FormatTimeDelta() is not locale-aware (it's only used for logging
342 // which is not localized) so we only need to test the C locale
343 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromMilliseconds(100)),
344 "0.1s");
345 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(0)),
346 "0s");
347 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(1)),
348 "1s");
349 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(59)),
350 "59s");
351 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(60)),
352 "1m0s");
353 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(61)),
354 "1m1s");
355 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(90)),
356 "1m30s");
357 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(1205)),
358 "20m5s");
359 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(3600)),
360 "1h0m0s");
361 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(3601)),
362 "1h0m1s");
363 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(3661)),
364 "1h1m1s");
365 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(7261)),
366 "2h1m1s");
367 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(86400)),
368 "1d0h0m0s");
369 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(86401)),
370 "1d0h0m1s");
371 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(200000)),
372 "2d7h33m20s");
373 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(200000) +
374 base::TimeDelta::FromMilliseconds(1)),
375 "2d7h33m20.001s");
David Zeuthen973449e2014-08-18 16:18:23 -0400376 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(-1)),
377 "-1s");
David Zeuthen674c3182013-04-18 14:05:20 -0700378}
379
David Zeuthen27a48bc2013-08-06 12:06:29 -0700380TEST(UtilsTest, TimeFromStructTimespecTest) {
381 struct timespec ts;
382
383 // Unix epoch (Thursday 00:00:00 UTC on Jan 1, 1970)
384 ts = (struct timespec) {.tv_sec = 0, .tv_nsec = 0};
385 EXPECT_EQ(base::Time::UnixEpoch(), utils::TimeFromStructTimespec(&ts));
386
387 // 42 ms after the Unix billennium (Sunday 01:46:40 UTC on September 9, 2001)
388 ts = (struct timespec) {.tv_sec = 1000 * 1000 * 1000,
389 .tv_nsec = 42 * 1000 * 1000};
390 base::Time::Exploded exploded = (base::Time::Exploded) {
391 .year = 2001, .month = 9, .day_of_week = 0, .day_of_month = 9,
392 .hour = 1, .minute = 46, .second = 40, .millisecond = 42};
393 EXPECT_EQ(base::Time::FromUTCExploded(exploded),
394 utils::TimeFromStructTimespec(&ts));
395}
396
David Zeuthene7f89172013-10-31 10:21:04 -0700397TEST(UtilsTest, DecodeAndStoreBase64String) {
398 base::FilePath path;
399
400 // Ensure we return false on empty strings or invalid base64.
401 EXPECT_FALSE(utils::DecodeAndStoreBase64String("", &path));
402 EXPECT_FALSE(utils::DecodeAndStoreBase64String("not valid base64", &path));
403
404 // Pass known base64 and check that it matches. This string was generated
405 // the following way:
406 //
407 // $ echo "Update Engine" | base64
408 // VXBkYXRlIEVuZ2luZQo=
409 EXPECT_TRUE(utils::DecodeAndStoreBase64String("VXBkYXRlIEVuZ2luZQo=",
410 &path));
411 ScopedPathUnlinker unlinker(path.value());
412 string expected_contents = "Update Engine\n";
413 string contents;
414 EXPECT_TRUE(utils::ReadFile(path.value(), &contents));
415 EXPECT_EQ(contents, expected_contents);
416 EXPECT_EQ(utils::FileSize(path.value()), expected_contents.size());
417}
418
David Zeuthen639aa362014-02-03 16:23:44 -0800419TEST(UtilsTest, ConvertToOmahaInstallDate) {
420 // The Omaha Epoch starts at Jan 1, 2007 0:00 PST which is a
421 // Monday. In Unix time, this point in time is easily obtained via
422 // the date(1) command like this:
423 //
424 // $ date +"%s" --date="Jan 1, 2007 0:00 PST"
425 const time_t omaha_epoch = 1167638400;
426 int value;
427
428 // Points in time *on and after* the Omaha epoch should not fail.
429 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
430 base::Time::FromTimeT(omaha_epoch), &value));
431 EXPECT_GE(value, 0);
432
433 // Anything before the Omaha epoch should fail. We test it for two points.
434 EXPECT_FALSE(utils::ConvertToOmahaInstallDate(
435 base::Time::FromTimeT(omaha_epoch - 1), &value));
436 EXPECT_FALSE(utils::ConvertToOmahaInstallDate(
437 base::Time::FromTimeT(omaha_epoch - 100*24*3600), &value));
438
439 // Check that we jump from 0 to 7 exactly on the one-week mark, e.g.
440 // on Jan 8, 2007 0:00 PST.
441 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
442 base::Time::FromTimeT(omaha_epoch + 7*24*3600 - 1), &value));
443 EXPECT_EQ(value, 0);
444 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
445 base::Time::FromTimeT(omaha_epoch + 7*24*3600), &value));
446 EXPECT_EQ(value, 7);
447
448 // Check a couple of more values.
449 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
450 base::Time::FromTimeT(omaha_epoch + 10*24*3600), &value));
451 EXPECT_EQ(value, 7);
452 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
453 base::Time::FromTimeT(omaha_epoch + 20*24*3600), &value));
454 EXPECT_EQ(value, 14);
455 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
456 base::Time::FromTimeT(omaha_epoch + 26*24*3600), &value));
457 EXPECT_EQ(value, 21);
458 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
459 base::Time::FromTimeT(omaha_epoch + 29*24*3600), &value));
460 EXPECT_EQ(value, 28);
461
462 // The date Jun 4, 2007 0:00 PDT is a Monday and is hence a point
463 // where the Omaha InstallDate jumps 7 days. Its unix time is
464 // 1180940400. Notably, this is a point in time where Daylight
465 // Savings Time (DST) was is in effect (e.g. it's PDT, not PST).
466 //
467 // Note that as utils::ConvertToOmahaInstallDate() _deliberately_
468 // ignores DST (as it's hard to implement in a thread-safe way using
469 // glibc, see comments in utils.h) we have to fudge by the DST
470 // offset which is one hour. Conveniently, if the function were
471 // someday modified to be DST aware, this test would have to be
472 // modified as well.
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700473 const time_t dst_time = 1180940400; // Jun 4, 2007 0:00 PDT.
David Zeuthen639aa362014-02-03 16:23:44 -0800474 const time_t fudge = 3600;
475 int value1, value2;
476 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
477 base::Time::FromTimeT(dst_time + fudge - 1), &value1));
478 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
479 base::Time::FromTimeT(dst_time + fudge), &value2));
480 EXPECT_EQ(value1, value2 - 7);
481}
482
Allie Wood78750a42015-02-11 15:42:11 -0800483TEST(UtilsTest, GetMinorVersion) {
484 // Test GetMinorVersion by verifying that it parses the conf file and returns
485 // the correct value.
Allie Wood78750a42015-02-11 15:42:11 -0800486 uint32_t minor_version;
487
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700488 brillo::KeyValueStore store;
Alex Deymob42b98d2015-07-06 17:42:38 -0700489 EXPECT_FALSE(utils::GetMinorVersion(store, &minor_version));
Allie Wood78750a42015-02-11 15:42:11 -0800490
Alex Deymob42b98d2015-07-06 17:42:38 -0700491 EXPECT_TRUE(store.LoadFromString("PAYLOAD_MINOR_VERSION=one-two-three\n"));
492 EXPECT_FALSE(utils::GetMinorVersion(store, &minor_version));
Allie Wood78750a42015-02-11 15:42:11 -0800493
Alex Deymob42b98d2015-07-06 17:42:38 -0700494 EXPECT_TRUE(store.LoadFromString("PAYLOAD_MINOR_VERSION=123\n"));
495 EXPECT_TRUE(utils::GetMinorVersion(store, &minor_version));
496 EXPECT_EQ(minor_version, 123);
Allie Wood78750a42015-02-11 15:42:11 -0800497}
498
Nam T. Nguyen2b67a592014-12-03 14:56:00 -0800499static bool BoolMacroTestHelper() {
500 int i = 1;
501 unsigned int ui = 1;
502 bool b = 1;
503 std::unique_ptr<char> cptr(new char);
504
505 TEST_AND_RETURN_FALSE(i);
506 TEST_AND_RETURN_FALSE(ui);
507 TEST_AND_RETURN_FALSE(b);
508 TEST_AND_RETURN_FALSE(cptr);
509
510 TEST_AND_RETURN_FALSE_ERRNO(i);
511 TEST_AND_RETURN_FALSE_ERRNO(ui);
512 TEST_AND_RETURN_FALSE_ERRNO(b);
513 TEST_AND_RETURN_FALSE_ERRNO(cptr);
514
515 return true;
516}
517
518static void VoidMacroTestHelper(bool* ret) {
519 int i = 1;
520 unsigned int ui = 1;
521 bool b = 1;
522 std::unique_ptr<char> cptr(new char);
523
524 *ret = false;
525
526 TEST_AND_RETURN(i);
527 TEST_AND_RETURN(ui);
528 TEST_AND_RETURN(b);
529 TEST_AND_RETURN(cptr);
530
531 TEST_AND_RETURN_ERRNO(i);
532 TEST_AND_RETURN_ERRNO(ui);
533 TEST_AND_RETURN_ERRNO(b);
534 TEST_AND_RETURN_ERRNO(cptr);
535
536 *ret = true;
537}
538
539TEST(UtilsTest, TestMacros) {
540 bool void_test = false;
541 VoidMacroTestHelper(&void_test);
542 EXPECT_TRUE(void_test);
543
544 EXPECT_TRUE(BoolMacroTestHelper());
545}
546
adlr@google.com3defe6a2009-12-04 20:57:17 +0000547} // namespace chromeos_update_engine