Convert TestAspects to MockRule.

It'd be nice to go further and break out a bunch of this code into more generally useful places (especially for callers that don't care about aspects). But that's a big mess and beyond the scope of what I'm aiming for here.

PiperOrigin-RevId: 177307854
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java b/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
index 76336fe..15bc2cc 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
@@ -29,11 +29,10 @@
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil.NullAction;
 import com.google.devtools.build.lib.analysis.BuildView.AnalysisResult;
 import com.google.devtools.build.lib.analysis.util.AnalysisTestCase;
+import com.google.devtools.build.lib.analysis.util.MockRule;
 import com.google.devtools.build.lib.analysis.util.TestAspects;
 import com.google.devtools.build.lib.analysis.util.TestAspects.AspectApplyingToFiles;
 import com.google.devtools.build.lib.analysis.util.TestAspects.AspectInfo;
-import com.google.devtools.build.lib.analysis.util.TestAspects.AspectRequiringRule;
-import com.google.devtools.build.lib.analysis.util.TestAspects.BaseRule;
 import com.google.devtools.build.lib.analysis.util.TestAspects.DummyRuleFactory;
 import com.google.devtools.build.lib.analysis.util.TestAspects.RuleInfo;
 import com.google.devtools.build.lib.cmdline.Label;
@@ -45,7 +44,6 @@
 import com.google.devtools.build.lib.packages.AspectParameters;
 import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
 import com.google.devtools.build.lib.packages.NativeAspectClass;
-import com.google.devtools.build.lib.packages.RuleClass;
 import com.google.devtools.build.lib.skyframe.AspectValue;
 import com.google.devtools.build.lib.testutil.TestConstants;
 import com.google.devtools.build.lib.vfs.ModifiedFileSet;
@@ -71,7 +69,7 @@
 
   @Test
   public void testAspectAppliedToAliasWithSelect() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new AspectRequiringRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ASPECT_REQUIRING_RULE);
     pkg("a",
         "aspect(name='a', foo=[':b'])",
         "alias(name='b', actual=select({'//conditions:default': ':c'}))",
@@ -83,7 +81,7 @@
 
   @Test
   public void testAspectAppliedToChainedAliases() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new AspectRequiringRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ASPECT_REQUIRING_RULE);
     pkg("a",
         "aspect(name='a', foo=[':b'])",
         "alias(name='b', actual=':c')",
@@ -98,7 +96,7 @@
 
   @Test
   public void testAspectAppliedToChainedAliasesAndSelect() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new AspectRequiringRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ASPECT_REQUIRING_RULE);
     pkg("a",
         "aspect(name='a', foo=[':b'])",
         "alias(name='b', actual=select({'//conditions:default': ':c'}))",
@@ -111,7 +109,7 @@
 
   @Test
   public void providersOfAspectAreMergedIntoDependency() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new AspectRequiringRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ASPECT_REQUIRING_RULE);
     pkg("a",
         "aspect(name='a', foo=[':b'])",
         "aspect(name='b', foo=[])");
@@ -123,8 +121,8 @@
 
   @Test
   public void aspectIsNotCreatedIfAdvertisedProviderIsNotPresent() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.LiarRule(),
-        new TestAspects.AspectRequiringProviderRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.LIAR_RULE,
+        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);
 
     pkg("a",
         "aspect_requiring_provider(name='a', foo=[':b'])",
@@ -136,8 +134,8 @@
 
   @Test
   public void aspectIsNotCreatedIfAdvertisedProviderIsNotPresentWithAlias() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.LiarRule(),
-        new TestAspects.AspectRequiringProviderRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.LIAR_RULE,
+        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);
 
     pkg("a",
         "aspect_requiring_provider(name='a', foo=[':b'])",
@@ -150,10 +148,8 @@
 
   @Test
   public void aspectIsNotPropagatedThroughLiars() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(),
-        new TestAspects.LiarRule(),
-        new TestAspects.HonestRule(),
-        new TestAspects.AspectRequiringProviderRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.LIAR_RULE,
+        TestAspects.HONEST_RULE, TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);
 
     pkg("a",
         "aspect_requiring_provider(name='a', foo=[':b_alias'])",
@@ -168,8 +164,8 @@
 
   @Test
   public void aspectPropagatedThroughAliasRule() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.HonestRule(),
-        new TestAspects.AspectRequiringProviderRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.HONEST_RULE,
+        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);
 
     pkg("a",
         "aspect_requiring_provider(name='a', foo=[':b_alias'])",
@@ -183,8 +179,8 @@
 
   @Test
   public void aspectPropagatedThroughAliasRuleAndHonestRules() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.HonestRule(),
-        new TestAspects.AspectRequiringProviderRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.HONEST_RULE,
+        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);
 
     pkg("a",
         "aspect_requiring_provider(name='a', foo=[':b'])",
@@ -208,9 +204,8 @@
       // TODO(b/67651960): fix or justify disabling.
       return;
     }
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.HonestRule(),
-        new TestAspects.AspectRequiringProviderRule());
-
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.HONEST_RULE,
+        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);
     pkg("a",
         "aspect_requiring_provider(name='a', foo=['//external:b'])",
         "honest(name='b', foo=[])");
@@ -232,8 +227,8 @@
 
   @Test
   public void aspectCreatedIfAdvertisedProviderIsPresent() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.HonestRule(),
