summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Reiche <oliver.reiche@huawei.com>2025-06-23 15:08:01 +0200
committerOliver Reiche <oliver.reiche@huawei.com>2025-06-24 14:56:58 +0200
commitb41c60fd8179fec987f158347111f650924aad47 (patch)
tree61f4addc0ff45fb5d65abe0807015417aae2b579
parentbbcc5977f49646941ac35060bb74a27eda5fbd76 (diff)
downloadjustbuild-b41c60fd8179fec987f158347111f650924aad47.tar.gz
Test: Add test for API output path modes
-rw-r--r--test/buildtool/execution_api/bazel/bazel_api.test.cpp17
-rw-r--r--test/buildtool/execution_api/common/api_test.hpp104
-rw-r--r--test/buildtool/execution_api/local/local_api.test.cpp13
3 files changed, 134 insertions, 0 deletions
diff --git a/test/buildtool/execution_api/bazel/bazel_api.test.cpp b/test/buildtool/execution_api/bazel/bazel_api.test.cpp
index bc147ef5..bfe32f83 100644
--- a/test/buildtool/execution_api/bazel/bazel_api.test.cpp
+++ b/test/buildtool/execution_api/bazel/bazel_api.test.cpp
@@ -225,3 +225,20 @@ TEST_CASE("BazelAPI: Collect file and directory symlinks", "[execution_api]") {
storage_config.Get().CreateTypedTmpDir("test_space")};
TestSymlinkCollection(api_factory, remote_config->platform_properties);
}
+
+TEST_CASE("BazelAPI: Run in different output path modes", "[execution_api]") {
+ auto storage_config = TestStorageConfig::Create();
+ auto remote_config = TestRemoteConfig::ReadFromEnvironment();
+
+ REQUIRE(remote_config);
+ REQUIRE(remote_config->remote_address);
+ auto auth = TestAuthConfig::ReadFromEnvironment();
+ REQUIRE(auth);
+
+ FactoryApi api_factory{
+ &*remote_config->remote_address,
+ &*auth,
+ storage_config.Get().hash_function,
+ storage_config.Get().CreateTypedTmpDir("test_space")};
+ TestOutputPathModes(api_factory, remote_config->platform_properties);
+}
diff --git a/test/buildtool/execution_api/common/api_test.hpp b/test/buildtool/execution_api/common/api_test.hpp
index 34fbb29a..7cdfe20e 100644
--- a/test/buildtool/execution_api/common/api_test.hpp
+++ b/test/buildtool/execution_api/common/api_test.hpp
@@ -29,6 +29,8 @@
#include <vector>
#include "catch2/catch_test_macros.hpp"
+#include "catch2/catch_tostring.hpp"
+#include "catch2/generators/catch_generators_all.hpp"
#include "fmt/core.h"
#include "gsl/gsl"
#include "src/buildtool/common/artifact.hpp"
@@ -42,6 +44,7 @@
#include "src/buildtool/execution_api/common/execution_api.hpp"
#include "src/buildtool/execution_api/common/execution_response.hpp"
#include "src/buildtool/execution_api/local/config.hpp"
+#include "src/buildtool/execution_api/local/local_api.hpp"
#include "src/buildtool/execution_api/local/local_response.hpp"
#include "src/buildtool/execution_engine/dag/dag.hpp"
#include "src/buildtool/file_system/file_system_manager.hpp"
@@ -860,4 +863,105 @@ TestRetrieveFileAndSymlinkWithSameContentToPath(ApiFactory const& api_factory,
}
}
+[[nodiscard]] static inline auto TestOutputPathModes(
+ ApiFactory const& api_factory,
+ ExecProps const& props) {
+ auto api = api_factory();
+
+ auto force_legacy = GENERATE(false, true);
+
+ DYNAMIC_SECTION("Separated output paths (legacy=" << force_legacy << ")") {
+ auto action =
+ api->CreateAction(*api->UploadTree({}),
+ {"/bin/sh",
+ "-c",
+ "set -e; touch foo; ln -s none fox; "
+ "mkdir -p bar; rm -rf bat; ln -s none bat"},
+ "",
+ {"foo", "fox"},
+ {"bar", "bat"},
+ {},
+ props,
+ force_legacy);
+ REQUIRE(action);
+
+ // run execution
+ auto const response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ auto const artifacts = response->Artifacts();
+ REQUIRE(artifacts.has_value());
+ REQUIRE(artifacts.value()->contains("foo"));
+ CHECK(IsFileObject(artifacts.value()->at("foo").type));
+ REQUIRE(artifacts.value()->contains("fox"));
+ CHECK(IsSymlinkObject(artifacts.value()->at("fox").type));
+ REQUIRE(artifacts.value()->contains("bar"));
+ CHECK(IsTreeObject(artifacts.value()->at("bar").type));
+ REQUIRE(artifacts.value()->contains("bat"));
+ CHECK(IsSymlinkObject(artifacts.value()->at("bat").type));
+
+ // verify DirectorySymlinks
+ auto* local_response = dynamic_cast<LocalResponse*>(response.get());
+ if (local_response != nullptr) {
+ auto dir_symlinks = local_response->DirectorySymlinks();
+ if (force_legacy or ProtocolTraits::IsNative(api->GetHashType())) {
+ // in legacy mode (<RBEv2.1), dir symlinks must be available,
+ // which is implicitly enabled for the native protocol as well.
+ REQUIRE(dir_symlinks.has_value());
+ CHECK(*dir_symlinks != nullptr);
+ }
+ if (dir_symlinks and *dir_symlinks != nullptr) {
+ // even in non-legacy mode, the API is free to additionally
+ // report output directory symlinks, and if it does so, it must
+ // correctly report all output directory symlinks.
+ CHECK((*dir_symlinks)->contains("bat"));
+ }
+ }
+ }
+
+ SECTION("Combined output paths") {
+ auto const* local_api = dynamic_cast<LocalApi const*>(api.get());
+ if (local_api == nullptr) {
+ // skip: combined output paths are only available for local api
+ return;
+ }
+
+ auto action = local_api->CreateAction(
+ *local_api->UploadTree({}),
+ {"/bin/sh",
+ "-c",
+ "set -e; touch foo; ln -s none fox; "
+ "mkdir -p bar; rm -rf bat; ln -s none bat"},
+ "",
+ {"foo", "fox", "bar", "bat"},
+ {},
+ props);
+ REQUIRE(action);
+
+ // run execution
+ auto const response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ auto const artifacts = response->Artifacts();
+ REQUIRE(artifacts.has_value());
+ REQUIRE(artifacts.value()->contains("foo"));
+ CHECK(IsFileObject(artifacts.value()->at("foo").type));
+ REQUIRE(artifacts.value()->contains("fox"));
+ CHECK(IsSymlinkObject(artifacts.value()->at("fox").type));
+ REQUIRE(artifacts.value()->contains("bar"));
+ CHECK(IsTreeObject(artifacts.value()->at("bar").type));
+ REQUIRE(artifacts.value()->contains("bat"));
+ CHECK(IsSymlinkObject(artifacts.value()->at("bat").type));
+
+ // with combined output paths, we cannot report output dir symlinks
+ auto* local_response = dynamic_cast<LocalResponse*>(response.get());
+ if (local_response != nullptr) {
+ auto dir_symlinks = local_response->DirectorySymlinks();
+ REQUIRE_FALSE(dir_symlinks);
+ }
+ }
+}
+
#endif // INCLUDED_SRC_TEST_BUILDTOOL_EXECUTION_API_COMMON_API_TEST_HPP
diff --git a/test/buildtool/execution_api/local/local_api.test.cpp b/test/buildtool/execution_api/local/local_api.test.cpp
index 94b9bf75..5904eb4f 100644
--- a/test/buildtool/execution_api/local/local_api.test.cpp
+++ b/test/buildtool/execution_api/local/local_api.test.cpp
@@ -159,3 +159,16 @@ TEST_CASE("LocalAPI: Collect file and directory symlinks", "[execution_api]") {
TestSymlinkCollection(api_factory, {});
}
+
+TEST_CASE("LocalAPI: Run in different output path modes", "[execution_api]") {
+ auto const storage_config = TestStorageConfig::Create();
+ auto const storage = Storage::Create(&storage_config.Get());
+ auto const local_exec_config = CreateLocalExecConfig();
+ // pack the local context instances to be passed to LocalApi
+ LocalContext const local_context{.exec_config = &local_exec_config,
+ .storage_config = &storage_config.Get(),
+ .storage = &storage};
+ FactoryApi api_factory(&local_context);
+
+ TestOutputPathModes(api_factory, {});
+}