utils_unittest.cc revision ab0d976fa47844870d55c87ab530072cea0c8c53
1// 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// 16 17#include "update_engine/common/utils.h" 18 19#include <errno.h> 20#include <stdint.h> 21#include <sys/stat.h> 22#include <sys/types.h> 23 24#include <map> 25#include <string> 26#include <vector> 27 28#include <base/files/file_path.h> 29#include <base/files/file_util.h> 30#include <base/files/scoped_temp_dir.h> 31#include <base/strings/string_util.h> 32#include <base/strings/stringprintf.h> 33#include <brillo/message_loops/fake_message_loop.h> 34#include <brillo/message_loops/message_loop_utils.h> 35#include <gtest/gtest.h> 36 37#include "update_engine/common/test_utils.h" 38 39using brillo::FakeMessageLoop; 40using std::map; 41using std::string; 42using std::vector; 43 44namespace chromeos_update_engine { 45 46class UtilsTest : public ::testing::Test { }; 47 48TEST(UtilsTest, CanParseECVersion) { 49 // Should be able to parse and valid key value line. 50 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( 55 "vendor=\"sam\" fw_version=\"00VFA616\"")); 56 57 // For invalid entries, should return the empty string. 58 EXPECT_EQ("", utils::ParseECVersion("b=1231a fw_version a=fasd2")); 59} 60 61TEST(UtilsTest, ReadFileFailure) { 62 brillo::Blob empty; 63 EXPECT_FALSE(utils::ReadFile("/this/doesn't/exist", &empty)); 64} 65 66TEST(UtilsTest, ReadFileChunk) { 67 base::FilePath file; 68 EXPECT_TRUE(base::CreateTemporaryFile(&file)); 69 ScopedPathUnlinker unlinker(file.value()); 70 brillo::Blob data; 71 const size_t kSize = 1024 * 1024; 72 for (size_t i = 0; i < kSize; i++) { 73 data.push_back(i % 255); 74 } 75 EXPECT_TRUE(utils::WriteFile(file.value().c_str(), data.data(), data.size())); 76 brillo::Blob in_data; 77 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)); 83 EXPECT_TRUE(brillo::Blob(data.begin() + 10, data.begin() + 10 + 20) == 84 in_data); 85} 86 87TEST(UtilsTest, ErrnoNumberAsStringTest) { 88 EXPECT_EQ("No such file or directory", utils::ErrnoNumberAsString(ENOENT)); 89} 90 91TEST(UtilsTest, IsSymlinkTest) { 92 string temp_dir; 93 EXPECT_TRUE(utils::MakeTempDirectory("symlink-test.XXXXXX", &temp_dir)); 94 string temp_file = temp_dir + "/temp-file"; 95 EXPECT_TRUE(utils::WriteFile(temp_file.c_str(), "", 0)); 96 string temp_symlink = temp_dir + "/temp-symlink"; 97 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")); 102 EXPECT_TRUE(base::DeleteFile(base::FilePath(temp_dir), true)); 103} 104 105TEST(UtilsTest, SplitPartitionNameTest) { 106 string disk; 107 int part_num; 108 109 EXPECT_TRUE(utils::SplitPartitionName("/dev/sda3", &disk, &part_num)); 110 EXPECT_EQ("/dev/sda", disk); 111 EXPECT_EQ(3, part_num); 112 113 EXPECT_TRUE(utils::SplitPartitionName("/dev/sdp1234", &disk, &part_num)); 114 EXPECT_EQ("/dev/sdp", disk); 115 EXPECT_EQ(1234, part_num); 116 117 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)); 146} 147 148TEST(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)); 155 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")); 181} 182 183TEST(UtilsTest, FuzzIntTest) { 184 static const unsigned int kRanges[] = { 0, 1, 2, 20 }; 185 for (unsigned int range : kRanges) { 186 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 195TEST(UtilsTest, RunAsRootGetFilesystemSizeTest) { 196 string img; 197 EXPECT_TRUE(utils::MakeTempFile("img.XXXXXX", &img, nullptr)); 198 ScopedPathUnlinker img_unlinker(img); 199 test_utils::CreateExtImageAtPath(img, nullptr); 200 // Extend the "partition" holding the file system from 10MiB to 20MiB. 201 EXPECT_EQ(0, test_utils::System(base::StringPrintf( 202 "dd if=/dev/zero of=%s seek=20971519 bs=1 count=1 status=none", 203 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 212// 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"' 216const uint8_t kSquashfsFile[] = { 217 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) { 250 uint8_t buffer[sizeof(kSquashfsFile)]; 251 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 279namespace { 280void GetFileFormatTester(const string& expected, 281 const vector<uint8_t>& contents) { 282 test_utils::ScopedTempFile file; 283 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} 288} // namespace 289 290TEST(UtilsTest, GetFileFormatTest) { 291 EXPECT_EQ("File not found.", utils::GetFileFormat("/path/to/nowhere")); 292 GetFileFormatTester("data", vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8}); 293 GetFileFormatTester("ELF", vector<uint8_t>{0x7f, 0x45, 0x4c, 0x46}); 294 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", 299 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}); 303 304 // 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 312 // ELF 32-bit LSB executable, ARM 313 GetFileFormatTester( 314 "ELF 32-bit little-endian arm", 315 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}); 319 320 // ELF 64-bit LSB executable, x86-64 321 GetFileFormatTester( 322 "ELF 64-bit little-endian x86-64", 323 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}); 327} 328 329TEST(UtilsTest, ScheduleCrashReporterUploadTest) { 330 // Not much to test. At least this tests for memory leaks, crashes, 331 // log errors. 332 FakeMessageLoop loop(nullptr); 333 loop.SetAsCurrent(); 334 utils::ScheduleCrashReporterUpload(); 335 // Test that we scheduled one callback from the crash reporter. 336 EXPECT_EQ(1, brillo::MessageLoopRunMaxIterations(&loop, 100)); 337 EXPECT_FALSE(loop.PendingTasks()); 338} 339 340TEST(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"); 376 EXPECT_EQ(utils::FormatTimeDelta(base::TimeDelta::FromSeconds(-1)), 377 "-1s"); 378} 379 380TEST(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 397TEST(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 419TEST(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. 473 const time_t dst_time = 1180940400; // Jun 4, 2007 0:00 PDT. 474 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 483TEST(UtilsTest, GetMinorVersion) { 484 // Test GetMinorVersion by verifying that it parses the conf file and returns 485 // the correct value. 486 uint32_t minor_version; 487 488 brillo::KeyValueStore store; 489 EXPECT_FALSE(utils::GetMinorVersion(store, &minor_version)); 490 491 EXPECT_TRUE(store.LoadFromString("PAYLOAD_MINOR_VERSION=one-two-three\n")); 492 EXPECT_FALSE(utils::GetMinorVersion(store, &minor_version)); 493 494 EXPECT_TRUE(store.LoadFromString("PAYLOAD_MINOR_VERSION=123\n")); 495 EXPECT_TRUE(utils::GetMinorVersion(store, &minor_version)); 496 EXPECT_EQ(minor_version, 123); 497} 498 499static 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 547} // namespace chromeos_update_engine 548