-        new TestAspects.AspectRequiringProviderRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.HONEST_RULE,
+        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);
 
     pkg("a",
         "aspect_requiring_provider(name='a', foo=[':b'])",
@@ -246,8 +241,8 @@
 
   @Test
   public void aspectCreatedIfAtLeastOneSetOfAdvertisedProvidersArePresent() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.HonestRule(),
-        new TestAspects.HonestRule2(), new TestAspects.AspectRequiringProviderSetsRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.HONEST_RULE,
+        TestAspects.HONEST_RULE_2, TestAspects.ASPECT_REQUIRING_PROVIDER_SETS_RULE);
 
     pkg("a",
         "aspect_requiring_provider_sets(name='a', foo=[':b', ':c'])",
@@ -262,9 +257,9 @@
   @Test
   public void aspectWithParametrizedDefinition() throws Exception {
     setRulesAvailableInTests(
-        new TestAspects.BaseRule(),
-        new TestAspects.HonestRule(),
-        new TestAspects.ParametrizedDefinitionAspectRule());
+        TestAspects.BASE_RULE,
+        TestAspects.HONEST_RULE,
+        TestAspects.PARAMETERIZED_DEFINITION_ASPECT_RULE);
 
     pkg(
         "a",
@@ -283,8 +278,8 @@
 
   @Test
   public void aspectInError() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.ErrorAspectRule(),
-        new TestAspects.SimpleRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ERROR_ASPECT_RULE,
+        TestAspects.SIMPLE_RULE);
 
     pkg("a",
         "simple(name='a', foo=[':b'])",
@@ -305,8 +300,8 @@
 
   @Test
   public void transitiveAspectInError() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.ErrorAspectRule(),
-        new TestAspects.SimpleRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ERROR_ASPECT_RULE,
+        TestAspects.SIMPLE_RULE);
 
     pkg("a",
         "error_aspect(name='a', foo=[':b'])",
@@ -328,8 +323,7 @@
 
   @Test
   public void aspectDependenciesDontShowDeprecationWarnings() throws Exception {
-    setRulesAvailableInTests(
-        new TestAspects.BaseRule(), new TestAspects.ExtraAttributeAspectRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.EXTRA_ATTRIBUTE_ASPECT_RULE);
 
     pkg("extra", "base(name='extra', deprecation='bad aspect')");
 
@@ -343,7 +337,7 @@
 
   @Test
   public void ruleDependencyDeprecationWarningsAbsentDuringAspectEvaluations() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.AspectRequiringRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ASPECT_REQUIRING_RULE);
 
     pkg("a", "aspect(name='a', foo=['//b:b'])");
     pkg("b", "aspect(name='b', bar=['//d:d'])");
@@ -359,7 +353,7 @@
       // TODO(b/67651960): fix or justify disabling.
       return;
     }
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.WarningAspectRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.WARNING_ASPECT_RULE);
     pkg("a", "warning_aspect(name='a', foo=['//b:b', '//c:c'])");
     pkg("b", "base(name='b')");
     pkg("c", "base(name='c')");
@@ -373,8 +367,8 @@
 
   @Test
   public void sameTargetInDifferentAttributes() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.AspectRequiringRule(),
-        new TestAspects.SimpleRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ASPECT_REQUIRING_RULE,
+        TestAspects.SIMPLE_RULE);
     pkg("a",
         "aspect(name='a', foo=[':b'], bar=[':b'])",
         "aspect(name='b', foo=[])");
@@ -386,8 +380,8 @@
 
   @Test
   public void sameTargetInDifferentAttributesWithDifferentAspects() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.MultiAspectRule(),
-        new TestAspects.SimpleRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.MULTI_ASPECT_RULE,
+        TestAspects.SIMPLE_RULE);
     pkg("a",
         "multi_aspect(name='a', foo=':b', bar=':b')",
         "simple(name='b')");
@@ -398,9 +392,8 @@
 
   @Test
   public void informationFromBaseRulePassedToAspect() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.HonestRule(),
-        new TestAspects.AspectRequiringProviderRule());
-
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.HONEST_RULE,
+        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);
     pkg("a",
         "aspect_requiring_provider(name='a', foo=[':b'], baz='hello')",
         "honest(name='b', foo=[])");
@@ -414,21 +407,13 @@
    * Rule definitions to be used in emptyAspectAttributesAreAvailableInRuleContext().
    */
   public static class EmptyAspectAttributesAreAvailableInRuleContext {
-    public static class TestRule implements RuleDefinition {
-      @Override
-      public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
-        return builder
-            .add(attr("foo", LABEL_LIST).legacyAllowAnyFileType()
-                .aspect(ASPECT_WITH_EMPTY_LATE_BOUND_ATTRIBUTE))
-            .build();
-      }
-
-      @Override
-      public Metadata getMetadata() {
-        return RuleDefinition.Metadata.builder().name("testrule")
-            .factoryClass(DummyRuleFactory.class).ancestors(BaseRule.class).build();
-      }
-    }
+    public static final MockRule TEST_RULE = () ->
+        MockRule.ancestor(TestAspects.BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+            "testrule",
+            (builder, env) ->
+                builder
+                    .add(attr("foo", LABEL_LIST).legacyAllowAnyFileType()
+                        .aspect(new AspectWithEmptyLateBoundAttribute())));
 
     public static class AspectWithEmptyLateBoundAttribute extends NativeAspectClass
       implements ConfiguredAspectFactory {
@@ -453,8 +438,6 @@
             .build();
       }
     }
-    public static final AspectWithEmptyLateBoundAttribute ASPECT_WITH_EMPTY_LATE_BOUND_ATTRIBUTE =
-        new AspectWithEmptyLateBoundAttribute();
   }
 
   /**
@@ -464,8 +447,8 @@
    */
   @Test
   public void emptyAspectAttributesAreAvailableInRuleContext() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(),
