summaryrefslogtreecommitdiff
path: root/test/buildtool/execution_api/common/api_test.hpp
diff options
context:
space:
mode:
authorOliver Reiche <oliver.reiche@huawei.com>2025-05-21 14:44:37 +0200
committerPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2025-06-04 14:34:44 +0200
commit0c4ac5ce707be113fd01ec8c1c4ce3120b8f202f (patch)
tree3796a17a7aeaa3cdc4a4fb59cb0e00a5e1af2ad6 /test/buildtool/execution_api/common/api_test.hpp
parentab7adbb24384387a5c46a6340ecdedc4c1481079 (diff)
downloadjustbuild-0c4ac5ce707be113fd01ec8c1c4ce3120b8f202f.tar.gz
Tests: Verify symlink handling in APIs
... which should not do any symlink checks in compatible mode.
Diffstat (limited to 'test/buildtool/execution_api/common/api_test.hpp')
-rw-r--r--test/buildtool/execution_api/common/api_test.hpp140
1 files changed, 117 insertions, 23 deletions
diff --git a/test/buildtool/execution_api/common/api_test.hpp b/test/buildtool/execution_api/common/api_test.hpp
index 10f4e5a8..6ff56308 100644
--- a/test/buildtool/execution_api/common/api_test.hpp
+++ b/test/buildtool/execution_api/common/api_test.hpp
@@ -36,6 +36,7 @@
#include "src/buildtool/common/artifact_description.hpp"
#include "src/buildtool/common/artifact_digest.hpp"
#include "src/buildtool/common/artifact_digest_factory.hpp"
+#include "src/buildtool/common/protocol_traits.hpp"
#include "src/buildtool/crypto/hash_function.hpp"
#include "src/buildtool/execution_api/common/execution_action.hpp"
#include "src/buildtool/execution_api/common/execution_api.hpp"
@@ -732,31 +733,124 @@ TestRetrieveFileAndSymlinkWithSameContentToPath(ApiFactory const& api_factory,
ExecProps const& props) {
auto api = api_factory();
- auto action = api->CreateAction(
- *api->UploadTree({}),
- {"/bin/sh", "-c", "set -e; ln -s none foo; rm -rf bar; ln -s none bar"},
- "",
- {"foo"},
- {"bar"},
- {},
- props);
+ SECTION("dangling") {
+ auto action = api->CreateAction(
+ *api->UploadTree({}),
+ {"/bin/sh",
+ "-c",
+ "set -e; "
+ "ln -s none foo; "
+ "rm -rf bar; ln -s none bar; "
+ "mkdir -p baz; ln -s none baz/foo; ln -s none baz/bar"},
+ "",
+ {"foo"},
+ {"bar", "baz"},
+ {},
+ props);
- // run execution
- auto const response = action->Execute();
- REQUIRE(response);
+ // 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(IsSymlinkObject(artifacts.value()->at("foo").type));
- REQUIRE(artifacts.value()->contains("bar"));
- CHECK(IsSymlinkObject(artifacts.value()->at("bar").type));
-
- // check if bar was correctly detected as directory symlink
- auto dir_symlinks = response->DirectorySymlinks();
- REQUIRE(dir_symlinks);
- CHECK((*dir_symlinks)->contains("bar"));
+ // verify result
+ auto const artifacts = response->Artifacts();
+ REQUIRE(artifacts.has_value());
+ REQUIRE(artifacts.value()->contains("foo"));
+ CHECK(IsSymlinkObject(artifacts.value()->at("foo").type));
+ REQUIRE(artifacts.value()->contains("bar"));
+ CHECK(IsSymlinkObject(artifacts.value()->at("bar").type));
+ REQUIRE(artifacts.value()->contains("baz"));
+ CHECK(IsTreeObject(artifacts.value()->at("baz").type));
+
+ // check if bar was correctly detected as directory symlink
+ auto dir_symlinks = response->DirectorySymlinks();
+ REQUIRE(dir_symlinks);
+ CHECK((*dir_symlinks)->contains("bar"));
+
+ SECTION("consuming dangling symlinks") {
+ auto dangling_symlinks_tree = artifacts.value()->at("baz");
+ auto consume_action =
+ api->CreateAction(dangling_symlinks_tree.digest,
+ {"/bin/sh",
+ "-c",
+ "set -e; "
+ "[ \"$(readlink foo)\" = \"none\" ]; "
+ "[ \"$(readlink bar)\" = \"none\" ]; "
+ "touch success"},
+ "",
+ {"success"},
+ {},
+ {},
+ props);
+
+ auto const consume_response = consume_action->Execute();
+ REQUIRE(consume_response);
+ CHECK(consume_response->ExitCode() == 0);
+ }
+ }
+
+ SECTION("upwards") {
+ auto action = api->CreateAction(
+ *api->UploadTree({}),
+ {"/bin/sh",
+ "-c",
+ "set -e; "
+ "ln -s ../foo foo; "
+ "rm -rf bar; ln -s /bar bar; "
+ "mkdir -p baz; ln -s ../foo baz/foo; ln -s /bar baz/bar"},
+ "",
+ {"foo"},
+ {"bar", "baz"},
+ {},
+ props);
+
+ // run execution
+ auto const response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ auto const artifacts = response->Artifacts();
+ REQUIRE(artifacts.has_value());
+
+ if (ProtocolTraits::IsNative(api->GetHashType())) {
+ // in native, no symlink is collected, as none of them is valid
+ CHECK(artifacts.value()->empty());
+ return;
+ }
+
+ REQUIRE(artifacts.value()->contains("foo"));
+ CHECK(IsSymlinkObject(artifacts.value()->at("foo").type));
+ REQUIRE(artifacts.value()->contains("bar"));
+ CHECK(IsSymlinkObject(artifacts.value()->at("bar").type));
+ REQUIRE(artifacts.value()->contains("baz"));
+ CHECK(IsTreeObject(artifacts.value()->at("baz").type));
+
+ // check if bar was correctly detected as directory symlink
+ auto dir_symlinks = response->DirectorySymlinks();
+ REQUIRE(dir_symlinks);
+ CHECK((*dir_symlinks)->contains("bar"));
+
+ SECTION("consuming upwards symlinks") {
+ auto upwards_symlinks_tree = artifacts.value()->at("baz");
+ auto consume_action =
+ api->CreateAction(upwards_symlinks_tree.digest,
+ {"/bin/sh",
+ "-c",
+ "set -e; "
+ "[ \"$(readlink foo)\" = \"../foo\" ]; "
+ "[ \"$(readlink bar)\" = \"/bar\" ]; "
+ "touch success"},
+ "",
+ {"success"},
+ {},
+ {},
+ props);
+
+ auto const consume_response = consume_action->Execute();
+ REQUIRE(consume_response);
+ CHECK(consume_response->ExitCode() == 0);
+ }
+ }
}
#endif // INCLUDED_SRC_TEST_BUILDTOOL_EXECUTION_API_COMMON_API_TEST_HPP