summaryrefslogtreecommitdiff
path: root/test/buildtool/build_engine/base_maps/rule_map.test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/buildtool/build_engine/base_maps/rule_map.test.cpp')
-rw-r--r--test/buildtool/build_engine/base_maps/rule_map.test.cpp348
1 files changed, 348 insertions, 0 deletions
diff --git a/test/buildtool/build_engine/base_maps/rule_map.test.cpp b/test/buildtool/build_engine/base_maps/rule_map.test.cpp
new file mode 100644
index 00000000..c0e64675
--- /dev/null
+++ b/test/buildtool/build_engine/base_maps/rule_map.test.cpp
@@ -0,0 +1,348 @@
+#include <filesystem>
+#include <functional>
+
+#include "catch2/catch.hpp"
+#include "src/buildtool/build_engine/base_maps/expression_map.hpp"
+#include "src/buildtool/build_engine/base_maps/json_file_map.hpp"
+#include "src/buildtool/build_engine/base_maps/rule_map.hpp"
+#include "src/buildtool/multithreading/task_system.hpp"
+#include "test/buildtool/build_engine/base_maps/test_repo.hpp"
+
+namespace {
+
+using namespace BuildMaps::Base; // NOLINT
+
+void SetupConfig(bool use_git) {
+ auto root = FileRoot{kBasePath / "data_rule"};
+ if (use_git) {
+ auto repo_path = CreateTestRepo();
+ REQUIRE(repo_path);
+ auto git_root = FileRoot::FromGit(*repo_path, kRuleTreeId);
+ REQUIRE(git_root);
+ root = std::move(*git_root);
+ }
+ RepositoryConfig::Instance().Reset();
+ RepositoryConfig::Instance().SetInfo(
+ "", RepositoryConfig::RepositoryInfo{root});
+}
+
+auto ReadUserRule(EntityName const& id,
+ UserRuleMap::Consumer value_checker,
+ bool use_git = false) -> bool {
+ SetupConfig(use_git);
+ auto expr_file_map = CreateExpressionFileMap(0);
+ auto expr_func_map = CreateExpressionMap(&expr_file_map);
+ auto rule_file_map = CreateRuleFileMap(0);
+ auto user_rule_map = CreateRuleMap(&rule_file_map, &expr_func_map);
+
+ bool success{true};
+ {
+ TaskSystem ts;
+ user_rule_map.ConsumeAfterKeysReady(
+ &ts,
+ {id},
+ std::move(value_checker),
+ [&success](std::string const& /*unused*/, bool /*unused*/) {
+ success = false;
+ });
+ }
+ return success;
+}
+
+} // namespace
+
+TEST_CASE("Test empty rule", "[expression_map]") {
+ auto name = EntityName{"", ".", "test_empty_rule"};
+ auto consumer = [](auto values) { REQUIRE(values[0]); };
+
+ SECTION("via file") {
+ CHECK(ReadUserRule(name, consumer, /*use_git=*/false));
+ }
+
+ SECTION("via git tree") {
+ CHECK(ReadUserRule(name, consumer, /*use_git=*/true));
+ }
+}
+
+TEST_CASE("Test rule fields", "[rule_map]") {
+ auto name = EntityName{"", ".", "test_rule_fields"};
+ auto consumer = [](auto values) {
+ REQUIRE(*values[0]);
+ REQUIRE_FALSE((*values[0])->StringFields().empty());
+ REQUIRE_FALSE((*values[0])->TargetFields().empty());
+ REQUIRE_FALSE((*values[0])->ConfigFields().empty());
+ CHECK((*values[0])->StringFields().at(0) == "foo");
+ CHECK((*values[0])->TargetFields().at(0) == "bar");
+ CHECK((*values[0])->ConfigFields().at(0) == "baz");
+ };
+
+ SECTION("via file") {
+ CHECK(ReadUserRule(name, consumer, /*use_git=*/false));
+ }
+
+ SECTION("via git tree") {
+ CHECK(ReadUserRule(name, consumer, /*use_git=*/true));
+ }
+}
+
+TEST_CASE("Test config_transitions target", "[rule_map]") {
+ auto consumer = [](auto values) { REQUIRE(*values[0]); };
+
+ SECTION("via field") {
+ auto name =
+ EntityName{"", ".", "test_config_transitions_target_via_field"};
+
+ SECTION("via file") {
+ CHECK(ReadUserRule(name, consumer, /*use_git=*/false));
+ }
+
+ SECTION("via git tree") {
+ CHECK(ReadUserRule(name, consumer, /*use_git=*/true));
+ }
+ }
+ SECTION("via implicit") {
+ auto name =
+ EntityName{"", ".", "test_config_transitions_target_via_implicit"};
+
+ SECTION("via file") {
+ CHECK(ReadUserRule(name, consumer, /*use_git=*/false));
+ }
+
+ SECTION("via git tree") {
+ CHECK(ReadUserRule(name, consumer, /*use_git=*/true));
+ }
+ }
+}
+
+TEST_CASE("Test config_transitions canonicalness", "[rule_map]") {
+ auto name = EntityName{"", ".", "test_config_transitions_canonicalness"};
+ auto consumer = [](auto values) {
+ REQUIRE(*values[0]);
+ auto const& transitions = (*values[0])->ConfigTransitions();
+ REQUIRE(transitions.size() == 4);
+ REQUIRE(transitions.at("foo"));
+ REQUIRE(transitions.at("bar"));
+ REQUIRE(transitions.at("baz"));
+ REQUIRE(transitions.at("qux"));
+ auto foo = transitions.at("foo")->Evaluate({}, {});
+ auto bar = transitions.at("bar")->Evaluate({}, {});
+ auto baz = transitions.at("baz")->Evaluate({}, {});
+ auto qux = transitions.at("qux")->Evaluate({}, {});
+ CHECK(foo == Expression::FromJson(R"([{}])"_json));
+ CHECK(bar == Expression::FromJson(R"([{"exists": true}])"_json));
+ CHECK(baz == Expression::FromJson(R"([{}])"_json));
+ CHECK(qux == Expression::FromJson(R"([{"defined": true}])"_json));
+ };
+
+ SECTION("via file") {
+ CHECK(ReadUserRule(name, consumer, /*use_git=*/false));
+ }
+
+ SECTION("via git tree") {
+ CHECK(ReadUserRule(name, consumer, /*use_git=*/true));
+ }
+}
+
+TEST_CASE("Test call of imported expression", "[rule_map]") {
+ auto name = EntityName{"", ".", "test_call_import"};
+ auto consumer = [](auto values) {
+ REQUIRE(*values[0]);
+ auto expr = (*values[0])->Expression();
+
+ REQUIRE(expr);
+ auto result = expr->Evaluate(
+ Configuration{Expression::FromJson(R"({"FOO": "bar"})"_json)}, {});
+
+ REQUIRE(result);
+ REQUIRE(result->IsMap());
+ CHECK(result["type"] == Expression{std::string{"RESULT"}});
+ CHECK(result["artifacts"] ==
+ Expression::FromJson(R"({"foo": "bar"})"_json));
+ };
+
+ SECTION("via file") {
+ CHECK(ReadUserRule(name, consumer, /*use_git=*/false));
+ }
+
+ SECTION("via git tree") {
+ CHECK(ReadUserRule(name, consumer, /*use_git=*/true));
+ }
+}
+
+TEST_CASE("Fail due to unknown ID", "[rule_map]") {
+ auto name = EntityName{"", ".", "does_not_exist"};
+ auto consumer = [](auto /*values*/) {
+ CHECK(false); // should never be called
+ };
+
+ SECTION("via file") {
+ CHECK_FALSE(ReadUserRule(name, consumer, /*use_git=*/false));
+ }
+
+ SECTION("via git tree") {
+ CHECK_FALSE(ReadUserRule(name, consumer, /*use_git=*/true));
+ }
+}
+
+TEST_CASE("Fail due to conflicting keyword names", "[rule_map]") {
+ SECTION("string_fields") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_string_kw_conflict"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+ SECTION("target_fields") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_target_kw_conflict"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+ SECTION("config_fields") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_config_kw_conflict"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+ SECTION("implicit_fields") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_implicit_kw_conflict"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+}
+
+TEST_CASE("Fail due to conflicting field names", "[rule_map]") {
+ SECTION("string <-> target") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_string_target_conflict"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+ SECTION("target <-> config") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_target_config_conflict"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+ SECTION("config <-> implicit") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_config_implicit_conflict"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+}
+
+TEST_CASE("Fail due to unknown config_transitions target", "[rule_map]") {
+ CHECK_FALSE(
+ ReadUserRule({"", ".", "test_unknown_config_transitions_target"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+}
+
+TEST_CASE("missing config_vars", "[rule_map]") {
+ CHECK(ReadUserRule({"", ".", "test_missing_config_vars"}, [](auto values) {
+ REQUIRE(*values[0]);
+ auto expr = (*values[0])->Expression();
+
+ REQUIRE(expr);
+ auto result = expr->Evaluate(
+ Configuration{Expression::FromJson(R"({"FOO": "bar"})"_json)}, {});
+
+ CHECK(result["artifacts"]["foo"] ==
+ Expression::FromJson(R"(null)"_json));
+ }));
+}
+
+TEST_CASE("Fail due to missing imports", "[rule_map]") {
+ CHECK(ReadUserRule({"", ".", "test_missing_imports"}, [](auto values) {
+ REQUIRE(*values[0]);
+ auto expr = (*values[0])->Expression();
+
+ REQUIRE(expr);
+ auto result = expr->Evaluate(
+ Configuration{Expression::FromJson(R"({"FOO": "bar"})"_json)}, {});
+
+ CHECK_FALSE(result);
+ }));
+}
+
+TEST_CASE("Malformed rule description", "[rule_map]") {
+ SECTION("Malformed rule") {
+ CHECK_FALSE(
+ ReadUserRule({"", ".", "test_malformed_rule"}, [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+
+ SECTION("Malformed rule expression") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_malformed_rule_expression"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+
+ SECTION("Malformed target_fields") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_malformed_target_fields"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+
+ SECTION("Malformed string_fields") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_malformed_string_fields"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+
+ SECTION("Malformed config_fields") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_malformed_config_fields"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+
+ SECTION("Malformed implicit") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_malformed_implicit"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+
+ SECTION("Malformed implicit entry") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_malformed_implicit_entry"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+
+ SECTION("Malformed implicit entity name") {
+ CHECK_FALSE(
+ ReadUserRule({"", ".", "test_malformed_implicit_entity_name"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+
+ SECTION("Malformed config_vars") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_malformed_config_vars"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+
+ SECTION("Malformed config_transitions") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_malformed_config_transitions"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+
+ SECTION("Malformed imports") {
+ CHECK_FALSE(ReadUserRule({"", ".", "test_malformed_imports"},
+ [](auto /*values*/) {
+ CHECK(false); // should never be called
+ }));
+ }
+}