-        new EmptyAspectAttributesAreAvailableInRuleContext.TestRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE,
+        EmptyAspectAttributesAreAvailableInRuleContext.TEST_RULE);
     pkg("a",
         "testrule(name='a', foo=[':b'])",
         "testrule(name='b')");
@@ -477,22 +460,14 @@
    * Rule definitions to be used in extraActionsAreEmitted().
    */
   public static class ExtraActionsAreEmitted {
-    public static class TestRule implements RuleDefinition {
-      @Override
-      public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
-        return builder
-            .add(attr("foo", LABEL_LIST).legacyAllowAnyFileType()
-                .aspect(ASPECT_THAT_REGISTERS_ACTION))
-            .add(attr(":action_listener", LABEL_LIST).cfg(HOST).value(ACTION_LISTENER))
-            .build();
-      }
-
-      @Override
-      public Metadata getMetadata() {
-        return RuleDefinition.Metadata.builder().name("testrule")
-            .factoryClass(DummyRuleFactory.class).ancestors(BaseRule.class).build();
-      }
-    }
+    public static final MockRule TEST_RULE = () ->
+        MockRule.ancestor(TestAspects.BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+            "testrule",
+            (builder, env) ->
+                builder
+                    .add(attr("foo", LABEL_LIST).legacyAllowAnyFileType()
+                        .aspect(new AspectThatRegistersAction()))
+                    .add(attr(":action_listener", LABEL_LIST).cfg(HOST).value(ACTION_LISTENER)));
 
     public static class AspectThatRegistersAction extends NativeAspectClass
       implements ConfiguredAspectFactory {
@@ -511,8 +486,6 @@
         return new ConfiguredAspect.Builder(this, parameters, ruleContext).build();
       }
     }
-    private static final AspectThatRegistersAction ASPECT_THAT_REGISTERS_ACTION =
-        new AspectThatRegistersAction();
   }
 
   /**
@@ -525,8 +498,7 @@
    */
   @Test
   public void extraActionsAreEmitted() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(),
