diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2023-08-24 11:43:05 +0200 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2023-08-24 12:29:21 +0200 |
commit | 7a503a1c875e4c9ac4b014036da77983af5272bc (patch) | |
tree | 32ae2f851ce87243b0c98781eb0591177168bb3d | |
parent | ff62463cc2ead9c153305fbb7bbce3d18c90ddf9 (diff) | |
download | justbuild-7a503a1c875e4c9ac4b014036da77983af5272bc.tar.gz |
Execution: only take complete actions from cache
... which are only actions that, besides giving exit code 0 also
created all the outputs they promised to.
-rw-r--r-- | src/buildtool/execution_api/local/TARGETS | 1 | ||||
-rw-r--r-- | src/buildtool/execution_api/local/local_action.cpp | 5 | ||||
-rw-r--r-- | src/buildtool/execution_api/remote/TARGETS | 1 | ||||
-rw-r--r-- | src/buildtool/execution_api/remote/bazel/bazel_action.cpp | 7 | ||||
-rw-r--r-- | src/buildtool/execution_api/utils/TARGETS | 7 | ||||
-rw-r--r-- | src/buildtool/execution_api/utils/outputscheck.hpp | 66 |
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 |