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", ], )