-        new ExtraActionsAreEmitted.TestRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, ExtraActionsAreEmitted.TEST_RULE);
     useConfiguration("--experimental_action_listener=//extra_actions:listener");
     scratch.file(
         "extra_actions/BUILD",
@@ -547,9 +519,8 @@
 
   @Test
   public void aspectPropagatesToAllAttributes() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(),
-        new TestAspects.SimpleRule(),
-        new TestAspects.AllAttributesAspectRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE,
+        TestAspects.ALL_ATTRIBUTES_ASPECT_RULE);
     pkg("a",
         "simple(name='a', foo=[':b'], foo1=':c', txt='some text')",
         "simple(name='b', foo=[], txt='some text')",
@@ -682,11 +653,8 @@
 
   @Test
   public void aspectPropagatesToAllAttributesImplicit() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(),
-        new TestAspects.SimpleRule(),
-        new TestAspects.ImplicitDepRule(),
-        new TestAspects.AllAttributesAspectRule());
-
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE,
+        TestAspects.IMPLICIT_DEP_RULE, TestAspects.ALL_ATTRIBUTES_ASPECT_RULE);
     scratch.file(
         "extra/BUILD",
         "simple(name ='extra')"
@@ -711,10 +679,8 @@
 
   @Test
   public void aspectPropagatesToAllAttributesLateBound() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(),
-        new TestAspects.SimpleRule(),
-        new TestAspects.LateBoundDepRule(),
-        new TestAspects.AllAttributesAspectRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE,
+        TestAspects.LATE_BOUND_DEP_RULE, TestAspects.ALL_ATTRIBUTES_ASPECT_RULE);
 
     scratch.file(
         "extra/BUILD",
@@ -744,10 +710,8 @@
    */
   @Test
   public void aspectWithAllAttributesDoesNotPropagateToOwnImplicitAttributes() throws Exception {
-    setRulesAvailableInTests(
-        new TestAspects.BaseRule(),
-        new TestAspects.SimpleRule(),
-        new TestAspects.AllAttributesWithToolAspectRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE,
+        TestAspects.ALL_ATTRIBUTES_WITH_TOOL_ASPECT_RULE);
     pkg(
         "a",
         "simple(name='tool')",
@@ -765,10 +729,8 @@
    */
   @Test
   public void aspectWithAllAttributesPropagatesToItsToolIfThereIsPath() throws Exception {
-    setRulesAvailableInTests(
-        new TestAspects.BaseRule(),
-        new TestAspects.SimpleRule(),
-        new TestAspects.AllAttributesWithToolAspectRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE,
+        TestAspects.ALL_ATTRIBUTES_WITH_TOOL_ASPECT_RULE);
     pkg(
         "a",
         "simple(name='tool')",
@@ -786,10 +748,8 @@
   @Test
   public void aspectTruthInAdvertisement() throws Exception {
     reporter.removeHandler(failFastHandler); // expect errors
-    setRulesAvailableInTests(
-        new TestAspects.BaseRule(),
-        new TestAspects.SimpleRule(),
-        new TestAspects.FalseAdvertisementAspectRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE,
+        TestAspects.FALSE_ADVERTISEMENT_ASPECT_RULE);
     pkg(
         "a",
         "simple(name = 's')",
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/DependencyResolverTest.java b/src/test/java/com/google/devtools/build/lib/analysis/DependencyResolverTest.java
index 11e04e9..9cc761f 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/DependencyResolverTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/DependencyResolverTest.java
@@ -22,7 +22,6 @@
 import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
 import com.google.devtools.build.lib.analysis.util.AnalysisTestCase;
 import com.google.devtools.build.lib.analysis.util.TestAspects;
-import com.google.devtools.build.lib.analysis.util.TestAspects.AspectRequiringRule;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.packages.Aspect;
@@ -145,7 +144,7 @@
 
   @Test
   public void hasAspectsRequiredByRule() throws Exception {
-    setRulesAvailableInTests(new AspectRequiringRule(), new TestAspects.BaseRule());
+    setRulesAvailableInTests(TestAspects.ASPECT_REQUIRING_RULE, TestAspects.BASE_RULE);
     pkg("a",
         "aspect(name='a', foo=[':b'])",
         "aspect(name='b', foo=[])");
@@ -157,7 +156,7 @@
 
   @Test
   public void hasAspectsRequiredByAspect() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.SimpleRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE);
     pkg("a",
         "simple(name='a', foo=[':b'])",
         "simple(name='b', foo=[])");
@@ -170,7 +169,7 @@
 
   @Test
   public void hasAllAttributesAspect() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.SimpleRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE);
     pkg("a",
         "simple(name='a', foo=[':b'])",
         "simple(name='b', foo=[])");
@@ -183,7 +182,7 @@
 
   @Test
   public void hasAspectDependencies() throws Exception {
-    setRulesAvailableInTests(new TestAspects.BaseRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE);
     pkg("a", "base(name='a')");
     pkg("extra", "base(name='extra')");
     OrderedSetMultimap<Attribute, Dependency> map =
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java b/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java
index 0e68a67..0a01e3f 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java
@@ -13,14 +13,10 @@
 // limitations under the License.
 package com.google.devtools.build.lib.analysis.util;
 
-import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.HOST;
 import static com.google.devtools.build.lib.packages.Attribute.attr;
 import static com.google.devtools.build.lib.packages.BuildType.LABEL;
 import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
-import static com.google.devtools.build.lib.packages.BuildType.NODEP_LABEL_LIST;
-import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
 import static com.google.devtools.build.lib.syntax.Type.STRING;
-import static com.google.devtools.build.lib.syntax.Type.STRING_LIST;
 
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableCollection;
@@ -28,15 +24,12 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.analysis.BaseRuleClasses;
 import com.google.devtools.build.lib.analysis.ConfiguredAspect;
 import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
 import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
 import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
 import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.analysis.RuleDefinition;
-import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
 import com.google.devtools.build.lib.analysis.Runfiles;
 import com.google.devtools.build.lib.analysis.RunfilesProvider;
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
@@ -54,8 +47,6 @@
 import com.google.devtools.build.lib.packages.BuildType;
 import com.google.devtools.build.lib.packages.NativeAspectClass;
 import com.google.devtools.build.lib.packages.Rule;
-import com.google.devtools.build.lib.packages.RuleClass;
-import com.google.devtools.build.lib.packages.RuleClass.Builder;
 import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
 import com.google.devtools.build.lib.rules.java.JavaConfiguration;
 import com.google.devtools.build.lib.syntax.Type;
@@ -548,492 +539,214 @@
             ImmutableList.of(SkylarkProviderIdentifier.forLegacy("advertised_provider")))
         .build();
 
-
   /**
    * A common base rule for mock rules in this class to reduce boilerplate.
    *
    * <p>It has a few common attributes because internal Blaze machinery assumes the presence of
    * these.
    */
-  public static class BaseRule implements RuleDefinition {
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("testonly", BOOLEAN).nonconfigurable("test").value(false))
-          .add(attr("deprecation", STRING).nonconfigurable("test").value((String) null))
-          .add(attr("tags", STRING_LIST))
-          .add(attr("visibility", NODEP_LABEL_LIST).orderIndependent().cfg(HOST)
-              .nonconfigurable("test"))
-          .add(attr(RuleClass.COMPATIBLE_ENVIRONMENT_ATTR, LABEL_LIST)
-              .allowedFileTypes(FileTypeSet.NO_FILE))
-          .add(attr(RuleClass.RESTRICTED_ENVIRONMENT_ATTR, LABEL_LIST)
-              .allowedFileTypes(FileTypeSet.NO_FILE))
-          .build();
-
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("base")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRuleClasses.RootRule.class)
-          .build();
-    }
-  }
+  public static final MockRule BASE_RULE = () ->
+      MockRule.factory(DummyRuleFactory.class).define("base");
 
   /**
    * A rule that defines an aspect on one of its attributes.
    */
-  public static class AspectRequiringRule implements RuleDefinition {
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
-              .aspect(SIMPLE_ASPECT))
-          .add(attr("bar", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
-              .aspect(SIMPLE_ASPECT))
-          .build();
-
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("aspect")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule ASPECT_REQUIRING_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "aspect",
+          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
+              .aspect(SIMPLE_ASPECT),
+          attr("bar", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
+              .aspect(SIMPLE_ASPECT));
 
   /**
    * A rule that defines different aspects on different attributes.
    */
-  public static class MultiAspectRule implements RuleDefinition {
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("foo", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE)
+  public static final MockRule MULTI_ASPECT_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(MultiAspectRuleFactory.class).define(
+          "multi_aspect",
+          attr("foo", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE)
               .mandatory()
-              .aspect(FOO_PROVIDER_ASPECT))
-          .add(attr("bar", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE)
+              .aspect(FOO_PROVIDER_ASPECT),
+          attr("bar", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE)
               .mandatory()
-              .aspect(BAR_PROVIDER_ASPECT))
-          .build();
+              .aspect(BAR_PROVIDER_ASPECT));
 
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("multi_aspect")
-          .factoryClass(MultiAspectRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  private static final Function<Rule, AspectParameters> TEST_ASPECT_PARAMETERS_EXTRACTOR =
+      (rule) -> {
+        if (rule.isAttrDefined("baz", STRING)) {
+          String value = rule.getAttributeContainer().getAttr("baz").toString();
+          if (!value.equals("")) {
+            return new AspectParameters.Builder().addAttribute("baz", value).build();
+          }
+        }
+        return AspectParameters.EMPTY;
+      };
 
   /**
    * A rule that defines an {@link AspectRequiringProvider} on one of its attributes.
    */
-  public static class AspectRequiringProviderRule implements RuleDefinition {
-
-    private static final class TestAspectParametersExtractor implements
-        Function<Rule, AspectParameters> {
-      @Override
-      public AspectParameters apply(Rule rule) {
-        if (rule.isAttrDefined("baz", STRING)) {
-          String value = rule.getAttributeContainer().getAttr("baz").toString();
-          if (!value.equals("")) {
-            return new AspectParameters.Builder().addAttribute("baz", value).build();
-          }
-        }
-        return AspectParameters.EMPTY;
-      }
-    }
-
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
-              .aspect(ASPECT_REQUIRING_PROVIDER, new TestAspectParametersExtractor()))
-          .add(attr("baz", STRING))
-          .build();
-
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("aspect_requiring_provider")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule ASPECT_REQUIRING_PROVIDER_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "aspect_requiring_provider",
+          (builder, env) ->
+              builder
+                  .add(
+                      attr("foo", LABEL_LIST)
+                          .allowedFileTypes(FileTypeSet.ANY_FILE)
+                          .aspect(ASPECT_REQUIRING_PROVIDER, TEST_ASPECT_PARAMETERS_EXTRACTOR))
+                  .add(attr("baz", STRING)));
 
   /**
    * A rule that defines an {@link AspectRequiringProviderSets} on one of its attributes.
    */
-  public static class AspectRequiringProviderSetsRule implements RuleDefinition {
-
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
-              .aspect(ASPECT_REQUIRING_PROVIDER_SETS))
-          .add(attr("baz", STRING))
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("aspect_requiring_provider_sets")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule ASPECT_REQUIRING_PROVIDER_SETS_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "aspect_requiring_provider_sets",
+          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
+              .aspect(ASPECT_REQUIRING_PROVIDER_SETS),
+          attr("baz", STRING));
 
   /**
    * A rule that defines an {@link ExtraAttributeAspect} on one of its attributes.
    */
-  public static class ExtraAttributeAspectRule implements RuleDefinition {
-
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
-              .aspect(EXTRA_ATTRIBUTE_ASPECT))
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("rule_with_extra_deps_aspect")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule EXTRA_ATTRIBUTE_ASPECT_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "rule_with_extra_deps_aspect",
+          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
+              .aspect(EXTRA_ATTRIBUTE_ASPECT));
 
   /**
    * A rule that defines an {@link ParametrizedDefinitionAspect} on one of its attributes.
    */
-  public static class ParametrizedDefinitionAspectRule implements RuleDefinition {
+  public static final MockRule PARAMETERIZED_DEFINITION_ASPECT_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "parametrized_definition_aspect",
+          (builder, env) ->
+              builder
+                  .add(
+                      attr("foo", LABEL_LIST)
+                          .allowedFileTypes(FileTypeSet.ANY_FILE)
+                          .aspect(PARAMETRIZED_DEFINITION_ASPECT, TEST_ASPECT_PARAMETERS_EXTRACTOR))
+                  .add(attr("baz", STRING)));
 
-    private static final class TestAspectParametersExtractor
-        implements Function<Rule, AspectParameters> {
-      @Override
-      public AspectParameters apply(Rule rule) {
-        if (rule.isAttrDefined("baz", STRING)) {
-          String value = rule.getAttributeContainer().getAttr("baz").toString();
-          if (!value.equals("")) {
-            return new AspectParameters.Builder().addAttribute("baz", value).build();
-          }
-        }
-        return AspectParameters.EMPTY;
-      }
-    }
-
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(
-              attr("foo", LABEL_LIST)
-                  .allowedFileTypes(FileTypeSet.ANY_FILE)
-                  .aspect(PARAMETRIZED_DEFINITION_ASPECT, new TestAspectParametersExtractor()))
-          .add(attr("baz", STRING))
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("parametrized_definition_aspect")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
 
   /**
    * A rule that defines an {@link ExtraAttributeAspectRequiringProvider} on one of its attributes.
    */
-  public static class ExtraAttributeAspectRequiringProviderRule implements RuleDefinition {
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
-              .aspect(EXTRA_ATTRIBUTE_ASPECT_REQUIRING_PROVIDER))
-          .build();
-
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("extra_attribute_aspect_requiring_provider")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule EXTRA_ATTRIBUTE_ASPECT_REQUIRING_PROVIDER_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "extra_attribute_aspect_requiring_provider",
+          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
+              .aspect(EXTRA_ATTRIBUTE_ASPECT_REQUIRING_PROVIDER));
 
   /**
    * A rule that defines an {@link AllAttributesAspect} on one of its attributes.
    */
-  public static class AllAttributesAspectRule implements RuleDefinition {
-
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
-              .aspect(ALL_ATTRIBUTES_ASPECT))
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("all_attributes_aspect")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule ALL_ATTRIBUTES_ASPECT_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "all_attributes_aspect",
+          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
+              .aspect(ALL_ATTRIBUTES_ASPECT));
 
   /** A rule that defines an {@link AllAttributesWithToolAspect} on one of its attributes. */
