Fix `ConsumedArtifactsTracker` handling of template expansion inputs. Tree artifacts that are only consumed via action templates were not getting registered as consumed - the children appear as action inputs, but not the parent. Make sure `ConsumedArtifactsTracker` registers the parent tree artifact as consumed if any children are consumed. PiperOrigin-RevId: 972275451 Change-Id: I8ff550134586efd8705eb4776b166648ce4817fe
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ConsumedArtifactsTracker.java b/src/main/java/com/google/devtools/build/lib/skyframe/ConsumedArtifactsTracker.java index 8501311..c024d4e 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ConsumedArtifactsTracker.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ConsumedArtifactsTracker.java
@@ -35,16 +35,21 @@ } void unregisterOutputsAfterExecutionDone(Collection<Artifact> outputs) { - consumed.removeAll(outputs); + for (Artifact artifact : outputs) { + consumed.remove(representative(artifact)); + } } /** Register the provided artifact as "consumed". */ void registerConsumedArtifact(Artifact artifact) { - // We should only store the consumed status of artifacts that will later on be checked for - // orphaned status directly. This is an optimization to keep the set smaller. - if (!artifact.isSourceArtifact() // Source artifacts won't be orphaned. - && !artifact.hasParent()) { // Will be checked through the parent artifact. - consumed.add(artifact); + if (artifact.isSourceArtifact()) { + return; // Source artifacts are never orphaned, so we don't track them. } + consumed.add(representative(artifact)); + } + + private static Artifact representative(Artifact artifact) { + // Tree artifact children are checked through the parent artifact. + return artifact.hasParent() ? artifact.getParent() : artifact; } }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/EphemeralCheckIfOutputConsumed.java b/src/main/java/com/google/devtools/build/lib/skyframe/EphemeralCheckIfOutputConsumed.java index e225ced..90455bd 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/EphemeralCheckIfOutputConsumed.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/EphemeralCheckIfOutputConsumed.java
@@ -22,5 +22,12 @@ * execution of its generating action, and its behavior is undefined afterwards. */ public interface EphemeralCheckIfOutputConsumed { + + /** + * Tests whether a generated artifact is known to be consumed. + * + * <p>Should not be called for {@linkplain Artifact#isSourceArtifact source artifacts}. Children + * of tree artifacts should be tested by passing their {@linkplain Artifact#getParent parent}. + */ boolean test(Artifact artifact); }
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/rewinding/RewindingTestsHelper.java b/src/test/java/com/google/devtools/build/lib/skyframe/rewinding/RewindingTestsHelper.java index a651265..4e6a14d 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/rewinding/RewindingTestsHelper.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/rewinding/RewindingTestsHelper.java
@@ -246,7 +246,7 @@ } public final ExecResult createLostInputsExecException( - ActionExecutionContext context, ImmutableList<ActionInput> lostInputs) throws IOException { + ActionExecutionContext context, List<ActionInput> lostInputs) throws IOException { ImmutableSetMultimap.Builder<String, ActionInput> builder = ImmutableSetMultimap.builder(); for (ActionInput lostInput : lostInputs) { builder.put(getHexDigest(lostInput, context), lostInput);