blob: 376779a387a017dd5b2f6425455b2d0f15672600 [file] [edit]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Tests the plugin-backed \c ObjectStore and \c ActionCache against the mock
/// plugin implementation in \c llvm/tools/libCASPluginTest.
///
//===----------------------------------------------------------------------===//
#include "CASTestConfig.h"
#include "llvm/CAS/ActionCache.h"
#include "llvm/CAS/ObjectStore.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Path.h"
#include "llvm/Testing/Support/Error.h"
#include "llvm/Testing/Support/SupportHelpers.h"
#include "gtest/gtest.h"
using namespace llvm;
using namespace llvm::cas;
using namespace llvm::unittest::cas;
// HWASan does not tag the globals of a dlopen'ed library with glibc, so the
// plugin faults as soon as it touches one of its own globals.
// FIXME: Re-enable once https://github.com/llvm/llvm-project/issues/57206 is
// fixed.
#if !LLVM_HWADDRESS_SANITIZER_BUILD
extern const char *TestMainArgv0;
static std::string TestStringArg1("castest-string-arg1");
/// \returns the path of the libCASPluginTest dynamic library, which implements
/// the CAS plugin API for testing purposes.
static std::string getCASPluginPath() {
std::string Executable =
sys::fs::getMainExecutable(TestMainArgv0, &TestStringArg1);
llvm::SmallString<256> PathBuf(sys::path::parent_path(Executable));
#if !defined(_WIN32) || defined(__MINGW32__)
sys::path::append(PathBuf, "libCASPluginTest" LLVM_PLUGIN_EXT);
#else
sys::path::append(PathBuf, "CASPluginTest" LLVM_PLUGIN_EXT);
#endif
return std::string(PathBuf);
}
static CASTestingEnv createPlugin(int I) {
unittest::TempDir Temp("plugin-cas", /*Unique=*/true);
std::optional<
std::pair<std::shared_ptr<ObjectStore>, std::shared_ptr<ActionCache>>>
DBs;
EXPECT_THAT_ERROR(createPluginCASDatabases(getCASPluginPath(), Temp.path(),
/*PluginArgs=*/{})
.moveInto(DBs),
Succeeded());
if (!DBs)
return CASTestingEnv{nullptr, nullptr, std::move(Temp)};
return CASTestingEnv{std::move(DBs->first), std::move(DBs->second),
std::move(Temp)};
}
INSTANTIATE_TEST_SUITE_P(PluginCAS, CASTest, ::testing::Values(createPlugin));
TEST(PluginCASTest, isMaterialized) {
unittest::TempDir Temp("plugin-cas", /*Unique=*/true);
std::string UpDir(Temp.path("up"));
std::string DownDir(Temp.path("down"));
std::pair<std::string, std::string> PluginOpts[] = {
{"upstream-path", std::string(UpDir)}};
{
std::optional<
std::pair<std::shared_ptr<ObjectStore>, std::shared_ptr<ActionCache>>>
DBs;
ASSERT_THAT_ERROR(
createPluginCASDatabases(getCASPluginPath(), DownDir, PluginOpts)
.moveInto(DBs),
Succeeded());
std::shared_ptr<ObjectStore> CAS;
std::shared_ptr<ActionCache> AC;
std::tie(CAS, AC) = std::move(*DBs);
std::optional<CASID> ID1, ID2;
ASSERT_THAT_ERROR(CAS->createProxy({}, "1").moveInto(ID1), Succeeded());
ASSERT_THAT_ERROR(CAS->createProxy({}, "2").moveInto(ID2), Succeeded());
std::optional<ObjectRef> ID2Ref = CAS->getReference(*ID2);
ASSERT_TRUE(ID2Ref);
bool IsMaterialized = false;
ASSERT_THAT_ERROR(CAS->isMaterialized(*ID2Ref).moveInto(IsMaterialized),
Succeeded());
EXPECT_TRUE(IsMaterialized);
ASSERT_THAT_ERROR(AC->put(*ID1, *ID2, /*CanBeDistributed=*/true),
Succeeded());
}
// Clear "local" cache.
sys::fs::remove_directories(DownDir);
{
std::optional<
std::pair<std::shared_ptr<ObjectStore>, std::shared_ptr<ActionCache>>>
DBs;
ASSERT_THAT_ERROR(
createPluginCASDatabases(getCASPluginPath(), DownDir, PluginOpts)
.moveInto(DBs),
Succeeded());
std::shared_ptr<ObjectStore> CAS;
std::shared_ptr<ActionCache> AC;
std::tie(CAS, AC) = std::move(*DBs);
std::optional<CASID> ID1, ID2;
ASSERT_THAT_ERROR(CAS->createProxy({}, "1").moveInto(ID1), Succeeded());
ASSERT_THAT_ERROR(AC->get(*ID1, /*CanBeDistributed=*/true).moveInto(ID2),
Succeeded());
std::optional<ObjectRef> ID2Ref = CAS->getReference(*ID2);
ASSERT_TRUE(ID2Ref);
bool IsMaterialized = false;
ASSERT_THAT_ERROR(CAS->isMaterialized(*ID2Ref).moveInto(IsMaterialized),
Succeeded());
EXPECT_FALSE(IsMaterialized);
std::optional<ObjectProxy> Obj;
ASSERT_THAT_ERROR(CAS->getProxy(*ID2Ref).moveInto(Obj), Succeeded());
ASSERT_THAT_ERROR(CAS->isMaterialized(*ID2Ref).moveInto(IsMaterialized),
Succeeded());
EXPECT_TRUE(IsMaterialized);
}
}
#endif /* !LLVM_HWADDRESS_SANITIZER_BUILD */