Optimize how null configurations get created and add test infrastructure for Bazel's dep configuration creation logic.

This essentially implements the following TODOs:

https://github.com/bazelbuild/bazel/blob/bc6045dcc8fa33d4241d231138020ac4bdecc14f/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java#L599
https://github.com/bazelbuild/bazel/blob/bc6045dcc8fa33d4241d231138020ac4bdecc14f/src/test/java/com/google/devtools/build/lib/skyframe/ConfigurationsForTargetsTest.java#L42

--
MOS_MIGRATED_REVID=134607049
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 d498709..2d50ef7 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
@@ -32,6 +32,8 @@
 import com.google.devtools.build.lib.packages.NoSuchTargetException;
 import com.google.devtools.build.lib.packages.NoSuchThingException;
 import com.google.devtools.build.lib.packages.Target;
+import com.google.devtools.build.lib.testutil.Suite;
+import com.google.devtools.build.lib.testutil.TestSpec;
 import com.google.devtools.build.lib.util.OrderedSetMultimap;
 import java.util.List;
 import java.util.Set;
@@ -109,7 +111,7 @@
   }
 
   @SafeVarargs
-  private final void assertDep(
+  private final Dependency assertDep(
       OrderedSetMultimap<Attribute, Dependency> dependentNodeMap,
       String attrName,
       String dep,
@@ -133,6 +135,7 @@
 
     assertNotNull("Dependency '" + dep + "' on attribute '" + attrName + "' not found", dependency);
     assertThat(dependency.getAspects()).containsExactly((Object[]) aspects);
+    return dependency;
   }
 
   @Test
@@ -182,4 +185,39 @@
         dependentNodeMap("//a:a", TestAspects.EXTRA_ATTRIBUTE_ASPECT);
     assertDep(map, "$dep", "//extra:extra");
   }
+
+  /**
+   * Null configurations should be static whether we're building with static or dynamic
+   * configurations. This is because the dynamic config logic that translates transitions into
+   * final configurations can be trivially skipped in those cases.
+   */
+  @Test
+  public void nullConfigurationsAlwaysStatic() throws Exception {
+    pkg("a",
+        "genrule(name = 'gen', srcs = ['gen.in'], cmd = '', outs = ['gen.out'])");
+    update();
+    Dependency dep = assertDep(dependentNodeMap("//a:gen", null), "srcs", "//a:gen.in");
+    assertThat(dep.hasStaticConfiguration()).isTrue();
+    assertThat(dep.getConfiguration()).isNull();
+  }
+
+  /** Runs the same test with trimmed dynamic configurations. */
+  @TestSpec(size = Suite.SMALL_TESTS)
+  @RunWith(JUnit4.class)
+  public static class WithDynamicConfigurations extends DependencyResolverTest {
+    @Override
+    protected FlagBuilder defaultFlags() {
+      return super.defaultFlags().with(Flag.DYNAMIC_CONFIGURATIONS);
+    }
+  }
+
+  /** Runs the same test with untrimmed dynamic configurations. */
+  @TestSpec(size = Suite.SMALL_TESTS)
+  @RunWith(JUnit4.class)
+  public static class WithDynamicConfigurationsNoTrim extends DependencyResolverTest {
+    @Override
+    protected FlagBuilder defaultFlags() {
+      return super.defaultFlags().with(Flag.DYNAMIC_CONFIGURATIONS_NOTRIM);
+    }
+  }
 }