-  public static class AllAttributesWithToolAspectRule implements RuleDefinition {
-
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(
-              attr("foo", LABEL_LIST)
-                  .allowedFileTypes(FileTypeSet.ANY_FILE)
-                  .aspect(ALL_ATTRIBUTES_WITH_TOOL_ASPECT))
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("all_attributes_with_tool_aspect")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule ALL_ATTRIBUTES_WITH_TOOL_ASPECT_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "all_attributes_with_tool_aspect",
+           attr("foo", LABEL_LIST)
+               .allowedFileTypes(FileTypeSet.ANY_FILE)
+               .aspect(ALL_ATTRIBUTES_WITH_TOOL_ASPECT));
 
   /**
    * A rule that defines a {@link WarningAspect} on one of its attributes.
    */
-  public static class WarningAspectRule implements RuleDefinition {
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
-              .aspect(WARNING_ASPECT))
-          .add(attr("bar", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("warning_aspect")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule WARNING_ASPECT_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "warning_aspect",
+          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
+              .aspect(WARNING_ASPECT),
+          attr("bar", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE));
 
   /**
    * A rule that defines an {@link ErrorAspect} on one of its attributes.
    */
-  public static class ErrorAspectRule implements RuleDefinition {
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
-              .aspect(ERROR_ASPECT))
-          .add(attr("bar", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("error_aspect")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule ERROR_ASPECT_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "error_aspect",
+          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
+              .aspect(ERROR_ASPECT),
+          attr("bar", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE));
 
   /**
    * A simple rule that has an attribute.
    */
-  public static class SimpleRule implements RuleDefinition {
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
-          .add(attr("foo1", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE))
-          .add(attr("txt", STRING))
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("simple")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule SIMPLE_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "simple",
+          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE),
+          attr("foo1", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE),
+          attr("txt", STRING));
 
   /**
    * A rule that advertises a provider but doesn't implement it.
    */
-  public static class LiarRule implements RuleDefinition {
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
-          .advertiseProvider(RequiredProvider.class)
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("liar")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule LIAR_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "liar",
+          (builder, env) ->
+              builder
+                  .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
+                  .advertiseProvider(RequiredProvider.class));
 
   /**
    * A rule that advertises a provider and implements it.
    */
-  public static class HonestRule implements RuleDefinition {
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
-          .advertiseProvider(RequiredProvider.class)
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("honest")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule HONEST_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "honest",
+          (builder, env) ->
+              builder
+              .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
+              .advertiseProvider(RequiredProvider.class));
 
   /**
    * A rule that advertises another, different provider and implements it.
    */
-  public static class HonestRule2 implements RuleDefinition {
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
-          .advertiseProvider(RequiredProvider2.class)
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("honest2")
-          .factoryClass(DummyRuleFactory2.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
-
+  public static final MockRule HONEST_RULE_2 = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory2.class).define(
+          "honest2",
+          (builder, env) ->
+              builder
+                  .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
+                  .advertiseProvider(RequiredProvider2.class));
 
   /**
    * Rule with an implcit dependency.
    */
-  public static class ImplicitDepRule implements RuleDefinition {
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("$dep", LABEL).value(Label.parseAbsoluteUnchecked("//extra:extra")))
-          .build();
-    }
+  public static final MockRule IMPLICIT_DEP_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "implicit_dep",
+          attr("$dep", LABEL).value(Label.parseAbsoluteUnchecked("//extra:extra")));
 
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("implicit_dep")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  // TODO(b/65746853): provide a way to do this without passing the entire configuration
+  private static final LateBoundDefault<?, List<Label>> PLUGINS_LABEL_LIST =
+      LateBoundDefault.fromTargetConfiguration(
+          JavaConfiguration.class,
+          ImmutableList.of(),
+          (rule, attributes, javaConfig) -> javaConfig.getPlugins());
 
