Avoid crashing when creating an `OutputFileConfiguredTarget` with `--allow_analysis_failures` when the generating rule has failure info.
PiperOrigin-RevId: 442560374
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
index 34460aa..bd86160 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
@@ -215,17 +215,24 @@
if (analysisEnvironment.getSkyframeEnv().valuesMissing()) {
return null;
}
+ Label ruleLabel = outputFile.getGeneratingRule().getLabel();
RuleConfiguredTarget rule =
(RuleConfiguredTarget)
targetContext.findDirectPrerequisite(
- outputFile.getGeneratingRule().getLabel(),
+ ruleLabel,
// Don't pass a specific configuration, as we don't care what configuration the
// generating rule is in. There can only be one actual dependency here, which is
// the target that generated the output file.
Optional.empty());
- Verify.verifyNotNull(rule);
+ Verify.verifyNotNull(
+ rule, "While analyzing %s, missing generating rule %s", outputFile, ruleLabel);
+ // If analysis failures are allowed and the generating rule has failure info, just propagate
+ // it. The output artifact won't exist, so we can't create an OutputFileConfiguredTarget.
+ if (config.allowAnalysisFailures()
+ && rule.get(AnalysisFailureInfo.STARLARK_CONSTRUCTOR.getKey()) != null) {
+ return rule;
+ }
Artifact artifact = rule.getArtifactByOutputLabel(outputFile.getLabel());
-
return new OutputFileConfiguredTarget(targetContext, outputFile, rule, artifact);
} else if (target instanceof InputFile) {
InputFile inputFile = (InputFile) target;
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/AnalysisFailureInfoTest.java b/src/test/java/com/google/devtools/build/lib/analysis/AnalysisFailureInfoTest.java
index 6cf883e..fdbdde8 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/AnalysisFailureInfoTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/AnalysisFailureInfoTest.java
@@ -26,19 +26,20 @@
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
+import com.google.testing.junit.testparameterinjector.TestParameter;
+import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import javax.annotation.Nullable;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkSemantics;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
/**
* Tests verifying analysis failure propagation via {@link AnalysisFailureInfo} when {@code
* --allow_analysis_failures=true}.
*/
-@RunWith(JUnit4.class)
+@RunWith(TestParameterInjector.class)
public final class AnalysisFailureInfoTest extends BuildViewTestCase {
@Before
@@ -64,18 +65,20 @@
return Starlark.getattr(/*mu=*/ null, StarlarkSemantics.DEFAULT, x, name, null);
}
- // Regression test for b/154007057
+ /** Regression test for b/154007057 (rule name) and b/186685477 (output file). */
@Test
- public void nativeRuleExpanderFailure() throws Exception {
+ public void nativeRuleExpanderFailure(
+ @TestParameter({"//test:bad_variable", "//test:bad_variable.out"}) String targetToRequest)
+ throws Exception {
scratch.file(
- "test/BUILD", //
+ "test/BUILD",
"genrule(",
" name = 'bad_variable',",
- " outs = ['bad.out'],",
+ " outs = ['bad_variable.out'],",
" cmd = 'cp $< $@', # Error to use $< with no srcs",
")");
- ConfiguredTarget target = getConfiguredTarget("//test:bad_variable");
+ ConfiguredTarget target = getConfiguredTarget(targetToRequest);
AnalysisFailureInfo info =
(AnalysisFailureInfo) target.get(AnalysisFailureInfo.STARLARK_CONSTRUCTOR.getKey());
AnalysisFailure failure = info.getCauses().getSet(AnalysisFailure.class).toList().get(0);
@@ -83,11 +86,11 @@
assertThat(failure.getLabel()).isEqualTo(Label.parseAbsoluteUnchecked("//test:bad_variable"));
}
- // Regression test for b/154007057
+ /** Regression test for b/154007057. */
@Test
public void nativeRuleConfiguredTargetFactoryCreateReturningNull() throws Exception {
scratch.file(
- "test/BUILD", //
+ "test/BUILD",
"native_rule_with_failing_configured_target_factory(",
" name = 'bad_factory',",
")");
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/BUILD b/src/test/java/com/google/devtools/build/lib/analysis/BUILD
index 8f031ac..7be1be4 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/analysis/BUILD
@@ -228,6 +228,7 @@
"//third_party:jsr305",
"//third_party:junit4",
"//third_party:truth",
+ "@com_google_testparameterinjector//:testparameterinjector",
],
)