summaryrefslogtreecommitdiff
path: root/test/buildtool/execution_api/common/api_test.hpp
diff options
context:
space:
mode:
authorOliver Reiche <oliver.reiche@huawei.com>2022-03-14 11:29:28 +0100
committerOliver Reiche <oliver.reiche@huawei.com>2022-03-14 11:29:28 +0100
commit10217a10a39f8a11aa97a47cc735943442a5aeeb (patch)
treeacc1f89526112b8f253b8dd7b39ad221d8bc5d9f /test/buildtool/execution_api/common/api_test.hpp
parentd6105778839cbdae5bfd234d54929b972328a6ee (diff)
downloadjustbuild-10217a10a39f8a11aa97a47cc735943442a5aeeb.tar.gz
ExecutionAPI: Add common tests for local and remote api
Diffstat (limited to 'test/buildtool/execution_api/common/api_test.hpp')
-rw-r--r--test/buildtool/execution_api/common/api_test.hpp314
1 files changed, 314 insertions, 0 deletions
diff --git a/test/buildtool/execution_api/common/api_test.hpp b/test/buildtool/execution_api/common/api_test.hpp
new file mode 100644
index 00000000..42026563
--- /dev/null
+++ b/test/buildtool/execution_api/common/api_test.hpp
@@ -0,0 +1,314 @@
+#include <cstdlib>
+#include <string>
+
+#include "catch2/catch.hpp"
+#include "src/buildtool/common/artifact_factory.hpp"
+#include "src/buildtool/execution_api/common/execution_action.hpp"
+#include "src/buildtool/execution_api/common/execution_api.hpp"
+#include "src/buildtool/execution_api/common/execution_response.hpp"
+
+using ApiFactory = std::function<IExecutionApi::Ptr()>;
+using ExecProps = std::map<std::string, std::string>;
+
+[[nodiscard]] static inline auto TestNoInputNoOutput(
+ ApiFactory const& api_factory,
+ ExecProps const& props,
+ bool is_hermetic = false) {
+ std::string test_content("test");
+
+ auto api = api_factory();
+
+ auto action = api->CreateAction(
+ *api->UploadTree({}), {"echo", "-n", test_content}, {}, {}, {}, props);
+
+ SECTION("Cache execution result in action cache") {
+ action->SetCacheFlag(IExecutionAction::CacheFlag::CacheOutput);
+
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ CHECK(response->HasStdOut());
+ CHECK(response->StdOut() == test_content);
+
+ if (is_hermetic) {
+ CHECK(not response->IsCached());
+
+ SECTION("Rerun execution to verify caching") {
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ CHECK(response->HasStdOut());
+ CHECK(response->StdOut() == test_content);
+ CHECK(response->IsCached());
+ }
+ }
+ }
+
+ SECTION("Do not cache execution result in action cache") {
+ action->SetCacheFlag(IExecutionAction::CacheFlag::DoNotCacheOutput);
+
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ CHECK(response->HasStdOut());
+ CHECK(response->StdOut() == test_content);
+ CHECK(not response->IsCached());
+
+ SECTION("Rerun execution to verify caching") {
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ CHECK(response->HasStdOut());
+ CHECK(response->StdOut() == test_content);
+ CHECK(not response->IsCached());
+ }
+ }
+}
+
+[[nodiscard]] static inline auto TestNoInputCreateOutput(
+ ApiFactory const& api_factory,
+ ExecProps const& props,
+ bool is_hermetic = false) {
+ std::string test_content("test");
+ auto test_digest = ArtifactDigest::Create(test_content);
+
+ std::string output_path{"output_file"};
+
+ auto api = api_factory();
+
+ auto action = api->CreateAction(
+ *api->UploadTree({}),
+ {"/bin/sh",
+ "-c",
+ "set -e\necho -n " + test_content + " > " + output_path},
+ {output_path},
+ {},
+ {},
+ props);
+
+ SECTION("Cache execution result in action cache") {
+ action->SetCacheFlag(IExecutionAction::CacheFlag::CacheOutput);
+
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ auto artifacts = response->Artifacts();
+ REQUIRE(artifacts.contains(output_path));
+ CHECK(artifacts.at(output_path).digest == test_digest);
+
+ if (is_hermetic) {
+ CHECK(not response->IsCached());
+
+ SECTION("Rerun execution to verify caching") {
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ auto artifacts = response->Artifacts();
+ REQUIRE(artifacts.contains(output_path));
+ CHECK(artifacts.at(output_path).digest == test_digest);
+ CHECK(response->IsCached());
+ }
+ }
+ }
+
+ SECTION("Do not cache execution result in action cache") {
+ action->SetCacheFlag(IExecutionAction::CacheFlag::DoNotCacheOutput);
+
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ auto artifacts = response->Artifacts();
+ REQUIRE(artifacts.contains(output_path));
+ CHECK(artifacts.at(output_path).digest == test_digest);
+ CHECK(not response->IsCached());
+
+ SECTION("Rerun execution to verify caching") {
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ auto artifacts = response->Artifacts();
+ REQUIRE(artifacts.contains(output_path));
+ CHECK(artifacts.at(output_path).digest == test_digest);
+ CHECK(not response->IsCached());
+ }
+ }
+}
+
+[[nodiscard]] static inline auto TestOneInputCopiedToOutput(
+ ApiFactory const& api_factory,
+ ExecProps const& props,
+ bool is_hermetic = false) {
+ std::string test_content("test");
+ auto test_digest = ArtifactDigest::Create(test_content);
+
+ auto input_artifact_opt =
+ ArtifactFactory::FromDescription(ArtifactFactory::DescribeKnownArtifact(
+ test_digest.hash(), test_digest.size(), ObjectType::File));
+ CHECK(input_artifact_opt.has_value());
+ auto input_artifact =
+ DependencyGraph::ArtifactNode{std::move(*input_artifact_opt)};
+
+ std::string input_path{"dir/subdir/input"};
+ std::string output_path{"output_file"};
+
+ auto api = api_factory();
+ CHECK(api->Upload(BlobContainer{{BazelBlob{test_digest, test_content}}},
+ false));
+
+ auto action =
+ api->CreateAction(*api->UploadTree({{input_path, &input_artifact}}),
+ {"cp", input_path, output_path},
+ {output_path},
+ {},
+ {},
+ props);
+
+ SECTION("Cache execution result in action cache") {
+ action->SetCacheFlag(IExecutionAction::CacheFlag::CacheOutput);
+
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ auto artifacts = response->Artifacts();
+ REQUIRE(artifacts.contains(output_path));
+ CHECK(artifacts.at(output_path).digest == test_digest);
+
+ if (is_hermetic) {
+ CHECK(not response->IsCached());
+
+ SECTION("Rerun execution to verify caching") {
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ auto artifacts = response->Artifacts();
+ REQUIRE(artifacts.contains(output_path));
+ CHECK(artifacts.at(output_path).digest == test_digest);
+ CHECK(response->IsCached());
+ }
+ }
+ }
+
+ SECTION("Do not cache execution result in action cache") {
+ action->SetCacheFlag(IExecutionAction::CacheFlag::DoNotCacheOutput);
+
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ auto artifacts = response->Artifacts();
+ REQUIRE(artifacts.contains(output_path));
+ CHECK(artifacts.at(output_path).digest == test_digest);
+ CHECK(not response->IsCached());
+
+ SECTION("Rerun execution to verify caching") {
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ auto artifacts = response->Artifacts();
+ REQUIRE(artifacts.contains(output_path));
+ CHECK(artifacts.at(output_path).digest == test_digest);
+ CHECK(not response->IsCached());
+ }
+ }
+}
+
+[[nodiscard]] static inline auto TestNonZeroExitCodeCreateOutput(
+ ApiFactory const& api_factory,
+ ExecProps const& props) {
+ std::string test_content("test");
+ auto test_digest = ArtifactDigest::Create(test_content);
+
+ std::string output_path{"output_file"};
+
+ auto api = api_factory();
+
+ auto action = api->CreateAction(*api->UploadTree({}),
+ {"/bin/sh",
+ "-c",
+ "set -e\necho -n " + test_content + " > " +
+ output_path + "\nexit 1\n"},
+ {output_path},
+ {},
+ {},
+ props);
+
+ SECTION("Cache execution result in action cache") {
+ action->SetCacheFlag(IExecutionAction::CacheFlag::CacheOutput);
+
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ CHECK(response->ExitCode() == 1);
+ auto artifacts = response->Artifacts();
+ REQUIRE(artifacts.contains(output_path));
+ CHECK(artifacts.at(output_path).digest == test_digest);
+
+ CHECK(not response->IsCached());
+
+ SECTION("Rerun execution to verify that non-zero actions are rerun") {
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ CHECK(response->ExitCode() == 1);
+ auto artifacts = response->Artifacts();
+ REQUIRE(artifacts.contains(output_path));
+ CHECK(artifacts.at(output_path).digest == test_digest);
+ CHECK(not response->IsCached());
+ }
+ }
+
+ SECTION("Do not cache execution result in action cache") {
+ action->SetCacheFlag(IExecutionAction::CacheFlag::DoNotCacheOutput);
+
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ CHECK(response->ExitCode() == 1);
+ auto artifacts = response->Artifacts();
+ REQUIRE(artifacts.contains(output_path));
+ CHECK(artifacts.at(output_path).digest == test_digest);
+ CHECK(not response->IsCached());
+
+ SECTION("Rerun execution to verify non-zero actions are not cached") {
+ // run execution
+ auto response = action->Execute();
+ REQUIRE(response);
+
+ // verify result
+ CHECK(response->ExitCode() == 1);
+ auto artifacts = response->Artifacts();
+ REQUIRE(artifacts.contains(output_path));
+ CHECK(artifacts.at(output_path).digest == test_digest);
+ CHECK(not response->IsCached());
+ }
+ }
+}