sapling/eden/fs/testharness/HgRepo.h
Chad Austin a8b380f589 skip edenfs tests when tsan is enabled
Summary:
Mercurial is incompatible with TSAN at the moment, due to Rust/C++
compilation issues, Python multiprocess, and Tokio false positives. So
disable our HG tests when running under TSAN.

Reviewed By: fanzeyi

Differential Revision: D25109413

fbshipit-source-id: 86e51ebd287e10f92d6e3b8e7bf191e7946c709a
2020-12-01 10:18:53 -08:00

166 lines
4.4 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#pragma once
#include <string>
#include <vector>
#include "eden/fs/utils/PathFuncs.h"
#include "eden/fs/utils/SpawnedProcess.h"
namespace facebook {
namespace eden {
class Hash;
/**
* A helper class for working with a mercurial repository in unit tests.
*/
class HgRepo {
public:
explicit HgRepo(AbsolutePathPiece path);
const AbsolutePath& path() const {
return path_;
}
/**
* Run an hg command.
*
* The parameters are the arguments to pass to hg. This should not
* include the "hg" program name itself (argument 0).
*
* e.g., hg("add") will run "hg add" in the repository.
* Arguments can be strings, RelativePaths, or AbsolutePaths.
*
* Returns the data that the command printed on stdout.
* Throws if the command exited with a non-zero status.
*/
template <typename... Args>
std::string hg(const Args&... args) {
std::vector<std::string> argsVector;
buildHgArgs(argsVector, args...);
return hg(std::move(argsVector));
}
/**
* Run an hg command.
*
* @param args The arguments to pass to "hg" (not including argument 0, "hg"
* itself).
*
* Returns the data that the command printed on stdout.
* Throws if the command exited with a non-zero status.
*/
std::string hg(std::vector<std::string> args);
/**
* Start an hg command and return the SpawnedProcess object without waiting
* for it to complete.
*/
template <typename... Args>
SpawnedProcess invokeHg(const Args&... args) {
std::vector<std::string> argsVector;
buildHgArgs(argsVector, args...);
return invokeHg(std::move(argsVector));
}
SpawnedProcess invokeHg(std::vector<std::string> args);
SpawnedProcess invokeHg(
std::vector<std::string> args,
SpawnedProcess::Options&& options);
/**
* Call "hg init" to create the repository.
*/
void hgInit(std::vector<std::string> extraArgs = {});
/**
* Configure the repository's hgrc to enable treemanifest.
*/
void enableTreeManifest(AbsolutePathPiece cacheDirectory);
/**
* Call "hg clone" to create the repository.
*/
void cloneFrom(
folly::StringPiece serverRepoUrl,
std::vector<std::string> extraArgs = {});
/**
* Append data to the repository's hgrc file
*/
void appendToHgrc(folly::StringPiece data);
void appendToHgrc(const std::vector<std::string>& lines);
Hash commit(folly::StringPiece message);
Hash getManifestForCommit(Hash commit);
void mkdir(RelativePathPiece path, mode_t permissions = 0755);
void mkdir(folly::StringPiece path, mode_t permissions = 0755) {
mkdir(RelativePathPiece{path}, permissions);
}
void writeFile(
RelativePathPiece path,
folly::StringPiece contents,
mode_t permissions = 0644);
void writeFile(
folly::StringPiece path,
folly::StringPiece contents,
mode_t permissions = 0644) {
writeFile(RelativePathPiece{path}, contents, permissions);
}
void symlink(folly::StringPiece contents, RelativePathPiece path);
private:
void buildHgArgs(std::vector<std::string>& /* cmd */) {}
template <typename... Args>
void buildHgArgs(
std::vector<std::string>& cmd,
folly::StringPiece str,
const Args&... args) {
cmd.push_back(str.str());
buildHgArgs(cmd, args...);
}
template <typename... Args>
void buildHgArgs(
std::vector<std::string>& cmd,
RelativePathPiece path,
const Args&... args) {
cmd.push_back(path.value().str());
buildHgArgs(cmd, args...);
}
template <typename... Args>
void buildHgArgs(
std::vector<std::string>& cmd,
AbsolutePathPiece path,
const Args&... args) {
cmd.push_back(path.value().str());
buildHgArgs(cmd, args...);
}
AbsolutePath hgCmd_;
SpawnedProcess::Environment hgEnv_;
AbsolutePath path_;
};
/**
* Skips the executing test unless it's okay to invoke hg in this test.
*
* Ideally, this function wouldn't exist, but traditionally hg has not run
* correctly in every build environment. Currently, hg is incompatible with TSAN
* due to known tokio false positives
* (https://github.com/tokio-rs/tokio/issues/2087) and undefined symbol:
* __tsan_func_entry in libomnibus.so.
*/
bool testEnvironmentSupportsHg();
} // namespace eden
} // namespace facebook