summaryrefslogtreecommitdiff
path: root/test/buildtool/execution_api/local_tree_map.test.cpp
diff options
context:
space:
mode:
authorKlaus Aehlig <klaus.aehlig@huawei.com>2022-02-22 17:03:21 +0100
committerKlaus Aehlig <klaus.aehlig@huawei.com>2022-02-22 17:03:21 +0100
commit619def44c1cca9f3cdf63544d5f24f2c7a7d9b77 (patch)
tree01868de723cb82c86842f33743fa7b14e24c1fa3 /test/buildtool/execution_api/local_tree_map.test.cpp
downloadjustbuild-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/execution_api/local_tree_map.test.cpp')
-rw-r--r--test/buildtool/execution_api/local_tree_map.test.cpp110
1 files changed, 110 insertions, 0 deletions
diff --git a/test/buildtool/execution_api/local_tree_map.test.cpp b/test/buildtool/execution_api/local_tree_map.test.cpp
new file mode 100644
index 00000000..d8becced
--- /dev/null
+++ b/test/buildtool/execution_api/local_tree_map.test.cpp
@@ -0,0 +1,110 @@
+#include <string>
+#include <thread>
+#include <vector>
+
+#include "catch2/catch.hpp"
+#include "src/buildtool/execution_api/common/local_tree_map.hpp"
+#include "src/utils/cpp/atomic.hpp"
+
+namespace {
+
+[[nodiscard]] auto ToDigest(std::string const& s) {
+ return static_cast<bazel_re::Digest>(ArtifactDigest{s, 0});
+}
+
+[[nodiscard]] auto ToInfo(std::string const& s) {
+ return Artifact::ObjectInfo{ArtifactDigest{s, 0}, ObjectType::File};
+}
+
+} // namespace
+
+TEST_CASE("LocalTree: empty tree", "[execution_api]") {
+ LocalTreeMap tree_map{};
+
+ auto tree = tree_map.CreateTree();
+ CHECK(tree.size() == 0);
+ CHECK(std::all_of(
+ tree.begin(), tree.end(), [](auto /*unused*/) { return false; }));
+}
+
+TEST_CASE("LocalTree: first wins", "[execution_api]") {
+ LocalTreeMap tree_map{};
+
+ auto tree = tree_map.CreateTree();
+ CHECK(tree.AddInfo("foo", ToInfo("bar")));
+ CHECK(tree.AddInfo("foo", ToInfo("baz")));
+ CHECK(tree.size() == 1);
+ for (auto const& [path, oid] : tree) {
+ CHECK(oid->digest.hash() == "bar");
+ }
+}
+
+TEST_CASE("LocalTreeMap: first wins", "[execution_api]") {
+ LocalTreeMap tree_map{};
+
+ auto tree_1 = tree_map.CreateTree();
+ CHECK(tree_1.AddInfo("foo", ToInfo("bar")));
+
+ auto tree_2 = tree_map.CreateTree();
+ CHECK(tree_2.AddInfo("foo", ToInfo("baz")));
+
+ auto tree_id = ToDigest("tree");
+ CHECK(tree_map.AddTree(tree_id, std::move(tree_1))); // NOLINT
+ CHECK(tree_map.AddTree(tree_id, std::move(tree_2))); // NOLINT
+
+ CHECK(tree_map.HasTree(tree_id));
+
+ auto const* tree = tree_map.GetTree(tree_id);
+ REQUIRE(tree != nullptr);
+ CHECK(tree->size() == 1);
+ for (auto const& [path, oid] : *tree) {
+ CHECK(oid->digest.hash() == "bar");
+ }
+}
+
+TEST_CASE("LocalTreeMap: thread-safety", "[execution_api]") {
+ constexpr auto kNumThreads = 100;
+ constexpr auto kQ = 10;
+
+ atomic<bool> starting_signal{false};
+ std::vector<std::thread> threads{};
+ threads.reserve(kNumThreads);
+
+ LocalTreeMap tree_map{};
+
+ for (int id{}; id < kNumThreads; ++id) {
+ threads.emplace_back(
+ [&tree_map, &starting_signal](int tid) {
+ auto entry_id = std::to_string(tid);
+ auto tree = tree_map.CreateTree();
+ REQUIRE(tree.AddInfo(entry_id, ToInfo(entry_id)));
+
+ auto tree_id = ToDigest(std::to_string(tid / kQ));
+ starting_signal.wait(false);
+
+ // kQ-many threads try to add tree with same id
+ REQUIRE(tree_map.AddTree(tree_id, std::move(tree))); // NOLINT
+ },
+ id);
+ }
+
+ starting_signal = true;
+ starting_signal.notify_all();
+ for (auto& thread : threads) {
+ thread.join();
+ }
+
+ for (int id{}; id <= (kNumThreads - 1) / kQ; ++id) {
+ auto tree_id = ToDigest(std::to_string(id));
+ CHECK(tree_map.HasTree(tree_id));
+
+ auto const* tree = tree_map.GetTree(tree_id);
+ REQUIRE(tree != nullptr);
+ CHECK(tree->size() == 1);
+ for (auto const& [path, oid] : *tree) {
+ auto entry_id = std::stoi(oid->digest.hash());
+ CHECK(entry_id >= id * kQ);
+ CHECK(entry_id < (id + 1) * kQ);
+ }
+ }
+}