Only apply deps limit to analysis tests using transitions
Previously, a transitive-dependency count limit was applied to all analysis_test rules for simplicity, since there was not deemed a use case for an analysis test that was "large". However, relaxing this restriction to only apply to rules using transitions facilitates a build_test-like Starlark rule which verifies an existing real target analyzes correctly without executing any actions.
Progress toward #6237
RELNOTES: None.
PiperOrigin-RevId: 235580276
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
index af2f5d2..dfba1a7 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
@@ -162,6 +162,27 @@
addProvider(new DepCountInfo(transitiveDepCount()));
}
+ if (ruleContext.getRule().hasAnalysisTestTransition()) {
+ int depCount = transitiveDepCount();
+ if (depCount > ruleContext.getConfiguration().analysisTestingDepsLimit()) {
+ ruleContext.ruleError(
+ String.format(
+ "analysis test rule excedeed maximum dependency edge count. "
+ + "Count: %s. Limit is %s. This limit is imposed on analysis test rules which "
+ + "use analysis_test_transition attribute transitions. Exceeding this limit "
+ + "indicates either the analysis_test has too many dependencies, or the "
+ + "underlying toolchains may be large. Try decreasing the number of test "
+ + "dependencies, (Analysis tests should not be very large!) or, if possible, "
+ + "try not using configuration transitions. If underlying toolchain size is "
+ + "to blame, it might be worth considering increasing "
+ + "--analysis_testing_deps_limit. (Beware, however, that large values of "
+ + "this flag can lead to no safeguards against giant "
+ + "test suites that can lead to Out Of Memory exceptions in the build server.)",
+ depCount, ruleContext.getConfiguration().analysisTestingDepsLimit()));
+ return null;
+ }
+ }
+
TransitiveInfoProviderMap providers = providersBuilder.build();
if (ruleContext.getRule().isAnalysisTest()) {
@@ -177,22 +198,6 @@
}
AnalysisTestActionBuilder.writeAnalysisTestAction(ruleContext, testResultInfo);
-
- int depCount = transitiveDepCount();
- if (depCount > ruleContext.getConfiguration().analysisTestingDepsLimit()) {
- ruleContext.ruleError(
- String.format(
- "analysis test rule excedeed maximum dependency edge count. "
- + "Count: %s. Limit is %s. This indicates either the analysis_test has too "
- + "many dependencies, or the underlying toolchains may be large. Try "
- + "decreasing the number of test dependencies. (Analysis tests should not be "
- + "very large!) If underlying toolchain size is to blame, it might be worth "
- + "considering increasing --analysis_testing_deps_limit. (Beware, however, "
- + "that large values of this flag can lead to no safeguards against giant "
- + "test suites that can lead to Out Of Memory exceptions in the build server.)",
- depCount, ruleContext.getConfiguration().analysisTestingDepsLimit()));
- return null;
- }
}
AnalysisEnvironment analysisEnvironment = ruleContext.getAnalysisEnvironment();
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
index 4639d41..24e1241 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
@@ -677,11 +677,14 @@
Attribute attr = descriptor.build(name);
hasStarlarkDefinedTransition |= attr.hasStarlarkDefinedTransition();
- if (attr.hasAnalysisTestTransition() && !builder.isAnalysisTest()) {
- throw new EvalException(
- location,
- "Only rule definitions with analysis_test=True may have attributes with "
- + "analysis_test_transition transitions");
+ if (attr.hasAnalysisTestTransition()) {
+ if (!builder.isAnalysisTest()) {
+ throw new EvalException(
+ location,
+ "Only rule definitions with analysis_test=True may have attributes with "
+ + "analysis_test_transition transitions");
+ }
+ builder.setHasAnalysisTestTransition();
}
// Check for existence of the function transition whitelist attribute.
// TODO(b/121385274): remove when we stop whitelisting starlark transitions
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Rule.java b/src/main/java/com/google/devtools/build/lib/packages/Rule.java
index ae01bd2..c3245b4 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Rule.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Rule.java
@@ -182,6 +182,14 @@
}
/**
+ * Returns true if this rule has at least one attribute with an analysis test transition. (A
+ * starlark-defined transition using analysis_test_transition()).
+ */
+ public boolean hasAnalysisTestTransition() {
+ return ruleClass.hasAnalysisTestTransition();
+ }
+
+ /**
* Returns true iff there were errors while constructing this rule, such as
* attributes with missing values or values of the wrong type.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
index d61cc4a..7f96fc4 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -645,6 +645,7 @@
private boolean workspaceOnly = false;
private boolean isExecutableSkylark = false;
private boolean isAnalysisTest = false;
+ private boolean hasAnalysisTestTransition = false;
private boolean isConfigMatcher = false;
private boolean hasFunctionTransitionWhitelist = false;
private boolean ignorePackageLicenses = false;
@@ -808,6 +809,7 @@
workspaceOnly,
isExecutableSkylark,
isAnalysisTest,
+ hasAnalysisTestTransition,
hasFunctionTransitionWhitelist,
ignorePackageLicenses,
implicitOutputsFunction,
@@ -1195,6 +1197,19 @@
}
/**
+ * This rule class has at least one attribute with an analysis test transition. (A
+ * starlark-defined transition using analysis_test_transition()).
+ */
+ public Builder setHasAnalysisTestTransition() {
+ this.hasAnalysisTestTransition = true;
+ return this;
+ }
+
+ public boolean hasAnalysisTestTransition() {
+ return this.hasAnalysisTestTransition;
+ }
+
+ /**
* This rule class has the _whitelist_function_transition attribute. Intended only for Skylark
* rules.
*/
@@ -1390,6 +1405,7 @@
private final boolean workspaceOnly;
private final boolean isExecutableSkylark;
private final boolean isAnalysisTest;
+ private final boolean hasAnalysisTestTransition;
private final boolean isConfigMatcher;
private final boolean hasFunctionTransitionWhitelist;
private final boolean ignorePackageLicenses;
@@ -1519,6 +1535,7 @@
boolean workspaceOnly,
boolean isExecutableSkylark,
boolean isAnalysisTest,
+ boolean hasAnalysisTestTransition,
boolean hasFunctionTransitionWhitelist,
boolean ignorePackageLicenses,
ImplicitOutputsFunction implicitOutputsFunction,
@@ -1569,6 +1586,7 @@
this.workspaceOnly = workspaceOnly;
this.isExecutableSkylark = isExecutableSkylark;
this.isAnalysisTest = isAnalysisTest;
+ this.hasAnalysisTestTransition = hasAnalysisTestTransition;
this.hasFunctionTransitionWhitelist = hasFunctionTransitionWhitelist;
this.ignorePackageLicenses = ignorePackageLicenses;
this.configurationFragmentPolicy = configurationFragmentPolicy;
@@ -2424,6 +2442,14 @@
}
/**
+ * Returns true if this rule class has at least one attribute with an analysis test transition. (A
+ * starlark-defined transition using analysis_test_transition()).
+ */
+ public boolean hasAnalysisTestTransition() {
+ return hasAnalysisTestTransition;
+ }
+
+ /**
* Returns true if this rule class has the _whitelist_function_transition attribute.
*/
public boolean hasFunctionTransitionWhitelist() {