-  /**
-   * Rule with a late-bound dependency.
-   */
-  public static class LateBoundDepRule implements RuleDefinition {
-    private static final LateBoundDefault<?, List<Label>> PLUGINS_LABEL_LIST =
-        LateBoundDefault.fromTargetConfiguration(
-            JavaConfiguration.class,
-            ImmutableList.of(),
-            (rule, attributes, javaConfig) -> javaConfig.getPlugins());
-
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr(":plugins", LABEL_LIST).value(PLUGINS_LABEL_LIST))
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("late_bound_dep")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule LATE_BOUND_DEP_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "late_bound_dep",
+          attr(":plugins", LABEL_LIST).value(PLUGINS_LABEL_LIST));
 
   /**
    * Rule with {@link FalseAdvertisementAspect}
    */
-  public static final class FalseAdvertisementAspectRule implements RuleDefinition {
-
-    @Override
-    public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("deps", LABEL_LIST).allowedFileTypes().aspect(FALSE_ADVERTISEMENT_ASPECT))
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return  RuleDefinition.Metadata.builder()
-          .name("false_advertisement_aspect")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(BaseRule.class)
-          .build();
-    }
-  }
+  public static final MockRule FALSE_ADVERTISEMENT_ASPECT_RULE = () ->
+      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "false_advertisement_aspect",
+          attr("deps", LABEL_LIST).allowedFileTypes().aspect(FALSE_ADVERTISEMENT_ASPECT));
 
   /** Aspect that propagates over rule outputs. */
   public static class AspectApplyingToFiles extends NativeAspectClass
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ConfigurationsForTargetsWithTrimmedConfigurationsTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ConfigurationsForTargetsWithTrimmedConfigurationsTest.java
index da21b61..44fc925 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/ConfigurationsForTargetsWithTrimmedConfigurationsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ConfigurationsForTargetsWithTrimmedConfigurationsTest.java
@@ -26,7 +26,6 @@
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
 import com.google.devtools.build.lib.analysis.RuleDefinition;
