test_utils.cc revision 2b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5
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> 8c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include <errno.h> 949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <stdio.h> 1049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <stdlib.h> 11161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymo#include <sys/stat.h> 12161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymo#include <sys/types.h> 1349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <unistd.h> 1409e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 15c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include <set> 1649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <string> 1749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <vector> 1809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 192b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo#include <base/files/file_util.h> 20161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymo#include <base/logging.h> 2175039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/strings/stringprintf.h> 222b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo#include <base/strings/string_util.h> 23161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymo 2449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "update_engine/file_writer.h" 25161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymo#include "update_engine/payload_generator/filesystem_iterator.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) && 13219a45f0eda0917b7788b925b501e774208474fdeGilad Arnold 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 235c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comvoid VerifyAllPaths(const string& parent, set<string> expected_paths) { 236c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com FilesystemIterator iter(parent, set<string>()); 237c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com ino_t test_ino = 0; 238c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com ino_t testlink_ino = 0; 239c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com while (!iter.IsEnd()) { 240c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com string path = iter.GetFullPath(); 241c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_TRUE(expected_paths.find(path) != expected_paths.end()) << path; 242c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_EQ(1, expected_paths.erase(path)); 24310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (EndsWith(path, "/hi", true) || 24410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo EndsWith(path, "/hello", true) || 24510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo EndsWith(path, "/test", true) || 24610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo EndsWith(path, "/testlink", true)) { 247c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_TRUE(S_ISREG(iter.GetStat().st_mode)); 24810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (EndsWith(path, "/test", true)) 249c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com test_ino = iter.GetStat().st_ino; 25010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo else if (EndsWith(path, "/testlink", true)) 251c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com testlink_ino = iter.GetStat().st_ino; 25210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } else if (EndsWith(path, "/some_dir", true) || 25310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo EndsWith(path, "/empty_dir", true) || 25410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo EndsWith(path, "/mnt", true) || 25510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo EndsWith(path, "/lost+found", true) || 256c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com parent == path) { 257c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_TRUE(S_ISDIR(iter.GetStat().st_mode)); 25810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } else if (EndsWith(path, "/fifo", true)) { 259c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_TRUE(S_ISFIFO(iter.GetStat().st_mode)); 26010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } else if (EndsWith(path, "/cdev", true)) { 261c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_TRUE(S_ISCHR(iter.GetStat().st_mode)); 26210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } else if (EndsWith(path, "/sym", true)) { 263c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_TRUE(S_ISLNK(iter.GetStat().st_mode)); 264c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com } else { 265c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com LOG(INFO) << "got non hardcoded path: " << path; 266c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com } 267c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com iter.Increment(); 268c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com } 269c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_EQ(testlink_ino, test_ino); 270c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_NE(0, test_ino); 271c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_FALSE(iter.IsErr()); 272c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_TRUE(expected_paths.empty()); 273c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com if (!expected_paths.empty()) { 274020600db42428e7e96bb0d2e05da225e68650955Alex Deymo for (const string& path : expected_paths) { 275020600db42428e7e96bb0d2e05da225e68650955Alex Deymo LOG(INFO) << "extra path: " << path; 276c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com } 277c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com } 278c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com} 279c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 28058e8b1f8b32b355d879008572648fd621873711dDon GarrettScopedLoopMounter::ScopedLoopMounter(const string& file_path, 28158e8b1f8b32b355d879008572648fd621873711dDon Garrett string* mnt_path, 282d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko unsigned long flags) { // NOLINT - long 283a6742b35938b6f58e24e3f1c550fe92d4d33eb74Gilad Arnold EXPECT_TRUE(utils::MakeTempDirectory("mnt.XXXXXX", mnt_path)); 2845c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le dir_remover_.reset(new ScopedDirRemover(*mnt_path)); 2855c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 28658e8b1f8b32b355d879008572648fd621873711dDon Garrett string loop_dev; 28758e8b1f8b32b355d879008572648fd621873711dDon Garrett loop_binder_.reset(new ScopedLoopbackDeviceBinder(file_path, &loop_dev)); 2885c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 2895c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le EXPECT_TRUE(utils::MountFilesystem(loop_dev, *mnt_path, flags)); 2905c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le unmounter_.reset(new ScopedFilesystemUnmounter(*mnt_path)); 2915c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le} 2925c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 29310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymonamespace { 29410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymoclass ScopedDirCloser { 29510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo public: 29610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo explicit ScopedDirCloser(DIR** dir) : dir_(dir) {} 29710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo ~ScopedDirCloser() { 29810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (dir_ && *dir_) { 29910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo int r = closedir(*dir_); 30010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_ERRNO(r == 0); 30110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo *dir_ = nullptr; 30210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo dir_ = nullptr; 30310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 30410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 30510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo private: 30610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo DIR** dir_; 30710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo}; 30810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo} // namespace 30910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 31010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymobool RecursiveUnlinkDir(const string& path) { 31110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo struct stat stbuf; 31210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo int r = lstat(path.c_str(), &stbuf); 31310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_FALSE_ERRNO((r == 0) || (errno == ENOENT)); 31410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if ((r < 0) && (errno == ENOENT)) 31510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // path request is missing. that's fine. 31610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo return true; 31710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (!S_ISDIR(stbuf.st_mode)) { 31810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_FALSE_ERRNO((unlink(path.c_str()) == 0) || 31910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo (errno == ENOENT)); 32010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // success or path disappeared before we could unlink. 32110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo return true; 32210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 32310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo { 32410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // We have a dir, unlink all children, then delete dir 32510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo DIR *dir = opendir(path.c_str()); 32610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_FALSE_ERRNO(dir); 32710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo ScopedDirCloser dir_closer(&dir); 32810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo struct dirent dir_entry; 32910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo struct dirent *dir_entry_p; 33010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo int err = 0; 33110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo while ((err = readdir_r(dir, &dir_entry, &dir_entry_p)) == 0) { 33210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (dir_entry_p == nullptr) { 33310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // end of stream reached 33410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo break; 33510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 33610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // Skip . and .. 33710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (!strcmp(dir_entry_p->d_name, ".") || 33810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo !strcmp(dir_entry_p->d_name, "..")) 33910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo continue; 34010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_FALSE(RecursiveUnlinkDir(path + "/" + 34110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo dir_entry_p->d_name)); 34210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 34310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_FALSE(err == 0); 34410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 34510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // unlink dir 34610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo TEST_AND_RETURN_FALSE_ERRNO((rmdir(path.c_str()) == 0) || (errno == ENOENT)); 34710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo return true; 34810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo} 34910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 35053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymostatic gboolean RunGMainLoopOnTimeout(gpointer user_data) { 35153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo bool* timeout = static_cast<bool*>(user_data); 35253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo *timeout = true; 35353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo return FALSE; // Remove timeout source 35453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo} 35553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 35653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymovoid RunGMainLoopUntil(int timeout_msec, base::Callback<bool()> terminate) { 35788b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko GMainLoop* loop = g_main_loop_new(nullptr, FALSE); 35853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo GMainContext* context = g_main_context_default(); 35953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 36053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo bool timeout = false; 36153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo guint source_id = g_timeout_add( 36253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo timeout_msec, RunGMainLoopOnTimeout, &timeout); 36353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 36453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo while (!timeout && (terminate.is_null() || !terminate.Run())) 36553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo g_main_context_iteration(context, TRUE); 36653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 36753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo g_source_remove(source_id); 36853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo g_main_loop_unref(loop); 36953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo} 37053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 3717b948f060281eb1f9ab198bce67da5aadf03df60Alex Deymoint RunGMainLoopMaxIterations(int iterations) { 3727b948f060281eb1f9ab198bce67da5aadf03df60Alex Deymo int result; 3737b948f060281eb1f9ab198bce67da5aadf03df60Alex Deymo GMainContext* context = g_main_context_default(); 3747b948f060281eb1f9ab198bce67da5aadf03df60Alex Deymo for (result = 0; 3757b948f060281eb1f9ab198bce67da5aadf03df60Alex Deymo result < iterations && g_main_context_iteration(context, FALSE); 3767b948f060281eb1f9ab198bce67da5aadf03df60Alex Deymo result++) {} 3777b948f060281eb1f9ab198bce67da5aadf03df60Alex Deymo return result; 3787b948f060281eb1f9ab198bce67da5aadf03df60Alex Deymo} 3797b948f060281eb1f9ab198bce67da5aadf03df60Alex Deymo 380beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad ArnoldGValue* GValueNewString(const char* str) { 3815665d0ced6812771559ca7bf938fa48f2b93ae48Alex Deymo GValue* gval = g_new0(GValue, 1); 382beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold g_value_init(gval, G_TYPE_STRING); 383beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold g_value_set_string(gval, str); 384beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold return gval; 385beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold} 386beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold 387beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnoldvoid GValueFree(gpointer arg) { 388beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold auto gval = reinterpret_cast<GValue*>(arg); 389beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold g_value_unset(gval); 3905665d0ced6812771559ca7bf938fa48f2b93ae48Alex Deymo g_free(gval); 391beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold} 392beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold 3932b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymobase::FilePath GetBuildArtifactsPath() { 3942b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo base::FilePath exe_path; 3952b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo base::ReadSymbolicLink(base::FilePath("/proc/self/exe"), &exe_path); 3962b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo return exe_path.DirName(); 3972b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo} 3982b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo 39910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo} // namespace test_utils 40049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com} // namespace chromeos_update_engine 401