summaryrefslogtreecommitdiff
path: root/test/buildtool/execution_api/bazel/bytestream_client.test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/buildtool/execution_api/bazel/bytestream_client.test.cpp')
-rw-r--r--test/buildtool/execution_api/bazel/bytestream_client.test.cpp169
1 files changed, 169 insertions, 0 deletions
diff --git a/test/buildtool/execution_api/bazel/bytestream_client.test.cpp b/test/buildtool/execution_api/bazel/bytestream_client.test.cpp
new file mode 100644
index 00000000..fa09862c
--- /dev/null
+++ b/test/buildtool/execution_api/bazel/bytestream_client.test.cpp
@@ -0,0 +1,169 @@
+#include <string>
+
+#include "catch2/catch.hpp"
+#include "src/buildtool/execution_api/bazel_msg/bazel_blob.hpp"
+#include "src/buildtool/execution_api/common/execution_common.hpp"
+#include "src/buildtool/execution_api/remote/bazel/bytestream_client.hpp"
+#include "src/buildtool/execution_api/remote/config.hpp"
+
+constexpr std::size_t kLargeSize = GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH + 1;
+
+TEST_CASE("ByteStream Client: Transfer single blob", "[execution_api]") {
+ auto const& info = RemoteExecutionConfig::Instance();
+ auto stream = ByteStreamClient{info.Host(), info.Port()};
+ auto uuid = CreateUUIDVersion4(*CreateProcessUniqueId());
+
+ SECTION("Upload small blob") {
+ std::string instance_name{"remote-execution"};
+ std::string content("foobar");
+
+ // digest of "foobar"
+ auto digest = ArtifactDigest::Create(content);
+
+ CHECK(stream.Write(fmt::format("{}/uploads/{}/blobs/{}/{}",
+ instance_name,
+ uuid,
+ digest.hash(),
+ digest.size()),
+ content));
+
+ SECTION("Download small blob") {
+ auto data = stream.Read(fmt::format(
+ "{}/blobs/{}/{}", instance_name, digest.hash(), digest.size()));
+
+ CHECK(data == content);
+ }
+ }
+
+ SECTION("Upload large blob") {
+ std::string instance_name{"remote-execution"};
+
+ std::string content(kLargeSize, '\0');
+ for (std::size_t i{}; i < content.size(); ++i) {
+ content[i] = instance_name[i % instance_name.size()];
+ }
+
+ // digest of "instance_nameinstance_nameinstance_..."
+ auto digest = ArtifactDigest::Create(content);
+
+ CHECK(stream.Write(fmt::format("{}/uploads/{}/blobs/{}/{}",
+ instance_name,
+ uuid,
+ digest.hash(),
+ digest.size()),
+ content));
+
+ SECTION("Download large blob") {
+ auto data = stream.Read(fmt::format(
+ "{}/blobs/{}/{}", instance_name, digest.hash(), digest.size()));
+
+ CHECK(data == content);
+ }
+
+ SECTION("Incrementally download large blob") {
+ auto reader = stream.IncrementalRead(fmt::format(
+ "{}/blobs/{}/{}", instance_name, digest.hash(), digest.size()));
+
+ std::string data{};
+ auto chunk = reader.Next();
+ while (chunk and not chunk->empty()) {
+ data.append(chunk->begin(), chunk->end());
+ chunk = reader.Next();
+ }
+
+ CHECK(chunk);
+ CHECK(data == content);
+ }
+ }
+}
+
+TEST_CASE("ByteStream Client: Transfer multiple blobs", "[execution_api]") {
+ auto const& info = RemoteExecutionConfig::Instance();
+ auto stream = ByteStreamClient{info.Host(), info.Port()};
+ auto uuid = CreateUUIDVersion4(*CreateProcessUniqueId());
+
+ SECTION("Upload small blobs") {
+ std::string instance_name{"remote-execution"};
+
+ BazelBlob foo{ArtifactDigest::Create("foo"), "foo"};
+ BazelBlob bar{ArtifactDigest::Create("bar"), "bar"};
+ BazelBlob baz{ArtifactDigest::Create("baz"), "baz"};
+
+ CHECK(stream.WriteMany<BazelBlob>(
+ {foo, bar, baz},
+ [&instance_name, &uuid](auto const& blob) {
+ return fmt::format("{}/uploads/{}/blobs/{}/{}",
+ instance_name,
+ uuid,
+ blob.digest.hash(),
+ blob.digest.size_bytes());
+ },
+ [](auto const& blob) { return blob.data; }));
+
+ SECTION("Download small blobs") {
+ std::vector<std::string> contents{};
+ stream.ReadMany<bazel_re::Digest>(
+ {foo.digest, bar.digest, baz.digest},
+ [&instance_name](auto const& digest) -> std::string {
+ return fmt::format("{}/blobs/{}/{}",
+ instance_name,
+ digest.hash(),
+ digest.size_bytes());
+ },
+ [&contents](auto data) {
+ contents.emplace_back(std::move(data));
+ });
+ REQUIRE(contents.size() == 3);
+ CHECK(contents[0] == foo.data);
+ CHECK(contents[1] == bar.data);
+ CHECK(contents[2] == baz.data);
+ }
+ }
+
+ SECTION("Upload large blobs") {
+ std::string instance_name{"remote-execution"};
+
+ std::string content_foo(kLargeSize, '\0');
+ std::string content_bar(kLargeSize, '\0');
+ std::string content_baz(kLargeSize, '\0');
+ for (std::size_t i{}; i < content_foo.size(); ++i) {
+ content_foo[i] = instance_name[(i + 0) % instance_name.size()];
+ content_bar[i] = instance_name[(i + 1) % instance_name.size()];
+ content_baz[i] = instance_name[(i + 2) % instance_name.size()];
+ }
+
+ BazelBlob foo{ArtifactDigest::Create(content_foo), content_foo};
+ BazelBlob bar{ArtifactDigest::Create(content_bar), content_bar};
+ BazelBlob baz{ArtifactDigest::Create(content_baz), content_baz};
+
+ CHECK(stream.WriteMany<BazelBlob>(
+ {foo, bar, baz},
+ [&instance_name, &uuid](auto const& blob) {
+ return fmt::format("{}/uploads/{}/blobs/{}/{}",
+ instance_name,
+ uuid,
+ blob.digest.hash(),
+ blob.digest.size_bytes());
+ },
+ [](auto const& blob) { return blob.data; }));
+
+ SECTION("Download large blobs") {
+ std::vector<std::string> contents{};
+ stream.ReadMany<bazel_re::Digest>(
+ {foo.digest, bar.digest, baz.digest},
+ [&instance_name](auto const& digest) -> std::string {
+ return fmt::format("{}/blobs/{}/{}",
+ instance_name,
+ digest.hash(),
+ digest.size_bytes());
+ },
+ [&contents](auto data) {
+ contents.emplace_back(std::move(data));
+ });
+ REQUIRE(contents.size() == 3);
+ CHECK(contents[0] == foo.data);
+ CHECK(contents[1] == bar.data);
+ CHECK(contents[2] == baz.data);
+ }
+ }
+}