summaryrefslogtreecommitdiff
path: root/test/buildtool
diff options
context:
space:
mode:
authorKlaus Aehlig <klaus.aehlig@huawei.com>2025-03-26 12:08:54 +0100
committerKlaus Aehlig <klaus.aehlig@huawei.com>2025-04-07 16:09:43 +0200
commit4cd12f7ba531c255aa3945bd5bc1a6a1ab0bc7bc (patch)
tree995f8faf1cf10056303386dd14b14143cd4a015e /test/buildtool
parenteb101e14097d02c74a1e34927a08bba4b7d739c5 (diff)
downloadjustbuild-4cd12f7ba531c255aa3945bd5bc1a6a1ab0bc7bc.tar.gz
Defined rules: add TREE_OVERLAY and DISJOINT_TREE_OVERLAY function
Diffstat (limited to 'test/buildtool')
-rw-r--r--test/buildtool/build_engine/target_map/TARGETS37
-rw-r--r--test/buildtool/build_engine/target_map/data_rules/tree_overlay/RULES55
-rw-r--r--test/buildtool/build_engine/target_map/data_src/tree_overlay/x0
-rw-r--r--test/buildtool/build_engine/target_map/data_targets/tree_overlay/TARGETS6
-rw-r--r--test/buildtool/build_engine/target_map/target_map.test.cpp187
5 files changed, 252 insertions, 33 deletions
diff --git a/test/buildtool/build_engine/target_map/TARGETS b/test/buildtool/build_engine/target_map/TARGETS
index e477393e..67d35ade 100644
--- a/test/buildtool/build_engine/target_map/TARGETS
+++ b/test/buildtool/build_engine/target_map/TARGETS
@@ -70,6 +70,7 @@
, ["@", "src", "src/buildtool/common", "config"]
, ["@", "src", "src/buildtool/common", "statistics"]
, ["@", "src", "src/buildtool/common", "tree"]
+ , ["@", "src", "src/buildtool/common", "tree_overlay"]
, ["@", "src", "src/buildtool/common/remote", "remote_common"]
, ["@", "src", "src/buildtool/common/remote", "retry_config"]
, ["@", "src", "src/buildtool/crypto", "hash_function"]
@@ -117,39 +118,9 @@
, "test_data":
{ "type": ["@", "rules", "data", "staged"]
, "srcs":
- [ "data_src/a/b/targets_here/c/d/foo"
- , "data_src/file_reference/hello.txt"
- , "data_src/foo"
- , "data_src/simple_rules/implicit_script.sh"
- , "data_src/simple_targets/bar.txt"
- , "data_src/simple_targets/baz.txt"
- , "data_src/simple_targets/foo.txt"
- , "data_src/tree/foo.txt"
- , "data_src/tree/tree/foo.txt"
- , "data_src/x/foo"
- , "data_src/x/x/foo"
- , "data_src/x/x/x/foo"
- , "data_src/x/x/x/x/foo"
- , "data_src/x/x/x/x/x/foo"
- , "data_targets/TARGETS"
- , "data_targets/a/b/targets_here/TARGETS"
- , "data_targets/bad_targets/TARGETS"
- , "data_targets/config_targets/TARGETS"
- , "data_targets/file_reference/TARGETS"
- , "data_targets/result/TARGETS"
- , "data_targets/simple_rules/TARGETS"
- , "data_targets/simple_targets/TARGETS"
- , "data_targets/symlink_reference/TARGETS"
- , "data_targets/tree/TARGETS"
- , "data_targets/x/TARGETS"
- , "data_targets/x/x/TARGETS"
- , "data_targets/x/x/x/TARGETS"
- , "data_targets/x/x/x/x/TARGETS"
- , "data_targets/x/x/x/x/x/TARGETS"
- , "data_rules/result/RULES"
- , "data_rules/rule/RULES"
- , "data_rules/simple_rules/RULES"
- , "data_rules/tree/RULES"
+ [ ["TREE", null, "data_src"]
+ , ["TREE", null, "data_targets"]
+ , ["TREE", null, "data_rules"]
]
, "stage": ["test", "buildtool", "build_engine", "target_map"]
}
diff --git a/test/buildtool/build_engine/target_map/data_rules/tree_overlay/RULES b/test/buildtool/build_engine/target_map/data_rules/tree_overlay/RULES
new file mode 100644
index 00000000..eb809da4
--- /dev/null
+++ b/test/buildtool/build_engine/target_map/data_rules/tree_overlay/RULES
@@ -0,0 +1,55 @@
+{ "overlay":
+ { "target_fields": ["deps"]
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "deps"
+ , { "type": "foreach"
+ , "range": {"type": "FIELD", "name": "deps"}
+ , "body":
+ {"type": "DEP_ARTIFACTS", "dep": {"type": "var", "name": "_"}}
+ }
+ ]
+ , [ "overlay tree"
+ , {"type": "TREE_OVERLAY", "$1": {"type": "var", "name": "deps"}}
+ ]
+ ]
+ , "body":
+ { "type": "RESULT"
+ , "artifacts":
+ { "type": "singleton_map"
+ , "key": "it"
+ , "value": {"type": "var", "name": "overlay tree"}
+ }
+ }
+ }
+ }
+, "disjoint overlay":
+ { "target_fields": ["deps"]
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "deps"
+ , { "type": "foreach"
+ , "range": {"type": "FIELD", "name": "deps"}
+ , "body":
+ {"type": "DEP_ARTIFACTS", "dep": {"type": "var", "name": "_"}}
+ }
+ ]
+ , [ "overlay tree"
+ , { "type": "DISJOINT_TREE_OVERLAY"
+ , "$1": {"type": "var", "name": "deps"}
+ }
+ ]
+ ]
+ , "body":
+ { "type": "RESULT"
+ , "artifacts":
+ { "type": "singleton_map"
+ , "key": "it"
+ , "value": {"type": "var", "name": "overlay tree"}
+ }
+ }
+ }
+ }
+}
diff --git a/test/buildtool/build_engine/target_map/data_src/tree_overlay/x b/test/buildtool/build_engine/target_map/data_src/tree_overlay/x
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/buildtool/build_engine/target_map/data_src/tree_overlay/x
diff --git a/test/buildtool/build_engine/target_map/data_targets/tree_overlay/TARGETS b/test/buildtool/build_engine/target_map/data_targets/tree_overlay/TARGETS
new file mode 100644
index 00000000..088d47de
--- /dev/null
+++ b/test/buildtool/build_engine/target_map/data_targets/tree_overlay/TARGETS
@@ -0,0 +1,6 @@
+{ "empty": {"type": ["tree_overlay", "overlay"]}
+, "one stage": {"type": ["tree_overlay", "overlay"], "deps": ["x"]}
+, "disjoint empty": {"type": ["tree_overlay", "disjoint overlay"]}
+, "disjoint one stage":
+ {"type": ["tree_overlay", "disjoint overlay"], "deps": ["x"]}
+}
diff --git a/test/buildtool/build_engine/target_map/target_map.test.cpp b/test/buildtool/build_engine/target_map/target_map.test.cpp
index 87698b13..0b51355b 100644
--- a/test/buildtool/build_engine/target_map/target_map.test.cpp
+++ b/test/buildtool/build_engine/target_map/target_map.test.cpp
@@ -46,6 +46,7 @@
#include "src/buildtool/common/repository_config.hpp"
#include "src/buildtool/common/statistics.hpp"
#include "src/buildtool/common/tree.hpp"
+#include "src/buildtool/common/tree_overlay.hpp"
#include "src/buildtool/crypto/hash_function.hpp"
#include "src/buildtool/execution_api/common/api_bundle.hpp"
#include "src/buildtool/execution_api/local/config.hpp"
@@ -1500,6 +1501,192 @@ TEST_CASE("trees", "[target_map]") {
}
}
+TEST_CASE("tree_overlays", "[target_map]") {
+ auto const storage_config = TestStorageConfig::Create();
+ auto const storage = Storage::Create(&storage_config.Get());
+
+ auto repo_config = SetupConfig();
+ auto directory_entries =
+ BuildMaps::Base::CreateDirectoryEntriesMap(&repo_config);
+ auto source = BuildMaps::Base::CreateSourceTargetMap(
+ &directory_entries,
+ &repo_config,
+ storage_config.Get().hash_function.GetType());
+ auto targets_file_map =
+ BuildMaps::Base::CreateTargetsFileMap(&repo_config, 0);
+ auto rule_file_map = BuildMaps::Base::CreateRuleFileMap(&repo_config, 0);
+ static auto expressions_file_map =
+ BuildMaps::Base::CreateExpressionFileMap(&repo_config, 0);
+ auto expr_map = BuildMaps::Base::CreateExpressionMap(&expressions_file_map,
+ &repo_config);
+ auto rule_map =
+ BuildMaps::Base::CreateRuleMap(&rule_file_map, &expr_map, &repo_config);
+ BuildMaps::Target::ResultTargetMap result_map{0};
+ Statistics stats{};
+ Progress exports_progress{};
+
+ auto serve_config = TestServeConfig::ReadFromEnvironment();
+ REQUIRE(serve_config);
+
+ LocalExecutionConfig local_exec_config{};
+
+ // pack the local context instances to be passed to ApiBundle
+ LocalContext const local_context{.exec_config = &local_exec_config,
+ .storage_config = &storage_config.Get(),
+ .storage = &storage};
+
+ Auth auth{};
+ RetryConfig retry_config{};
+ RemoteExecutionConfig remote_exec_config{};
+
+ // pack the remote context instances to be passed to ApiBundle
+ RemoteContext const remote_context{.auth = &auth,
+ .retry_config = &retry_config,
+ .exec_config = &remote_exec_config};
+
+ auto const apis = ApiBundle::Create(&local_context,
+ &remote_context,
+ /*repo_config=*/nullptr);
+
+ auto serve =
+ ServeApi::Create(*serve_config, &local_context, &remote_context, &apis);
+
+ AnalyseContext ctx{.repo_config = &repo_config,
+ .storage = &storage,
+ .statistics = &stats,
+ .progress = &exports_progress,
+ .serve = serve ? &*serve : nullptr};
+
+ auto absent_target_variables_map =
+ BuildMaps::Target::CreateAbsentTargetVariablesMap(&ctx, 0);
+
+ auto absent_target_map = BuildMaps::Target::CreateAbsentTargetMap(
+ &ctx, &result_map, &absent_target_variables_map, 0);
+
+ auto target_map = BuildMaps::Target::CreateTargetMap(&ctx,
+ &source,
+ &targets_file_map,
+ &rule_map,
+ &directory_entries,
+ &absent_target_map,
+ &result_map);
+
+ AnalysedTargetPtr result;
+ bool error{false};
+ std::string error_msg;
+ auto empty_config = Configuration{Expression::FromJson(R"({})"_json)};
+
+ SECTION("empty") {
+ error = false;
+ error_msg = "NONE";
+ {
+ TaskSystem ts;
+ target_map.ConsumeAfterKeysReady(
+ &ts,
+ {BuildMaps::Target::ConfiguredTarget{
+ .target =
+ BuildMaps::Base::EntityName{
+ "", "tree_overlay", "empty"},
+ .config = empty_config}},
+ [&result](auto values) { result = *values[0]; },
+ [&error, &error_msg](std::string const& msg, bool /*unused*/) {
+ error = true;
+ error_msg = msg;
+ });
+ }
+ CHECK(not error);
+ CHECK(error_msg == "NONE");
+ CHECK(result->TreeOverlays().size() == 1);
+ CHECK(result->TreeOverlays()[0]->ToJson()["trees"] ==
+ nlohmann::json::array());
+ CHECK(result->TreeOverlays()[0]->ToJson()["disjoint"] == false);
+ }
+
+ SECTION("implicit tree") {
+ error = false;
+ error_msg = "NONE";
+ {
+ TaskSystem ts;
+ target_map.ConsumeAfterKeysReady(
+ &ts,
+ {BuildMaps::Target::ConfiguredTarget{
+ .target =
+ BuildMaps::Base::EntityName{
+ "", "tree_overlay", "one stage"},
+ .config = empty_config}},
+ [&result](auto values) { result = *values[0]; },
+ [&error, &error_msg](std::string const& msg, bool /*unused*/) {
+ error = true;
+ error_msg = msg;
+ });
+ }
+ CHECK(not error);
+ CHECK(error_msg == "NONE");
+ CHECK(result->Trees().size() == 1);
+ CHECK(result->Trees()[0]->ToJson()["x"]["type"] == "LOCAL");
+ CHECK(result->TreeOverlays().size() == 1);
+ CHECK(result->TreeOverlays()[0]->ToJson()["trees"].size() == 1);
+ CHECK(result->TreeOverlays()[0]->ToJson()["trees"][0]["type"] ==
+ "TREE");
+ CHECK(result->TreeOverlays()[0]->ToJson()["disjoint"] == false);
+ }
+
+ SECTION("disjoint empty") {
+ error = false;
+ error_msg = "NONE";
+ {
+ TaskSystem ts;
+ target_map.ConsumeAfterKeysReady(
+ &ts,
+ {BuildMaps::Target::ConfiguredTarget{
+ .target =
+ BuildMaps::Base::EntityName{
+ "", "tree_overlay", "disjoint empty"},
+ .config = empty_config}},
+ [&result](auto values) { result = *values[0]; },
+ [&error, &error_msg](std::string const& msg, bool /*unused*/) {
+ error = true;
+ error_msg = msg;
+ });
+ }
+ CHECK(not error);
+ CHECK(error_msg == "NONE");
+ CHECK(result->TreeOverlays().size() == 1);
+ CHECK(result->TreeOverlays()[0]->ToJson()["trees"] ==
+ nlohmann::json::array());
+ CHECK(result->TreeOverlays()[0]->ToJson()["disjoint"] == true);
+ }
+
+ SECTION("disjoint implicit tree") {
+ error = false;
+ error_msg = "NONE";
+ {
+ TaskSystem ts;
+ target_map.ConsumeAfterKeysReady(
+ &ts,
+ {BuildMaps::Target::ConfiguredTarget{
+ .target =
+ BuildMaps::Base::EntityName{
+ "", "tree_overlay", "disjoint one stage"},
+ .config = empty_config}},
+ [&result](auto values) { result = *values[0]; },
+ [&error, &error_msg](std::string const& msg, bool /*unused*/) {
+ error = true;
+ error_msg = msg;
+ });
+ }
+ CHECK(not error);
+ CHECK(error_msg == "NONE");
+ CHECK(result->Trees().size() == 1);
+ CHECK(result->Trees()[0]->ToJson()["x"]["type"] == "LOCAL");
+ CHECK(result->TreeOverlays().size() == 1);
+ CHECK(result->TreeOverlays()[0]->ToJson()["trees"].size() == 1);
+ CHECK(result->TreeOverlays()[0]->ToJson()["trees"][0]["type"] ==
+ "TREE");
+ CHECK(result->TreeOverlays()[0]->ToJson()["disjoint"] == true);
+ }
+}
+
TEST_CASE("RESULT error reporting", "[target_map]") {
auto const storage_config = TestStorageConfig::Create();
auto const storage = Storage::Create(&storage_config.Get());