test_utils.cc revision 305345001d85ca2282112c2a30fe75c7a4773491
18155d081dc729d407f8ff9e95b4ef91ae14281ceMike Frysinger// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Use of this source code is governed by a BSD-style license that can be 349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// found in the LICENSE file. 449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 5c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include "update_engine/test_utils.h" 609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo#include <attr/xattr.h> 86b9e38ef1180efe55e4a82bb18536d1b53fe493dAlex Deymo#include <dirent.h> 9c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include <errno.h> 1049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <stdio.h> 1149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <stdlib.h> 12161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymo#include <sys/stat.h> 13161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymo#include <sys/types.h> 1449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <unistd.h> 1509e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 16c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include <set> 1749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <string> 1849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <vector> 1909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 202b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo#include <base/files/file_util.h> 21161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymo#include <base/logging.h> 222b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo#include <base/strings/string_util.h> 23305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo#include <base/strings/stringprintf.h> 24161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymo 2549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "update_engine/file_writer.h" 26c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include "update_engine/utils.h" 2749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 28161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymousing base::StringPrintf; 29c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comusing std::set; 3049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comusing std::string; 3149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comusing std::vector; 3249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 3349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace chromeos_update_engine { 3449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 3552490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymovoid PrintTo(const Extent& extent, ::std::ostream* os) { 3652490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo *os << "(" << extent.start_block() << ", " << extent.num_blocks() << ")"; 3752490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo} 3852490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo 3910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymonamespace test_utils { 4010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 41a6742b35938b6f58e24e3f1c550fe92d4d33eb74Gilad Arnoldconst char* const kMountPathTemplate = "UpdateEngineTests_mnt-XXXXXX"; 4261d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold 43f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkoconst uint8_t kRandomString[] = { 4410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xf2, 0xb7, 0x55, 0x92, 0xea, 0xa6, 0xc9, 0x57, 4510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xe0, 0xf8, 0xeb, 0x34, 0x93, 0xd9, 0xc4, 0x8f, 4610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xcb, 0x20, 0xfa, 0x37, 0x4b, 0x40, 0xcf, 0xdc, 4710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xa5, 0x08, 0x70, 0x89, 0x79, 0x35, 0xe2, 0x3d, 4810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x56, 0xa4, 0x75, 0x73, 0xa3, 0x6d, 0xd1, 0xd5, 4910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x26, 0xbb, 0x9c, 0x60, 0xbd, 0x2f, 0x5a, 0xfa, 5010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xb7, 0xd4, 0x3a, 0x50, 0xa7, 0x6b, 0x3e, 0xfd, 5110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x61, 0x2b, 0x3a, 0x31, 0x30, 0x13, 0x33, 0x53, 5210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xdb, 0xd0, 0x32, 0x71, 0x5c, 0x39, 0xed, 0xda, 5310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xb4, 0x84, 0xca, 0xbc, 0xbd, 0x78, 0x1c, 0x0c, 5410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xd8, 0x0b, 0x41, 0xe8, 0xe1, 0xe0, 0x41, 0xad, 5510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x03, 0x12, 0xd3, 0x3d, 0xb8, 0x75, 0x9b, 0xe6, 5610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xd9, 0x01, 0xd0, 0x87, 0xf4, 0x36, 0xfa, 0xa7, 5710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x0a, 0xfa, 0xc5, 0x87, 0x65, 0xab, 0x9a, 0x7b, 5810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xeb, 0x58, 0x23, 0xf0, 0xa8, 0x0a, 0xf2, 0x33, 5910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x3a, 0xe2, 0xe3, 0x35, 0x74, 0x95, 0xdd, 0x3c, 6010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x59, 0x5a, 0xd9, 0x52, 0x3a, 0x3c, 0xac, 0xe5, 6110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x15, 0x87, 0x6d, 0x82, 0xbc, 0xf8, 0x7d, 0xbe, 6210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xca, 0xd3, 0x2c, 0xd6, 0xec, 0x38, 0xeb, 0xe4, 6310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x53, 0xb0, 0x4c, 0x3f, 0x39, 0x29, 0xf7, 0xa4, 6410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x73, 0xa8, 0xcb, 0x32, 0x50, 0x05, 0x8c, 0x1c, 6510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x1c, 0xca, 0xc9, 0x76, 0x0b, 0x8f, 0x6b, 0x57, 6610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x1f, 0x24, 0x2b, 0xba, 0x82, 0xba, 0xed, 0x58, 6710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xd8, 0xbf, 0xec, 0x06, 0x64, 0x52, 0x6a, 0x3f, 6810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xe4, 0xad, 0xce, 0x84, 0xb4, 0x27, 0x55, 0x14, 6910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xe3, 0x75, 0x59, 0x73, 0x71, 0x51, 0xea, 0xe8, 7010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xcc, 0xda, 0x4f, 0x09, 0xaf, 0xa4, 0xbc, 0x0e, 7110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xa6, 0x1f, 0xe2, 0x3a, 0xf8, 0x96, 0x7d, 0x30, 7210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x23, 0xc5, 0x12, 0xb5, 0xd8, 0x73, 0x6b, 0x71, 7310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xab, 0xf1, 0xd7, 0x43, 0x58, 0xa7, 0xc9, 0xf0, 7410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xe4, 0x85, 0x1c, 0xd6, 0x92, 0x50, 0x2c, 0x98, 7510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x36, 0xfe, 0x87, 0xaf, 0x43, 0x8f, 0x8f, 0xf5, 7610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x88, 0x48, 0x18, 0x42, 0xcf, 0x42, 0xc1, 0xa8, 7710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xe8, 0x05, 0x08, 0xa1, 0x45, 0x70, 0x5b, 0x8c, 7810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x39, 0x28, 0xab, 0xe9, 0x6b, 0x51, 0xd2, 0xcb, 7910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x30, 0x04, 0xea, 0x7d, 0x2f, 0x6e, 0x6c, 0x3b, 8010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x5f, 0x82, 0xd9, 0x5b, 0x89, 0x37, 0x65, 0x65, 8110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xbe, 0x9f, 0xa3, 0x5d, 8210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo}; 8310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 8410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymobool IsXAttrSupported(const base::FilePath& dir_path) { 8510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo char *path = strdup(dir_path.Append("xattr_test_XXXXXX").value().c_str()); 8610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 8710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo int fd = mkstemp(path); 8810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (fd == -1) { 8910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo PLOG(ERROR) << "Error creating temporary file in " << dir_path.value(); 9010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo free(path); 9110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo return false; 9210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 9310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 9410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (unlink(path) != 0) { 9510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo PLOG(ERROR) << "Error unlinking temporary file " << path; 9610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo close(fd); 9710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo free(path); 9810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo return false; 9910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 10010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 10110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo int xattr_res = fsetxattr(fd, "user.xattr-test", "value", strlen("value"), 0); 10210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (xattr_res != 0) { 10310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (errno == ENOTSUP) { 10410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // Leave it to call-sites to warn about non-support. 10510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } else { 10610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo PLOG(ERROR) << "Error setting xattr on " << path; 10710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 10810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 10910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo close(fd); 11010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo free(path); 11110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo return xattr_res == 0; 11210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo} 11310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 114f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkobool WriteFileVector(const string& path, const chromeos::Blob& data) { 115f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko return utils::WriteFile(path.c_str(), data.data(), data.size()); 116c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com} 117c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 118f329b933db41d26644a97afef928eb1b319d6d99Alex Deymobool WriteFileString(const string& path, const string& data) { 119970bb28905b44bf9f2cb986bb412ecda1095b0b1Andrew de los Reyes return utils::WriteFile(path.c_str(), data.data(), data.size()); 120c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com} 121c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 12219a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// Binds provided |filename| to an unused loopback device, whose name is written 12319a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// to the string pointed to by |lo_dev_name_p|. Returns true on success, false 12419a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// otherwise (along with corresponding test failures), in which case the content 12519a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// of |lo_dev_name_p| is unknown. 12619a45f0eda0917b7788b925b501e774208474fdeGilad Arnoldbool BindToUnusedLoopDevice(const string& filename, string* lo_dev_name_p) { 12719a45f0eda0917b7788b925b501e774208474fdeGilad Arnold CHECK(lo_dev_name_p); 12819a45f0eda0917b7788b925b501e774208474fdeGilad Arnold 12919a45f0eda0917b7788b925b501e774208474fdeGilad Arnold // Bind to an unused loopback device, sanity check the device name. 13019a45f0eda0917b7788b925b501e774208474fdeGilad Arnold lo_dev_name_p->clear(); 13119a45f0eda0917b7788b925b501e774208474fdeGilad Arnold if (!(utils::ReadPipe("losetup --show -f " + filename, lo_dev_name_p) && 1326a9d3497bcf57b8b9f5765a2909a51c9f8119cd1Alex Vakulenko base::StartsWithASCII(*lo_dev_name_p, "/dev/loop", true))) { 13319a45f0eda0917b7788b925b501e774208474fdeGilad Arnold ADD_FAILURE(); 13419a45f0eda0917b7788b925b501e774208474fdeGilad Arnold return false; 135c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com } 136c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 13719a45f0eda0917b7788b925b501e774208474fdeGilad Arnold // Strip anything from the first newline char. 13819a45f0eda0917b7788b925b501e774208474fdeGilad Arnold size_t newline_pos = lo_dev_name_p->find('\n'); 13919a45f0eda0917b7788b925b501e774208474fdeGilad Arnold if (newline_pos != string::npos) 14019a45f0eda0917b7788b925b501e774208474fdeGilad Arnold lo_dev_name_p->erase(newline_pos); 141c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 14219a45f0eda0917b7788b925b501e774208474fdeGilad Arnold return true; 143c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com} 144c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 145f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkobool ExpectVectorsEq(const chromeos::Blob& expected, 146f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko const chromeos::Blob& actual) { 1478006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes EXPECT_EQ(expected.size(), actual.size()); 1488006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes if (expected.size() != actual.size()) 149c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com return false; 150617bbc23d2cf4cba5881ec54607926393f7245c7Gilad Arnold bool is_all_eq = true; 1518006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes for (unsigned int i = 0; i < expected.size(); i++) { 1528006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes EXPECT_EQ(expected[i], actual[i]) << "offset: " << i; 153617bbc23d2cf4cba5881ec54607926393f7245c7Gilad Arnold is_all_eq = is_all_eq && (expected[i] == actual[i]); 154c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com } 155617bbc23d2cf4cba5881ec54607926393f7245c7Gilad Arnold return is_all_eq; 156c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com} 157c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 158f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkovoid FillWithData(chromeos::Blob* buffer) { 1598006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes size_t input_counter = 0; 160f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko for (uint8_t& b : *buffer) { 161f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko b = kRandomString[input_counter]; 1628006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes input_counter++; 1638006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes input_counter %= sizeof(kRandomString); 1648006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes } 1658006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes} 1668006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 1675c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Levoid CreateEmptyExtImageAtPath(const string& path, 1685c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le size_t size, 1695c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le int block_size) { 1705c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le EXPECT_EQ(0, System(StringPrintf("dd if=/dev/zero of=%s" 1711f93d031baa4c0c4f390fcf5784b5179d15f289dAlex Deymo " seek=%zu bs=1 count=1 status=none", 1725c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le path.c_str(), size))); 1736ded6548c4d3606923d606981dd29f224bcfc723Alex Deymo EXPECT_EQ(0, System(StringPrintf("mkfs.ext3 -q -b %d -F %s", 1745c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le block_size, path.c_str()))); 1755c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le} 1765c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 177c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comvoid CreateExtImageAtPath(const string& path, vector<string>* out_paths) { 17861d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold // create 10MiB sparse file, mounted at a unique location. 17961d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold string mount_path; 18061d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold CHECK(utils::MakeTempDirectory(kMountPathTemplate, &mount_path)); 181a58b62a57eb2fe4070ed7efbf869b37037fbeaa7Alex Deymo ScopedDirRemover mount_path_unlinker(mount_path); 18261d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold 183c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_EQ(0, System(StringPrintf("dd if=/dev/zero of=%s" 1841f93d031baa4c0c4f390fcf5784b5179d15f289dAlex Deymo " seek=10485759 bs=1 count=1 status=none", 185c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com path.c_str()))); 1866ded6548c4d3606923d606981dd29f224bcfc723Alex Deymo EXPECT_EQ(0, System(StringPrintf("mkfs.ext3 -q -b 4096 -F %s", 1876ded6548c4d3606923d606981dd29f224bcfc723Alex Deymo path.c_str()))); 188c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_EQ(0, System(StringPrintf("mount -o loop %s %s", path.c_str(), 18961d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 19061d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("echo hi > %s/hi", mount_path.c_str()))); 19161d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("echo hello > %s/hello", 19261d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 19361d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("mkdir %s/some_dir", mount_path.c_str()))); 19461d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("mkdir %s/some_dir/empty_dir", 19561d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 19661d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("mkdir %s/some_dir/mnt", 19761d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 19861d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("echo T > %s/some_dir/test", 19961d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 20061d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("mkfifo %s/some_dir/fifo", 20161d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 20261d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("mknod %s/cdev c 2 3", mount_path.c_str()))); 20361d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("ln -s /some/target %s/sym", 20461d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 205c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_EQ(0, System(StringPrintf("ln %s/some_dir/test %s/testlink", 20661d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str(), mount_path.c_str()))); 20761d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("echo T > %s/srchardlink0", 20861d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 20929da8aafd5da32ebfb57c7f3cf1b89ce3e5d60cbAndrew de los Reyes EXPECT_EQ(0, System(StringPrintf("ln %s/srchardlink0 %s/srchardlink1", 21061d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str(), mount_path.c_str()))); 21148a0a4826c47fe097d7ff31ad830911c1f288dbfAndrew de los Reyes EXPECT_EQ(0, System(StringPrintf("ln -s bogus %s/boguslink", 21261d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 21361d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_TRUE(utils::UnmountFilesystem(mount_path.c_str())); 2145c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 215c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com if (out_paths) { 216c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->clear(); 217c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back(""); 218c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/hi"); 21948a0a4826c47fe097d7ff31ad830911c1f288dbfAndrew de los Reyes out_paths->push_back("/boguslink"); 220c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/hello"); 221c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/some_dir"); 222c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/some_dir/empty_dir"); 223c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/some_dir/mnt"); 224c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/some_dir/test"); 225c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/some_dir/fifo"); 226c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/cdev"); 227c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/testlink"); 228c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/sym"); 22929da8aafd5da32ebfb57c7f3cf1b89ce3e5d60cbAndrew de los Reyes out_paths->push_back("/srchardlink0"); 23029da8aafd5da32ebfb57c7f3cf1b89ce3e5d60cbAndrew de los Reyes out_paths->push_back("/srchardlink1"); 231c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/lost+found"); 232c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com } 233c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com} 234c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 23558e8b1f8b32b355d879008572648fd621873711dDon GarrettScopedLoopMounter::ScopedLoopMounter(const string& file_path, 23658e8b1f8b32b355d879008572648fd621873711dDon Garrett string* mnt_path, 237d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko unsigned long flags) { // NOLINT - long 238a6742b35938b6f58e24e3f1c550fe92d4d33eb74Gilad Arnold EXPECT_TRUE(utils::MakeTempDirectory("mnt.XXXXXX", mnt_path)); 2395c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le dir_remover_.reset(new ScopedDirRemover(*mnt_path)); 2405c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 24158e8b1f8b32b355d879008572648fd621873711dDon Garrett string loop_dev; 24258e8b1f8b32b355d879008572648fd621873711dDon Garrett loop_binder_.reset(new ScopedLoopbackDeviceBinder(file_path, &loop_dev)); 2435c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 2445c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le EXPECT_TRUE(utils::MountFilesystem(loop_dev, *mnt_path, flags)); 2455c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le unmounter_.reset(new ScopedFilesystemUnmounter(*mnt_path)); 2465c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le} 2475c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 24810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymonamespace { 24910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymoclass ScopedDirCloser { 25010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo public: 25110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo explicit ScopedDirCloser(DIR** dir) : dir_(dir) {} 25210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo ~ScopedDirCloser() { 25310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (dir_ && *dir_) { 25410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo int r = closedir(*dir_); 25510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_ERRNO(r == 0); 25610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo *dir_ = nullptr; 25710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo dir_ = nullptr; 25810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 25910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 26010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo private: 26110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo DIR** dir_; 26210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo}; 26310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo} // namespace 26410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 26510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymobool RecursiveUnlinkDir(const string& path) { 26610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo struct stat stbuf; 26710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo int r = lstat(path.c_str(), &stbuf); 26810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_FALSE_ERRNO((r == 0) || (errno == ENOENT)); 26910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if ((r < 0) && (errno == ENOENT)) 27010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // path request is missing. that's fine. 27110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo return true; 27210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (!S_ISDIR(stbuf.st_mode)) { 27310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_FALSE_ERRNO((unlink(path.c_str()) == 0) || 27410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo (errno == ENOENT)); 27510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // success or path disappeared before we could unlink. 27610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo return true; 27710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 27810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo { 27910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // We have a dir, unlink all children, then delete dir 28010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo DIR *dir = opendir(path.c_str()); 28110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_FALSE_ERRNO(dir); 28210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo ScopedDirCloser dir_closer(&dir); 28310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo struct dirent dir_entry; 28410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo struct dirent *dir_entry_p; 28510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo int err = 0; 28610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo while ((err = readdir_r(dir, &dir_entry, &dir_entry_p)) == 0) { 28710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (dir_entry_p == nullptr) { 28810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // end of stream reached 28910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo break; 29010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 29110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // Skip . and .. 29210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (!strcmp(dir_entry_p->d_name, ".") || 29310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo !strcmp(dir_entry_p->d_name, "..")) 29410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo continue; 29510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_FALSE(RecursiveUnlinkDir(path + "/" + 29610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo dir_entry_p->d_name)); 29710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 29810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_FALSE(err == 0); 29910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 30010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // unlink dir 30110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_FALSE_ERRNO((rmdir(path.c_str()) == 0) || (errno == ENOENT)); 30210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo return true; 30310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo} 30410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 3052b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymobase::FilePath GetBuildArtifactsPath() { 3062b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo base::FilePath exe_path; 3072b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo base::ReadSymbolicLink(base::FilePath("/proc/self/exe"), &exe_path); 3082b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo return exe_path.DirName(); 3092b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo} 3102b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo 31110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo} // namespace test_utils 31249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com} // namespace chromeos_update_engine 313