-import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.analysis.config.BuildOptions;
 import com.google.devtools.build.lib.analysis.config.ConfigurationResolver;
@@ -43,7 +42,6 @@
 import com.google.devtools.build.lib.packages.Attribute.Transition;
 import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
 import com.google.devtools.build.lib.packages.Rule;
-import com.google.devtools.build.lib.packages.RuleClass;
 import com.google.devtools.build.lib.packages.RuleTransitionFactory;
 import com.google.devtools.build.lib.testutil.Suite;
 import com.google.devtools.build.lib.testutil.TestSpec;
@@ -109,88 +107,37 @@
   }
 
   /** Base rule that depends on the test configuration fragment. */
-  private static class TestBaseRule implements RuleDefinition {
-    @Override
-    public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
-      return builder.requiresConfigurationFragments(TestConfiguration.class).build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("test_base")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(TestAspects.BaseRule.class)
-          .build();
-    }
-  }
+  private static final MockRule TEST_BASE_RULE = () ->
+      MockRule.ancestor(TestAspects.BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "test_base",
+          (builder, env) ->
+              builder.requiresConfigurationFragments(TestConfiguration.class).build());
 
   /** A rule with an empty split transition on an attribute. */
-  private static class EmptySplitRule implements RuleDefinition {
-    @Override
-    public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(
-              attr("with_empty_transition", LABEL)
-                  .allowedFileTypes(FileTypeSet.ANY_FILE)
-                  .cfg(new EmptySplitTransition()))
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("empty_split")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(TestBaseRule.class)
-          .build();
-    }
-  }
+  private static final MockRule EMPTY_SPLIT_RULE = () ->
+      MockRule.ancestor(TEST_BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "empty_split",
+          attr("with_empty_transition", LABEL)
+              .allowedFileTypes(FileTypeSet.ANY_FILE)
+              .cfg(new EmptySplitTransition()));
 
   /** Rule with a split transition on an attribute. */
-  private static class AttributeTransitionRule implements RuleDefinition {
-
-    @Override
-    public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .add(attr("without_transition", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE))
-          .add(
-              attr("with_cpu_transition", LABEL)
-                  .allowedFileTypes(FileTypeSet.ANY_FILE)
-                  .cfg(new SetsCpuSplitTransition()))
-          .add(
-              attr("with_host_cpu_transition", LABEL)
-                  .allowedFileTypes(FileTypeSet.ANY_FILE)
-                  .cfg(new SetsHostCpuSplitTransition()))
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("attribute_transition")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(TestBaseRule.class)
-          .build();
-    }
-  }
+  private static final MockRule ATTRIBUTE_TRANSITION_RULE = () ->
+      MockRule.ancestor(TEST_BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "attribute_transition",
+          attr("without_transition", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE),
+          attr("with_cpu_transition", LABEL)
+              .allowedFileTypes(FileTypeSet.ANY_FILE)
+              .cfg(new SetsCpuSplitTransition()),
+          attr("with_host_cpu_transition", LABEL)
+              .allowedFileTypes(FileTypeSet.ANY_FILE)
+              .cfg(new SetsHostCpuSplitTransition()));
 
   /** Rule with rule class configuration transition. */
