diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2022-02-22 17:03:21 +0100 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2022-02-22 17:03:21 +0100 |
commit | 619def44c1cca9f3cdf63544d5f24f2c7a7d9b77 (patch) | |
tree | 01868de723cb82c86842f33743fa7b14e24c1fa3 /test/buildtool/common | |
download | justbuild-619def44c1cca9f3cdf63544d5f24f2c7a7d9b77.tar.gz |
Initial self-hosting commit
This is the initial version of our tool that is able to
build itself. In can be bootstrapped by
./bin/bootstrap.py
Co-authored-by: Oliver Reiche <oliver.reiche@huawei.com>
Co-authored-by: Victor Moreno <victor.moreno1@huawei.com>
Diffstat (limited to 'test/buildtool/common')
-rw-r--r-- | test/buildtool/common/TARGETS | 41 | ||||
-rw-r--r-- | test/buildtool/common/action_description.test.cpp | 72 | ||||
-rw-r--r-- | test/buildtool/common/artifact_description.test.cpp | 127 | ||||
-rw-r--r-- | test/buildtool/common/artifact_factory.test.cpp | 54 |
4 files changed, 294 insertions, 0 deletions
diff --git a/test/buildtool/common/TARGETS b/test/buildtool/common/TARGETS new file mode 100644 index 00000000..d6bcdbf1 --- /dev/null +++ b/test/buildtool/common/TARGETS @@ -0,0 +1,41 @@ +{ "artifact_factory": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["artifact_factory"] + , "srcs": ["artifact_factory.test.cpp"] + , "deps": + [ ["@", "catch2", "", "catch2"] + , ["test", "catch-main"] + , ["src/buildtool/common", "artifact_factory"] + ] + , "stage": ["test", "buildtool", "common"] + } +, "artifact_description": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["artifact_description"] + , "srcs": ["artifact_description.test.cpp"] + , "deps": + [ ["@", "catch2", "", "catch2"] + , ["test", "catch-main"] + , ["src/buildtool/common", "artifact_factory"] + , ["src/buildtool/common", "artifact_description"] + ] + , "stage": ["test", "buildtool", "common"] + } +, "action_description": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["action_description"] + , "srcs": ["action_description.test.cpp"] + , "deps": + [ ["@", "catch2", "", "catch2"] + , ["test", "catch-main"] + , ["src/buildtool/common", "artifact_factory"] + , ["src/buildtool/common", "action_description"] + ] + , "stage": ["test", "buildtool", "common"] + } +, "TESTS": + { "type": "install" + , "tainted": ["test"] + , "deps": ["action_description", "artifact_description", "artifact_factory"] + } +}
\ No newline at end of file diff --git a/test/buildtool/common/action_description.test.cpp b/test/buildtool/common/action_description.test.cpp new file mode 100644 index 00000000..ac7367e1 --- /dev/null +++ b/test/buildtool/common/action_description.test.cpp @@ -0,0 +1,72 @@ +#include "catch2/catch.hpp" +#include "src/buildtool/common/action_description.hpp" +#include "src/buildtool/common/artifact_factory.hpp" + +TEST_CASE("From JSON", "[action_description]") { + using path = std::filesystem::path; + auto desc = + ActionDescription{{"output0", "output1"}, + {"dir0", "dir1"}, + Action{"id", {"command", "line"}, {{"env", "vars"}}}, + {{"path0", ArtifactDescription{path{"input0"}}}, + {"path1", ArtifactDescription{path{"input1"}}}}}; + auto const& action = desc.GraphAction(); + auto json = ArtifactFactory::DescribeAction(desc.OutputFiles(), + desc.OutputDirs(), + action.Command(), + desc.Inputs(), + action.Env()); + + SECTION("Parse full action") { + auto description = ActionDescription::FromJson("id", json); + REQUIRE(description); + CHECK(description->ToJson() == json); + } + + SECTION("Parse action without optional input") { + json["input"] = nlohmann::json::object(); + CHECK(ActionDescription::FromJson("id", json)); + + json["input"] = nlohmann::json::array(); + CHECK_FALSE(ActionDescription::FromJson("id", json)); + + json.erase("input"); + CHECK(ActionDescription::FromJson("id", json)); + } + + SECTION("Parse action without optional env") { + json["env"] = nlohmann::json::object(); + CHECK(ActionDescription::FromJson("id", json)); + + json["env"] = nlohmann::json::array(); + CHECK_FALSE(ActionDescription::FromJson("id", json)); + + json.erase("env"); + CHECK(ActionDescription::FromJson("id", json)); + } + + SECTION("Parse action without mandatory outputs") { + json["output"] = nlohmann::json::array(); + json["output_dirs"] = nlohmann::json::array(); + CHECK_FALSE(ActionDescription::FromJson("id", json)); + + json["output"] = nlohmann::json::object(); + json["output_dirs"] = nlohmann::json::object(); + CHECK_FALSE(ActionDescription::FromJson("id", json)); + + json.erase("output"); + json.erase("output_dirs"); + CHECK_FALSE(ActionDescription::FromJson("id", json)); + } + + SECTION("Parse action without mandatory command") { + json["command"] = nlohmann::json::array(); + CHECK_FALSE(ActionDescription::FromJson("id", json)); + + json["command"] = nlohmann::json::object(); + CHECK_FALSE(ActionDescription::FromJson("id", json)); + + json.erase("command"); + CHECK_FALSE(ActionDescription::FromJson("id", json)); + } +} diff --git a/test/buildtool/common/artifact_description.test.cpp b/test/buildtool/common/artifact_description.test.cpp new file mode 100644 index 00000000..b1522198 --- /dev/null +++ b/test/buildtool/common/artifact_description.test.cpp @@ -0,0 +1,127 @@ +#include "catch2/catch.hpp" +#include "src/buildtool/common/artifact_description.hpp" +#include "src/buildtool/common/artifact_factory.hpp" + +[[nodiscard]] auto operator==(Artifact const& lhs, Artifact const& rhs) + -> bool { + return lhs.Id() == rhs.Id() and lhs.FilePath() == rhs.FilePath() and + lhs.Info() == rhs.Info(); +} + +TEST_CASE("Local artifact", "[artifact_description]") { + auto local_desc = + ArtifactDescription{std::filesystem::path{"local_path"}, "repo"}; + auto local = local_desc.ToArtifact(); + auto local_from_factory = + ArtifactFactory::FromDescription(local_desc.ToJson()); + CHECK(local == *local_from_factory); +} + +TEST_CASE("Known artifact", "[artifact_description]") { + SECTION("File object") { + auto known_desc = ArtifactDescription{ + ArtifactDigest{std::string{"f_fake_hash"}, 0}, ObjectType::File}; + auto known = known_desc.ToArtifact(); + auto known_from_factory = + ArtifactFactory::FromDescription(known_desc.ToJson()); + CHECK(known == *known_from_factory); + } + SECTION("Executable object") { + auto known_desc = + ArtifactDescription{ArtifactDigest{std::string{"x_fake_hash"}, 1}, + ObjectType::Executable}; + auto known = known_desc.ToArtifact(); + auto known_from_factory = + ArtifactFactory::FromDescription(known_desc.ToJson()); + CHECK(known == *known_from_factory); + } +} + +TEST_CASE("Action artifact", "[artifact_description]") { + auto action_desc = + ArtifactDescription{"action_id", std::filesystem::path{"out_path"}}; + auto action = action_desc.ToArtifact(); + auto action_from_factory = + ArtifactFactory::FromDescription(action_desc.ToJson()); + CHECK(action == *action_from_factory); +} + +TEST_CASE("From JSON", "[artifact_description]") { + auto local = ArtifactFactory::DescribeLocalArtifact("local", "repo"); + auto known = + ArtifactFactory::DescribeKnownArtifact("hash", 0, ObjectType::File); + auto action = ArtifactFactory::DescribeActionArtifact("id", "output"); + + SECTION("Parse artifacts") { + CHECK(ArtifactDescription::FromJson(local)); + CHECK(ArtifactDescription::FromJson(known)); + CHECK(ArtifactDescription::FromJson(action)); + } + + SECTION("Parse artifact without mandatory type") { + local.erase("type"); + known.erase("type"); + action.erase("type"); + CHECK_FALSE(ArtifactDescription::FromJson(local)); + CHECK_FALSE(ArtifactDescription::FromJson(known)); + CHECK_FALSE(ArtifactDescription::FromJson(action)); + } + + SECTION("Parse artifact without mandatory data") { + local.erase("data"); + known.erase("data"); + action.erase("data"); + CHECK_FALSE(ArtifactDescription::FromJson(local)); + CHECK_FALSE(ArtifactDescription::FromJson(known)); + CHECK_FALSE(ArtifactDescription::FromJson(action)); + } + + SECTION("Parse local artifact without mandatory path") { + local["data"]["path"] = 0; + CHECK_FALSE(ArtifactDescription::FromJson(local)); + + local["data"].erase("path"); + CHECK_FALSE(ArtifactDescription::FromJson(local)); + } + + SECTION("Parse known artifact") { + SECTION("without mandatory id") { + known["data"]["id"] = 0; + CHECK_FALSE(ArtifactDescription::FromJson(known)); + + known["data"].erase("id"); + CHECK_FALSE(ArtifactDescription::FromJson(known)); + } + SECTION("without mandatory size") { + known["data"]["size"] = "0"; + CHECK_FALSE(ArtifactDescription::FromJson(known)); + + known["data"].erase("size"); + CHECK_FALSE(ArtifactDescription::FromJson(known)); + } + SECTION("without mandatory file_type") { + known["data"]["file_type"] = "more_than_one_char"; + CHECK_FALSE(ArtifactDescription::FromJson(known)); + + known["data"].erase("file_type"); + CHECK_FALSE(ArtifactDescription::FromJson(known)); + } + } + + SECTION("Parse action artifact") { + SECTION("without mandatory id") { + action["data"]["id"] = 0; + CHECK_FALSE(ArtifactDescription::FromJson(action)); + + action["data"].erase("id"); + CHECK_FALSE(ArtifactDescription::FromJson(action)); + } + SECTION("without mandatory path") { + action["data"]["path"] = 0; + CHECK_FALSE(ArtifactDescription::FromJson(action)); + + action["data"].erase("path"); + CHECK_FALSE(ArtifactDescription::FromJson(action)); + } + } +} diff --git a/test/buildtool/common/artifact_factory.test.cpp b/test/buildtool/common/artifact_factory.test.cpp new file mode 100644 index 00000000..818ce410 --- /dev/null +++ b/test/buildtool/common/artifact_factory.test.cpp @@ -0,0 +1,54 @@ +#include "catch2/catch.hpp" +#include "src/buildtool/common/artifact_factory.hpp" + +TEST_CASE("Description missing mandatory key/value pair", + "[artifact_factory]") { + + nlohmann::json const missing_type = {{"data", {{"path", "some/path"}}}}; + CHECK(not ArtifactFactory::FromDescription(missing_type)); + nlohmann::json const missing_data = {{"type", "LOCAL"}}; + CHECK(not ArtifactFactory::FromDescription(missing_data)); +} + +TEST_CASE("Local artifact description contains incorrect value for \"data\"", + "[artifact_factory]") { + nlohmann::json const local_art_missing_path = { + {"type", "LOCAL"}, {"data", nlohmann::json::object()}}; + CHECK(not ArtifactFactory::FromDescription(local_art_missing_path)); +} + +TEST_CASE("Known artifact description contains incorrect value for \"data\"", + "[artifact_factory]") { + std::string file_type{}; + file_type += ToChar(ObjectType::File); + SECTION("missing \"id\"") { + nlohmann::json const known_art_missing_id = { + {"type", "KNOWN"}, + {"data", {{"size", 15}, {"file_type", file_type}}}}; + CHECK(not ArtifactFactory::FromDescription(known_art_missing_id)); + } + SECTION("missing \"size\"") { + nlohmann::json const known_art_missing_size = { + {"type", "KNOWN"}, + {"data", {{"id", "known_input"}, {"file_type", file_type}}}}; + CHECK(not ArtifactFactory::FromDescription(known_art_missing_size)); + } + SECTION("missing \"file_type\"") { + nlohmann::json const known_art_missing_file_type = { + {"type", "KNOWN"}, {"data", {{"id", "known_input"}, {"size", 15}}}}; + + CHECK( + not ArtifactFactory::FromDescription(known_art_missing_file_type)); + } +} + +TEST_CASE("Action artifact description contains incorrect value for \"data\"", + "[artifact_factory]") { + nlohmann::json const action_art_missing_id = { + {"type", "ACTION"}, {"data", {{"path", "output/path"}}}}; + CHECK(not ArtifactFactory::FromDescription(action_art_missing_id)); + + nlohmann::json const action_art_missing_path = { + {"type", "ACTION"}, {"data", {{"id", "action_id"}}}}; + CHECK(not ArtifactFactory::FromDescription(action_art_missing_path)); +} |