summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/buildtool/execution_api/local/TARGETS1
-rw-r--r--src/buildtool/execution_api/local/local_action.cpp5
-rw-r--r--src/buildtool/execution_api/remote/TARGETS1
-rw-r--r--src/buildtool/execution_api/remote/bazel/bazel_action.cpp7
-rw-r--r--src/buildtool/execution_api/utils/TARGETS7
-rw-r--r--src/buildtool/execution_api/utils/outputscheck.hpp66
6 files changed, 85 insertions, 2 deletions
diff --git a/src/buildtool/execution_api/local/TARGETS b/src/buildtool/execution_api/local/TARGETS
index 1ea94d69..f2c0e1b4 100644
--- a/src/buildtool/execution_api/local/TARGETS
+++ b/src/buildtool/execution_api/local/TARGETS
@@ -44,6 +44,7 @@
, ["src/buildtool/common", "common"]
, ["src/buildtool/common", "bazel_types"]
, ["src/buildtool/file_system", "file_system_manager"]
+ , ["src/buildtool/execution_api/utils", "outputscheck"]
]
}
}
diff --git a/src/buildtool/execution_api/local/local_action.cpp b/src/buildtool/execution_api/local/local_action.cpp
index 3fcd8fe7..badc62e5 100644
--- a/src/buildtool/execution_api/local/local_action.cpp
+++ b/src/buildtool/execution_api/local/local_action.cpp
@@ -22,6 +22,7 @@
#include "src/buildtool/compatibility/native_support.hpp"
#include "src/buildtool/execution_api/local/config.hpp"
#include "src/buildtool/execution_api/local/local_response.hpp"
+#include "src/buildtool/execution_api/utils/outputscheck.hpp"
#include "src/buildtool/file_system/file_system_manager.hpp"
#include "src/buildtool/file_system/object_type.hpp"
#include "src/buildtool/storage/config.hpp"
@@ -89,7 +90,9 @@ auto LocalAction::Execute(Logger const* logger) noexcept
if (do_cache) {
if (auto result = storage_->ActionCache().CachedResult(action)) {
- if (result->exit_code() == 0) {
+ if (result->exit_code() == 0 and
+ ActionResultContainsExpectedOutputs(
+ *result, output_files_, output_dirs_)) {
return IExecutionResponse::Ptr{
new LocalResponse{action.hash(),
{std::move(*result), /*is_cached=*/true},
diff --git a/src/buildtool/execution_api/remote/TARGETS b/src/buildtool/execution_api/remote/TARGETS
index 7af331ab..d999ef26 100644
--- a/src/buildtool/execution_api/remote/TARGETS
+++ b/src/buildtool/execution_api/remote/TARGETS
@@ -41,6 +41,7 @@
, ["src/buildtool/file_system", "object_type"]
, ["src/buildtool/compatibility", "compatibility"]
, ["src/buildtool/execution_api/bazel_msg", "bazel_msg_factory"]
+ , ["src/buildtool/execution_api/utils", "outputscheck"]
]
}
, "bazel":
diff --git a/src/buildtool/execution_api/remote/bazel/bazel_action.cpp b/src/buildtool/execution_api/remote/bazel/bazel_action.cpp
index 04d4c3f7..65dfd083 100644
--- a/src/buildtool/execution_api/remote/bazel/bazel_action.cpp
+++ b/src/buildtool/execution_api/remote/bazel/bazel_action.cpp
@@ -17,6 +17,7 @@
#include "src/buildtool/execution_api/bazel_msg/bazel_blob_container.hpp"
#include "src/buildtool/execution_api/bazel_msg/bazel_msg_factory.hpp"
#include "src/buildtool/execution_api/remote/bazel/bazel_response.hpp"
+#include "src/buildtool/execution_api/utils/outputscheck.hpp"
BazelAction::BazelAction(
std::shared_ptr<BazelNetwork> network,
@@ -57,7 +58,11 @@ auto BazelAction::Execute(Logger const* logger) noexcept
if (do_cache) {
if (auto result =
network_->GetCachedActionResult(action, output_files_)) {
- if (result->exit_code() == 0) {
+ if (result->exit_code() == 0 and
+ ActionResultContainsExpectedOutputs(
+ *result, output_files_, output_dirs_)
+
+ ) {
return IExecutionResponse::Ptr{new BazelResponse{
action.hash(), network_, {*result, true}}};
}
diff --git a/src/buildtool/execution_api/utils/TARGETS b/src/buildtool/execution_api/utils/TARGETS
index 20b65c18..1c5bb6c5 100644
--- a/src/buildtool/execution_api/utils/TARGETS
+++ b/src/buildtool/execution_api/utils/TARGETS
@@ -15,4 +15,11 @@
]
, "stage": ["src", "buildtool", "execution_api", "utils"]
}
+, "outputscheck":
+ { "type": ["@", "rules", "CC", "library"]
+ , "name": ["outputscheck"]
+ , "hdrs": ["outputscheck.hpp"]
+ , "deps": [["src/buildtool/common", "common"]]
+ , "stage": ["src", "buildtool", "execution_api", "utils"]
+ }
}
diff --git a/src/buildtool/execution_api/utils/outputscheck.hpp b/src/buildtool/execution_api/utils/outputscheck.hpp
new file mode 100644
index 00000000..13bf5dd2
--- /dev/null
+++ b/src/buildtool/execution_api/utils/outputscheck.hpp
@@ -0,0 +1,66 @@
+// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef INCLUDED_SRC_BUILDTOOL_EXECUTION_API_UTILS_OUTPUTSCHECK_HPP
+#define INCLUDED_SRC_BUILDTOOL_EXECUTION_API_UTILS_OUTPUTSCHECK_HPP
+
+#ifndef BOOTSTRAP_BUILD_TOOL
+
+#include <algorithm>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "src/buildtool/common/bazel_types.hpp"
+
+[[nodiscard]] static inline auto ActionResultContainsExpectedOutputs(
+ const bazel_re::ActionResult& result,
+ std::vector<std::string> expected_files,
+ std::vector<std::string> expected_dirs) noexcept -> bool {
+ try {
+ std::set<std::string> actual_output_files{};
+ for (auto const& file : result.output_files()) {
+ actual_output_files.emplace(file.path());
+ }
+ for (auto const& file : result.output_file_symlinks()) {
+ actual_output_files.emplace(file.path());
+ }
+ for (auto const& file : result.output_directory_symlinks()) {
+ actual_output_files.emplace(file.path());
+ }
+ if (not std::all_of(expected_files.begin(),
+ expected_files.end(),
+ [&actual_output_files](auto const& expected) {
+ return actual_output_files.contains(expected);
+ })) {
+ return false;
+ }
+
+ std::set<std::string> actual_output_dirs{};
+ for (auto const& dir : result.output_directories()) {
+ actual_output_dirs.emplace(dir.path());
+ }
+ return std::all_of(expected_dirs.begin(),
+ expected_dirs.end(),
+ [&actual_output_dirs](auto const& expected) {
+ return actual_output_dirs.contains(expected);
+ });
+ } catch (...) {
+ return false;
+ }
+}
+
+#endif
+
+#endif