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