-  private static class RuleClassTransitionRule implements RuleDefinition {
-    @Override
-    public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
-      return builder.cfg(new SetsCpuPatchTransition()).build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("rule_class_transition")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(TestBaseRule.class)
-          .build();
-    }
-  }
+  private static final MockRule RULE_CLASS_TRANSITION_RULE = () ->
+      MockRule.ancestor(TEST_BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "rule_class_transition",
+          (builder, env) -> builder.cfg(new SetsCpuPatchTransition()).build());
 
   private static class SetsTestFilterFromAttributePatchTransition implements PatchTransition {
     private final String value;
@@ -224,35 +171,20 @@
   /**
    * Rule with a RuleTransitionFactory which sets the --test_filter flag according to its attribute.
    */
-  private static class UsesRuleTransitionFactoryRule implements RuleDefinition {
-    @Override
-    public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
-      return builder
-          .cfg(new SetsTestFilterFromAttributeTransitionFactory())
-          .add(
-              attr("sets_test_filter_to", STRING)
-                  .nonconfigurable("used in RuleTransitionFactory")
-                  .value(""))
-          .build();
-    }
-
-    @Override
-    public Metadata getMetadata() {
-      return RuleDefinition.Metadata.builder()
-          .name("uses_rule_transition_factory")
-          .factoryClass(DummyRuleFactory.class)
-          .ancestors(TestBaseRule.class)
-          .build();
-    }
-  }
+  private static final MockRule USES_RULE_TRANSITION_FACTORY_RULE = () ->
+      MockRule.ancestor(TEST_BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
+          "uses_rule_transition_factory",
+          (builder, env) ->
+              builder
+                  .cfg(new SetsTestFilterFromAttributeTransitionFactory())
+                  .add(attr("sets_test_filter_to", STRING)
+                      .nonconfigurable("used in RuleTransitionFactory")
+                      .value("")));
 
   @Test
   public void testRuleClassTransition() throws Exception {
-    setRulesAvailableInTests(
-        new TestAspects.BaseRule(),
-        new TestBaseRule(),
-        new AttributeTransitionRule(),
-        new RuleClassTransitionRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, ATTRIBUTE_TRANSITION_RULE,
+        RULE_CLASS_TRANSITION_RULE);
     scratch.file("a/BUILD",
         "attribute_transition(",
         "   name='attribute',",
@@ -266,11 +198,8 @@
 
   @Test
   public void testNonConflictingAttributeAndRuleClassTransitions() throws Exception {
-    setRulesAvailableInTests(
-        new TestAspects.BaseRule(),
-        new TestBaseRule(),
-        new AttributeTransitionRule(),
-        new RuleClassTransitionRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, ATTRIBUTE_TRANSITION_RULE,
+        RULE_CLASS_TRANSITION_RULE);
     scratch.file("a/BUILD",
         "attribute_transition(",
         "   name='attribute',",
@@ -285,11 +214,8 @@
 
   @Test
   public void testConflictingAttributeAndRuleClassTransitions() throws Exception {
-    setRulesAvailableInTests(
-        new TestAspects.BaseRule(),
-        new TestBaseRule(),
-        new AttributeTransitionRule(),
-        new RuleClassTransitionRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, ATTRIBUTE_TRANSITION_RULE,
+        RULE_CLASS_TRANSITION_RULE);
     scratch.file("a/BUILD",
         "attribute_transition(",
         "   name='attribute',",
@@ -303,11 +229,8 @@
 
   @Test
   public void testEmptySplitDoesNotSuppressRuleClassTransition() throws Exception {
-    setRulesAvailableInTests(
-        new TestAspects.BaseRule(),
-        new TestBaseRule(),
-        new EmptySplitRule(),
-        new RuleClassTransitionRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, EMPTY_SPLIT_RULE,
+        RULE_CLASS_TRANSITION_RULE);
     scratch.file(
         "a/BUILD",
         "empty_split(",
@@ -322,8 +245,7 @@
 
   @Test
   public void testTopLevelRuleClassTransition() throws Exception {
-    setRulesAvailableInTests(
-        new TestAspects.BaseRule(), new TestBaseRule(), new RuleClassTransitionRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, RULE_CLASS_TRANSITION_RULE);
     scratch.file(
         "a/BUILD",
         "rule_class_transition(",
@@ -336,11 +258,8 @@
 
   @Test
   public void testTopLevelRuleClassTransitionAndNoTransition() throws Exception {
-    setRulesAvailableInTests(
-        new TestAspects.BaseRule(),
-        new TestBaseRule(),
-        new RuleClassTransitionRule(),
-        new TestAspects.SimpleRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, RULE_CLASS_TRANSITION_RULE,
+        TestAspects.SIMPLE_RULE);
     scratch.file(
         "a/BUILD",
         "rule_class_transition(",
@@ -355,11 +274,8 @@
   @Test
   public void ruleTransitionFactoryUsesNonconfigurableAttributesToGenerateTransition()
       throws Exception {
-    setRulesAvailableInTests(
-        new TestAspects.BaseRule(),
-        new TestBaseRule(),
-        new AttributeTransitionRule(),
-        new UsesRuleTransitionFactoryRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, ATTRIBUTE_TRANSITION_RULE,
+        USES_RULE_TRANSITION_FACTORY_RULE);
     useConfiguration("--test_filter=SET ON COMMAND LINE: original and best");
     scratch.file(
         "a/BUILD",
@@ -379,11 +295,8 @@
 
   @Test
   public void ruleTransitionFactoryCanReturnNullToCauseNoTransition() throws Exception {
-    setRulesAvailableInTests(
-        new TestAspects.BaseRule(),
-        new TestBaseRule(),
-        new AttributeTransitionRule(),
-        new UsesRuleTransitionFactoryRule());
+    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, ATTRIBUTE_TRANSITION_RULE,
+        USES_RULE_TRANSITION_FACTORY_RULE);
     useConfiguration("--test_filter=SET ON COMMAND LINE: original and best");
     scratch.file(
         "a/BUILD",
@@ -404,7 +317,7 @@
   @Test
   public void topLevelRuleTransitionFactoryUsesNonconfigurableAttributes() throws Exception {
     setRulesAvailableInTests(
-        new TestAspects.BaseRule(), new TestBaseRule(), new UsesRuleTransitionFactoryRule());
+        TestAspects.BASE_RULE, TEST_BASE_RULE, USES_RULE_TRANSITION_FACTORY_RULE);
     useConfiguration("--test_filter=SET ON COMMAND LINE: original and best");
     scratch.file(
         "a/BUILD",
@@ -420,7 +333,7 @@
   @Test
   public void topLevelRuleTransitionFactoryCanReturnNullInTesting() throws Exception {
     setRulesAvailableInTests(
-        new TestAspects.BaseRule(), new TestBaseRule(), new UsesRuleTransitionFactoryRule());
+        TestAspects.BASE_RULE, TEST_BASE_RULE, USES_RULE_TRANSITION_FACTORY_RULE);
     useConfiguration("--test_filter=SET ON COMMAND LINE: original and best");
     scratch.file(
         "a/BUILD",