blob: 24468b91b8e7d216ada3a1133fa0d396ddfa36bc [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) {
Alex Deymo80f70ff2016-02-10 16:08:11 -0800184 static const uint32_t kRanges[] = { 0, 1, 2, 20 };
185 for (uint32_t range : kRanges) {
Darin Petkov5c0a8af2010-08-24 13:39:13 -0700186 const int kValue = 50;
187 for (int tries = 0; tries < 100; ++tries) {
Alex Deymo80f70ff2016-02-10 16:08:11 -0800188 uint32_t value = utils::FuzzInt(kValue, range);
Darin Petkov5c0a8af2010-08-24 13:39:13 -0700189 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);
Alex Deymo5fe0c4e2016-02-16 18:46:24 -0800416 EXPECT_EQ(static_cast<off_t>(expected_contents.size()),
417 utils::FileSize(path.value()));
David Zeuthene7f89172013-10-31 10:21:04 -0700418}
419
David Zeuthen639aa362014-02-03 16:23:44 -0800420TEST(UtilsTest, ConvertToOmahaInstallDate) {
421 // The Omaha Epoch starts at Jan 1, 2007 0:00 PST which is a
422 // Monday. In Unix time, this point in time is easily obtained via
423 // the date(1) command like this:
424 //
425 // $ date +"%s" --date="Jan 1, 2007 0:00 PST"
426 const time_t omaha_epoch = 1167638400;
427 int value;
428
429 // Points in time *on and after* the Omaha epoch should not fail.
430 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
431 base::Time::FromTimeT(omaha_epoch), &value));
432 EXPECT_GE(value, 0);
433
434 // Anything before the Omaha epoch should fail. We test it for two points.
435 EXPECT_FALSE(utils::ConvertToOmahaInstallDate(
436 base::Time::FromTimeT(omaha_epoch - 1), &value));
437 EXPECT_FALSE(utils::ConvertToOmahaInstallDate(
438 base::Time::FromTimeT(omaha_epoch - 100*24*3600), &value));
439
440 // Check that we jump from 0 to 7 exactly on the one-week mark, e.g.
441 // on Jan 8, 2007 0:00 PST.
442 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
443 base::Time::FromTimeT(omaha_epoch + 7*24*3600 - 1), &value));
444 EXPECT_EQ(value, 0);
445 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
446 base::Time::FromTimeT(omaha_epoch + 7*24*3600), &value));
447 EXPECT_EQ(value, 7);
448
449 // Check a couple of more values.
450 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
451 base::Time::FromTimeT(omaha_epoch + 10*24*3600), &value));
452 EXPECT_EQ(value, 7);
453 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
454 base::Time::FromTimeT(omaha_epoch + 20*24*3600), &value));
455 EXPECT_EQ(value, 14);
456 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
457 base::Time::FromTimeT(omaha_epoch + 26*24*3600), &value));
458 EXPECT_EQ(value, 21);
459 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
460 base::Time::FromTimeT(omaha_epoch + 29*24*3600), &value));
461 EXPECT_EQ(value, 28);
462
463 // The date Jun 4, 2007 0:00 PDT is a Monday and is hence a point
464 // where the Omaha InstallDate jumps 7 days. Its unix time is
465 // 1180940400. Notably, this is a point in time where Daylight
466 // Savings Time (DST) was is in effect (e.g. it's PDT, not PST).
467 //
468 // Note that as utils::ConvertToOmahaInstallDate() _deliberately_
469 // ignores DST (as it's hard to implement in a thread-safe way using
470 // glibc, see comments in utils.h) we have to fudge by the DST
471 // offset which is one hour. Conveniently, if the function were
472 // someday modified to be DST aware, this test would have to be
473 // modified as well.
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700474 const time_t dst_time = 1180940400; // Jun 4, 2007 0:00 PDT.
David Zeuthen639aa362014-02-03 16:23:44 -0800475 const time_t fudge = 3600;
476 int value1, value2;
477 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
478 base::Time::FromTimeT(dst_time + fudge - 1), &value1));
479 EXPECT_TRUE(utils::ConvertToOmahaInstallDate(
480 base::Time::FromTimeT(dst_time + fudge), &value2));
481 EXPECT_EQ(value1, value2 - 7);
482}
483
Allie Wood78750a42015-02-11 15:42:11 -0800484TEST(UtilsTest, GetMinorVersion) {
485 // Test GetMinorVersion by verifying that it parses the conf file and returns
486 // the correct value.
Allie Wood78750a42015-02-11 15:42:11 -0800487 uint32_t minor_version;
488
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700489 brillo::KeyValueStore store;
Alex Deymob42b98d2015-07-06 17:42:38 -0700490 EXPECT_FALSE(utils::GetMinorVersion(store, &minor_version));
Allie Wood78750a42015-02-11 15:42:11 -0800491
Alex Deymob42b98d2015-07-06 17:42:38 -0700492 EXPECT_TRUE(store.LoadFromString("PAYLOAD_MINOR_VERSION=one-two-three\n"));
493 EXPECT_FALSE(utils::GetMinorVersion(store, &minor_version));
Allie Wood78750a42015-02-11 15:42:11 -0800494
Alex Deymob42b98d2015-07-06 17:42:38 -0700495 EXPECT_TRUE(store.LoadFromString("PAYLOAD_MINOR_VERSION=123\n"));
496 EXPECT_TRUE(utils::GetMinorVersion(store, &minor_version));
Alex Deymo80f70ff2016-02-10 16:08:11 -0800497 EXPECT_EQ(123U, minor_version);
Allie Wood78750a42015-02-11 15:42:11 -0800498}
499
Nam T. Nguyen2b67a592014-12-03 14:56:00 -0800500static bool BoolMacroTestHelper() {
501 int i = 1;
502 unsigned int ui = 1;
503 bool b = 1;
504 std::unique_ptr<char> cptr(new char);
505
506 TEST_AND_RETURN_FALSE(i);
507 TEST_AND_RETURN_FALSE(ui);
508 TEST_AND_RETURN_FALSE(b);
509 TEST_AND_RETURN_FALSE(cptr);
510
511 TEST_AND_RETURN_FALSE_ERRNO(i);
512 TEST_AND_RETURN_FALSE_ERRNO(ui);
513 TEST_AND_RETURN_FALSE_ERRNO(b);
514 TEST_AND_RETURN_FALSE_ERRNO(cptr);
515
516 return true;
517}
518
519static void VoidMacroTestHelper(bool* ret) {
520 int i = 1;
521 unsigned int ui = 1;
522 bool b = 1;
523 std::unique_ptr<char> cptr(new char);
524
525 *ret = false;
526
527 TEST_AND_RETURN(i);
528 TEST_AND_RETURN(ui);
529 TEST_AND_RETURN(b);
530 TEST_AND_RETURN(cptr);
531
532 TEST_AND_RETURN_ERRNO(i);
533 TEST_AND_RETURN_ERRNO(ui);
534 TEST_AND_RETURN_ERRNO(b);
535 TEST_AND_RETURN_ERRNO(cptr);
536
537 *ret = true;
538}
539
540TEST(UtilsTest, TestMacros) {
541 bool void_test = false;
542 VoidMacroTestHelper(&void_test);
543 EXPECT_TRUE(void_test);
544
545 EXPECT_TRUE(BoolMacroTestHelper());
546}
547
adlr@google.com3defe6a2009-12-04 20:57:17 +0000548} // namespace chromeos_update_engine