From 4db3bab8b8dd86112c5df011e32622171e575477 Mon Sep 17 00:00:00 2001 From: Luca Di Grazia Date: Sun, 4 Sep 2022 15:56:47 +0200 Subject: [PATCH] bzlmod: Remove overrides from DiscoveryValue and SelectionValue (https://github.com/bazelbuild/bazel/issues/13316) The overrides cannot be nicely encapsulated in SelectionValue because we need the overrides when fetching modules with non-registry overrides, which happens during discovery. Any consumers of overrides should get them from the ModuleFileValue of the root module directly instead. PiperOrigin-RevId: 384236547 --- .../lib/bazel/bzlmod/DiscoveryFunction.java | 12 +- .../lib/bazel/bzlmod/DiscoveryValue.java | 8 +- .../lib/bazel/bzlmod/SelectionFunction.java | 257 +--- .../lib/bazel/bzlmod/SelectionValue.java | 18 +- .../bazel/bzlmod/DiscoveryFunctionTest.java | 236 +--- .../bazel/bzlmod/SelectionFunctionTest.java | 1106 +++-------------- 6 files changed, 260 insertions(+), 1377 deletions(-) diff --git a/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/DiscoveryFunction.java b/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/DiscoveryFunction.java index 6bb81bf2bce..4ee86d516a3 100644 --- a/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/DiscoveryFunction.java +++ b/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/DiscoveryFunction.java @@ -16,7 +16,6 @@ package com.google.devtools.build.lib.bazel.bzlmod; import com.google.common.collect.ImmutableMap; -import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileValue.RootModuleFileValue; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionException; import com.google.devtools.build.skyframe.SkyKey; @@ -40,12 +39,11 @@ public class DiscoveryFunction implements SkyFunction { @Override public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, InterruptedException { - RootModuleFileValue root = - (RootModuleFileValue) env.getValue(ModuleFileValue.keyForRootModule()); + ModuleFileValue root = (ModuleFileValue) env.getValue(ModuleFileValue.keyForRootModule()); if (root == null) { return null; } - ModuleKey rootModuleKey = ModuleKey.create(root.getModule().getName(), Version.EMPTY); + ModuleKey rootModuleKey = ModuleKey.create(root.getModule().getName(), ""); ImmutableMap overrides = root.getOverrides(); Map depGraph = new HashMap<>(); depGraph.put( @@ -88,13 +86,13 @@ private static Module rewriteDepKeys( Module module, ImmutableMap overrides, String rootModuleName) { return module.withDepKeysTransformed( depKey -> { - Version newVersion = depKey.getVersion(); + String newVersion = depKey.getVersion(); @Nullable ModuleOverride override = overrides.get(depKey.getName()); if (override instanceof NonRegistryOverride || rootModuleName.equals(depKey.getName())) { - newVersion = Version.EMPTY; + newVersion = ""; } else if (override instanceof SingleVersionOverride) { - Version overrideVersion = ((SingleVersionOverride) override).getVersion(); + String overrideVersion = ((SingleVersionOverride) override).getVersion(); if (!overrideVersion.isEmpty()) { newVersion = overrideVersion; } diff --git a/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/DiscoveryValue.java b/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/DiscoveryValue.java index 1eb0b44b9b7..585e6c61b21 100644 --- a/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/DiscoveryValue.java +++ b/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/DiscoveryValue.java @@ -29,15 +29,11 @@ public abstract class DiscoveryValue implements SkyValue { @AutoCodec public static final SkyKey KEY = () -> SkyFunctions.DISCOVERY; public static DiscoveryValue create( - String rootModuleName, - ImmutableMap depGraph, - ImmutableMap overrides) { - return new AutoValue_DiscoveryValue(rootModuleName, depGraph, overrides); + String rootModuleName, ImmutableMap depGraph) { + return new AutoValue_DiscoveryValue(rootModuleName, depGraph); } public abstract String getRootModuleName(); public abstract ImmutableMap getDepGraph(); - - public abstract ImmutableMap getOverrides(); } diff --git a/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionFunction.java b/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionFunction.java index 6c0880276d3..6f4ff5f5fc1 100644 --- a/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionFunction.java +++ b/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionFunction.java @@ -16,13 +16,8 @@ package com.google.devtools.build.lib.bazel.bzlmod; import com.google.auto.value.AutoValue; -import com.google.common.base.Joiner; import com.google.common.base.Preconditions; -import com.google.common.collect.Comparators; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSortedSet; -import com.google.common.collect.Maps; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionException; import com.google.devtools.build.skyframe.SkyKey; @@ -35,57 +30,15 @@ * Runs module selection. This step of module resolution reads the output of {@link * DiscoveryFunction} and applies the Minimal Version Selection algorithm to it, removing unselected * modules from the dependency graph and rewriting dependencies to point to the selected versions. - * - *

Essentially, what needs to happen is: - * - *

    - *
  • In the most basic case, only one version of each module is selected (ie. remains in the dep - * graph). The selected version is simply the highest among all existing versions in the dep - * graph. In other words, each module name forms a "selection group". If foo@1.5 is selected, - * then any other foo@X is removed from the dep graph, and any module depending on foo@X will - * depend on foo@1.5 instead. - *
  • As an extension of the above, we also remove any module that becomes unreachable from the - * root module because of the removal of some other module. - *
  • If, however, versions of the same module but with different compatibility levels exist in - * the dep graph, then one version is selected for each compatibility level (ie. we split the - * selection groups by compatibility level). In the end, though, still only one version can - * remain in the dep graph after the removal of unselected and unreachable modules. - *
  • Things get more complicated with multiple-version overrides. If module foo has a - * multiple-version override which allows version [1.3, 1.5, 2.0] (using the major version as - * the compatibility level), then we further split the selection groups by the target allowed - * version (keep in mind that versions are upgraded to the nearest higher-or-equal allowed - * version at the same compatibility level). If, for example, some module depends on foo@1.0, - * then it'll depend on foo@1.3 post-selection instead (and foo@1.0 will be removed). If any - * of foo@1.7, foo@2.2, or foo@3.0 exist in the dependency graph before selection, they must - * be removed before the end of selection (by becoming unreachable, for example), otherwise - * it'll be an error since they're not allowed by the override (these versions are in - * selection groups that have no valid target allowed version). - *
*/ public class SelectionFunction implements SkyFunction { /** During selection, a version is selected for each distinct "selection group". */ @AutoValue abstract static class SelectionGroup { - static SelectionGroup create( - String moduleName, int compatibilityLevel, Version targetAllowedVersion) { + static SelectionGroup of(Module module) { return new AutoValue_SelectionFunction_SelectionGroup( - moduleName, compatibilityLevel, targetAllowedVersion); - } - - abstract String getModuleName(); - - abstract int getCompatibilityLevel(); - - /** This is only used for modules with multiple-version overrides. */ - abstract Version getTargetAllowedVersion(); - } - - @AutoValue - abstract static class ModuleNameAndCompatibilityLevel { - static ModuleNameAndCompatibilityLevel create(String moduleName, int compatibilityLevel) { - return new AutoValue_SelectionFunction_ModuleNameAndCompatibilityLevel( - moduleName, compatibilityLevel); + module.getName(), module.getCompatibilityLevel()); } abstract String getModuleName(); @@ -93,74 +46,6 @@ static ModuleNameAndCompatibilityLevel create(String moduleName, int compatibili abstract int getCompatibilityLevel(); } - /** - * Computes a mapping from (moduleName, compatibilityLevel) to the set of allowed versions. This - * is only performed for modules with multiple-version overrides. - */ - private static ImmutableMap> - computeAllowedVersionSets( - ImmutableMap overrides, ImmutableMap depGraph) - throws SelectionException { - Map> allowedVersionSets = - new HashMap<>(); - for (Map.Entry overrideEntry : overrides.entrySet()) { - String moduleName = overrideEntry.getKey(); - ModuleOverride override = overrideEntry.getValue(); - if (!(override instanceof MultipleVersionOverride)) { - continue; - } - ImmutableList allowedVersions = ((MultipleVersionOverride) override).getVersions(); - for (Version allowedVersion : allowedVersions) { - Module allowedVersionModule = depGraph.get(ModuleKey.create(moduleName, allowedVersion)); - if (allowedVersionModule == null) { - throw new SelectionException( - String.format( - "multiple_version_override for module %s contains version %s, but it doesn't" - + " exist in the dependency graph", - moduleName, allowedVersion)); - } - ImmutableSortedSet.Builder allowedVersionSet = - allowedVersionSets.computeIfAbsent( - ModuleNameAndCompatibilityLevel.create( - moduleName, allowedVersionModule.getCompatibilityLevel()), - // Remember that the empty version compares greater than any other version, so we - // can use it as a sentinel value. - k -> ImmutableSortedSet.naturalOrder().add(Version.EMPTY)); - allowedVersionSet.add(allowedVersion); - } - } - return ImmutableMap.copyOf( - Maps.transformValues(allowedVersionSets, ImmutableSortedSet.Builder::build)); - } - - /** - * Computes the {@link SelectionGroup} for the given module. If the module has a multiple-version - * override (which would be reflected in the allowedVersionSets), information in there will be - * used to compute its targetAllowedVersion. - */ - private static SelectionGroup computeSelectionGroup( - Module module, - ImmutableMap> - allowedVersionSets) { - ImmutableSortedSet allowedVersionSet = - allowedVersionSets.get( - ModuleNameAndCompatibilityLevel.create( - module.getName(), module.getCompatibilityLevel())); - if (allowedVersionSet == null) { - // This means that this module has no multiple-version override. - return SelectionGroup.create(module.getName(), module.getCompatibilityLevel(), Version.EMPTY); - } - return SelectionGroup.create( - module.getName(), - module.getCompatibilityLevel(), - // We use the `ceiling` method here to quickly locate the lowest allowed version that's - // still no lower than this module's version. - // If this module's version is higher than any allowed version (in which case EMPTY is - // returned), it should result in an error. We don't immediately throw here because it might - // still become unreferenced later. - allowedVersionSet.ceiling(module.getVersion())); - } - @Override public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, InterruptedException { @@ -168,47 +53,33 @@ public SkyValue compute(SkyKey skyKey, Environment env) if (discovery == null) { return null; } - ImmutableMap depGraph = discovery.getDepGraph(); - ModuleFileValue rootModule = (ModuleFileValue) env.getValue(ModuleFileValue.keyForRootModule()); - if (rootModule == null) { - return null; - } - ImmutableMap overrides = rootModule.getOverrides(); - - // For any multiple-version overrides, build a mapping from (moduleName, compatibilityLevel) to - // the set of allowed versions. - ImmutableMap> allowedVersionSets; - try { - allowedVersionSets = computeAllowedVersionSets(overrides, depGraph); - } catch (SelectionException e) { - throw new SelectionFunctionException(e); - } - // For each module in the dep graph, pre-compute its selection group. For most modules this is - // simply its (moduleName, compatibilityLevel) tuple; for modules with multiple-version - // overrides, it additionally includes the targetAllowedVersion, which denotes the version to - // "snap" to during selection. - ImmutableMap selectionGroups = - ImmutableMap.copyOf( - Maps.transformValues( - depGraph, module -> computeSelectionGroup(module, allowedVersionSets))); + // TODO(wyv): multiple_version_override - // Figure out the version to select for every selection group. - Map selectedVersions = new HashMap<>(); - for (Map.Entry entry : selectionGroups.entrySet()) { + // First figure out the version to select for every selection group. + ImmutableMap depGraph = discovery.getDepGraph(); + Map selectedVersions = new HashMap<>(); + for (Map.Entry entry : depGraph.entrySet()) { ModuleKey key = entry.getKey(); - SelectionGroup selectionGroup = entry.getValue(); - selectedVersions.merge(selectionGroup, key.getVersion(), Comparators::max); + Module module = entry.getValue(); + + ParsedVersion parsedVersion; + try { + parsedVersion = ParsedVersion.parse(key.getVersion()); + } catch (ParsedVersion.ParseException e) { + throw new SelectionFunctionException(e); + } + selectedVersions.merge(SelectionGroup.of(module), parsedVersion, ParsedVersion::max); } - // Build a new dep graph where deps with unselected versions are removed. + // Now build a new dep graph where deps with unselected versions are removed. ImmutableMap.Builder newDepGraphBuilder = new ImmutableMap.Builder<>(); for (Map.Entry entry : depGraph.entrySet()) { ModuleKey moduleKey = entry.getKey(); Module module = entry.getValue(); // Remove any dep whose version isn't selected. - Version selectedVersion = selectedVersions.get(selectionGroups.get(moduleKey)); + String selectedVersion = selectedVersions.get(SelectionGroup.of(module)).getOriginal(); if (!moduleKey.getVersion().equals(selectedVersion)) { continue; } @@ -219,7 +90,10 @@ public SkyValue compute(SkyKey skyKey, Environment env) module.withDepKeysTransformed( depKey -> ModuleKey.create( - depKey.getName(), selectedVersions.get(selectionGroups.get(depKey))))); + depKey.getName(), + selectedVersions + .get(SelectionGroup.of(depGraph.get(depKey))) + .getOriginal()))); } ImmutableMap newDepGraph = newDepGraphBuilder.build(); @@ -228,9 +102,9 @@ public SkyValue compute(SkyKey skyKey, Environment env) // We can also take this opportunity to check that none of the remaining modules conflict with // each other (e.g. same module name but different compatibility levels, or not satisfying // multiple_version_override). - DepGraphWalker walker = new DepGraphWalker(newDepGraph, overrides, selectionGroups); + DepGraphWalker walker = new DepGraphWalker(newDepGraph); try { - walker.walk(ModuleKey.create(discovery.getRootModuleName(), Version.EMPTY), null); + walker.walk(ModuleKey.create(discovery.getRootModuleName(), ""), null); } catch (SelectionException e) { throw new SelectionFunctionException(e); } @@ -243,20 +117,12 @@ public SkyValue compute(SkyKey skyKey, Environment env) * a new dep graph and checking that nothing conflicts. */ static class DepGraphWalker { - private static final Joiner JOINER = Joiner.on(", "); private final ImmutableMap oldDepGraph; - private final ImmutableMap overrides; - private final ImmutableMap selectionGroups; private final HashMap newDepGraph; private final HashMap moduleByName; - DepGraphWalker( - ImmutableMap oldDepGraph, - ImmutableMap overrides, - ImmutableMap selectionGroups) { + DepGraphWalker(ImmutableMap oldDepGraph) { this.oldDepGraph = oldDepGraph; - this.overrides = overrides; - this.selectionGroups = selectionGroups; this.newDepGraph = new HashMap<>(); this.moduleByName = new HashMap<>(); } @@ -272,62 +138,27 @@ void walk(ModuleKey key, @Nullable ModuleKey from) throws SelectionException { Module module = oldDepGraph.get(key); newDepGraph.put(key, module); - ModuleOverride override = overrides.get(key.getName()); - if (override instanceof MultipleVersionOverride) { - if (selectionGroups.get(key).getTargetAllowedVersion().isEmpty()) { - // This module has no target allowed version, which means that there's no allowed version - // higher than its version at the same compatibility level. - Preconditions.checkState( - from != null, "the root module cannot have a multiple version override"); - throw new SelectionException( - String.format( - "%s depends on %s which is not allowed by the multiple_version_override on %s," - + " which allows only [%s]", - from, - key, - key.getName(), - JOINER.join(((MultipleVersionOverride) override).getVersions()))); - } - } else { - ExistingModule existingModuleWithSameName = - moduleByName.put( - module.getName(), ExistingModule.create(key, module.getCompatibilityLevel(), from)); - if (existingModuleWithSameName != null) { - // This has to mean that a module with the same name but a different compatibility level - // was also selected. - Preconditions.checkState( - from != null && existingModuleWithSameName.getDependent() != null, - "the root module cannot possibly exist more than once in the dep graph"); - throw new SelectionException( - String.format( - "%s depends on %s with compatibility level %d, but %s depends on %s with" - + " compatibility level %d which is different", - from, - key, - module.getCompatibilityLevel(), - existingModuleWithSameName.getDependent(), - existingModuleWithSameName.getModuleKey(), - existingModuleWithSameName.getCompatibilityLevel())); - } - } - - // Make sure that we don't have `module` depending on the same dependency version twice. - HashMap depKeyToRepoName = new HashMap<>(); - for (Map.Entry depEntry : module.getDeps().entrySet()) { - String repoName = depEntry.getKey(); - ModuleKey depKey = depEntry.getValue(); - String previousRepoName = depKeyToRepoName.put(depKey, repoName); - if (previousRepoName != null) { - throw new SelectionException( - String.format( - "%s depends on %s at least twice (with repo names %s and %s). Consider adding a" - + " multiple_version_override if you want to depend on multiple versions of" - + " %s simultaneously", - key, depKey, repoName, previousRepoName, key.getName())); - } + ExistingModule existingModuleWithSameName = + moduleByName.put( + module.getName(), ExistingModule.create(key, module.getCompatibilityLevel(), from)); + if (existingModuleWithSameName != null) { + // This has to mean that a module with the same name but a different compatibility level was + // also selected. + Preconditions.checkState( + from != null && existingModuleWithSameName.getDependent() != null, + "the root module cannot possibly exist more than once in the dep graph"); + throw new SelectionException( + String.format( + "%s depends on %s with compatibility level %d, but %s depends on %s with" + + " compatibility level %d which is different", + from, + key, + module.getCompatibilityLevel(), + existingModuleWithSameName.getDependent(), + existingModuleWithSameName.getModuleKey(), + existingModuleWithSameName.getCompatibilityLevel())); } - // Now visit our dependencies. for (ModuleKey depKey : module.getDeps().values()) { walk(depKey, key); } diff --git a/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionValue.java b/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionValue.java index 2f9b6eb29c6..398f0458c1e 100644 --- a/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionValue.java +++ b/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionValue.java @@ -29,25 +29,11 @@ public abstract class SelectionValue implements SkyValue { @AutoCodec public static final SkyKey KEY = () -> SkyFunctions.SELECTION; public static SelectionValue create( - String rootModuleName, - ImmutableMap depGraph, - ImmutableMap canonicalRepoNameLookup, - ImmutableMap moduleNameLookup) { - return new AutoValue_SelectionValue( - rootModuleName, depGraph, canonicalRepoNameLookup, moduleNameLookup); + String rootModuleName, ImmutableMap depGraph) { + return new AutoValue_SelectionValue(rootModuleName, depGraph); } public abstract String getRootModuleName(); - /** The post-selection dep graph. */ public abstract ImmutableMap getDepGraph(); - - /** A mapping from a canonical repo name to the key of the module backing it. */ - public abstract ImmutableMap getCanonicalRepoNameLookup(); - - /** - * A mapping from a plain module name to the key of the module (only works for modules without - * multiple-version overrides). - */ - public abstract ImmutableMap getModuleNameLookup(); } diff --git a/dataset/GitHub_Java/bazelbuild.bazel/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/DiscoveryFunctionTest.java b/dataset/GitHub_Java/bazelbuild.bazel/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/DiscoveryFunctionTest.java index 2248fff896a..6b0dbcd2d85 100644 --- a/dataset/GitHub_Java/bazelbuild.bazel/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/DiscoveryFunctionTest.java +++ b/dataset/GitHub_Java/bazelbuild.bazel/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/DiscoveryFunctionTest.java @@ -16,38 +16,25 @@ package com.google.devtools.build.lib.bazel.bzlmod; import static com.google.common.truth.Truth.assertThat; -import static com.google.devtools.build.lib.bazel.bzlmod.BzlmodTestUtil.createModuleKey; import static org.junit.Assert.fail; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.actions.FileStateValue; import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; -import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.ServerDirectories; import com.google.devtools.build.lib.analysis.util.AnalysisMock; -import com.google.devtools.build.lib.bazel.repository.starlark.StarlarkRepositoryModule; -import com.google.devtools.build.lib.packages.PackageFactory; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; -import com.google.devtools.build.lib.rules.repository.LocalRepositoryFunction; -import com.google.devtools.build.lib.rules.repository.LocalRepositoryRule; -import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction; -import com.google.devtools.build.lib.rules.repository.RepositoryFunction; import com.google.devtools.build.lib.skyframe.BazelSkyframeExecutorConstants; -import com.google.devtools.build.lib.skyframe.BzlmodRepoRuleFunction; import com.google.devtools.build.lib.skyframe.ExternalFilesHelper; import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction; import com.google.devtools.build.lib.skyframe.FileFunction; import com.google.devtools.build.lib.skyframe.FileStateFunction; -import com.google.devtools.build.lib.skyframe.ManagedDirectoriesKnowledge; import com.google.devtools.build.lib.skyframe.PrecomputedFunction; import com.google.devtools.build.lib.skyframe.PrecomputedValue; import com.google.devtools.build.lib.skyframe.SkyFunctions; -import com.google.devtools.build.lib.starlarkbuildapi.repository.RepositoryBootstrap; import com.google.devtools.build.lib.testutil.FoundationTestCase; -import com.google.devtools.build.lib.testutil.TestRuleClassProvider; import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.Root; @@ -61,8 +48,6 @@ import com.google.devtools.build.skyframe.SequentialBuildDriver; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionName; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import net.starlark.java.eval.StarlarkSemantics; import org.junit.Before; @@ -104,20 +89,7 @@ public void setup() throws Exception { packageLocator, ExternalFileAction.DEPEND_ON_EXTERNAL_PKG_FOR_EXTERNAL_REPO_PATHS, directories); - ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder(); - TestRuleClassProvider.addStandardRules(builder); - builder - .clearWorkspaceFileSuffixForTesting() - .addStarlarkBootstrap(new RepositoryBootstrap(new StarlarkRepositoryModule())); - ConfiguredRuleClassProvider ruleClassProvider = builder.build(); - PackageFactory packageFactory = - AnalysisMock.get() - .getPackageFactoryBuilderForTesting(directories) - .build(ruleClassProvider, fileSystem); - - ImmutableMap repositoryHandlers = - ImmutableMap.of(LocalRepositoryRule.NAME, new LocalRepositoryFunction()); MemoizingEvaluator evaluator = new InMemoryMemoizingEvaluator( ImmutableMap.builder() @@ -133,39 +105,11 @@ public void setup() throws Exception { SkyFunctions.MODULE_FILE, new ModuleFileFunction(registryFactory, workspaceRoot)) .put(SkyFunctions.PRECOMPUTED, new PrecomputedFunction()) - .put( - SkyFunctions.REPOSITORY_DIRECTORY, - new RepositoryDelegatorFunction( - repositoryHandlers, - null, - new AtomicBoolean(true), - ImmutableMap::of, - directories, - ManagedDirectoriesKnowledge.NO_MANAGED_DIRECTORIES, - BazelSkyframeExecutorConstants.EXTERNAL_PACKAGE_HELPER)) - .put( - BzlmodRepoRuleValue.BZLMOD_REPO_RULE, - new BzlmodRepoRuleFunction( - packageFactory, - ruleClassProvider, - directories, - new BzlmodRepoRuleHelperImpl())) .build(), differencer); driver = new SequentialBuildDriver(evaluator); PrecomputedValue.STARLARK_SEMANTICS.set(differencer, StarlarkSemantics.DEFAULT); - RepositoryDelegatorFunction.REPOSITORY_OVERRIDES.set(differencer, ImmutableMap.of()); - RepositoryDelegatorFunction.DEPENDENCY_FOR_UNCONDITIONAL_FETCHING.set( - differencer, RepositoryDelegatorFunction.DONT_FETCH_UNCONDITIONALLY); - PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, packageLocator.get()); - RepositoryDelegatorFunction.RESOLVED_FILE_INSTEAD_OF_WORKSPACE.set( - differencer, Optional.empty()); - PrecomputedValue.REPO_ENV.set(differencer, ImmutableMap.of()); - RepositoryDelegatorFunction.OUTPUT_VERIFICATION_REPOSITORY_RULES.set( - differencer, ImmutableSet.of()); - RepositoryDelegatorFunction.RESOLVED_FILE_FOR_VERIFICATION.set(differencer, Optional.empty()); - RepositoryDelegatorFunction.ENABLE_BZLMOD.set(differencer, true); } @Test @@ -177,14 +121,14 @@ public void testSimpleDiamond() throws Exception { "bazel_dep(name='C',version='2.0')"); FakeRegistry registry = registryFactory - .newFakeRegistry("/foo") + .newFakeRegistry() .addModule( - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), "module(name='B', version='1.0');bazel_dep(name='D',version='3.0')") .addModule( - createModuleKey("C", "2.0"), + ModuleKey.create("C", "2.0"), "module(name='C', version='2.0');bazel_dep(name='D',version='3.0')") - .addModule(createModuleKey("D", "3.0"), "module(name='D', version='3.0')"); + .addModule(ModuleKey.create("D", "3.0"), "module(name='D', version='3.0')"); ModuleFileFunction.REGISTRIES.set(differencer, ImmutableList.of(registry.getUrl())); EvaluationResult result = @@ -196,33 +140,29 @@ public void testSimpleDiamond() throws Exception { assertThat(discoveryValue.getRootModuleName()).isEqualTo("A"); assertThat(discoveryValue.getDepGraph()) .containsExactly( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.parse("0.1")) - .addDep("B", createModuleKey("B", "1.0")) - .addDep("C", createModuleKey("C", "2.0")) + .setVersion("0.1") + .addDep("B", ModuleKey.create("B", "1.0")) + .addDep("C", ModuleKey.create("C", "2.0")) .build(), - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), Module.builder() .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("D", createModuleKey("D", "3.0")) + .setVersion("1.0") + .addDep("D", ModuleKey.create("D", "3.0")) .setRegistry(registry) .build(), - createModuleKey("C", "2.0"), + ModuleKey.create("C", "2.0"), Module.builder() .setName("C") - .setVersion(Version.parse("2.0")) - .addDep("D", createModuleKey("D", "3.0")) + .setVersion("2.0") + .addDep("D", ModuleKey.create("D", "3.0")) .setRegistry(registry) .build(), - createModuleKey("D", "3.0"), - Module.builder() - .setName("D") - .setVersion(Version.parse("3.0")) - .setRegistry(registry) - .build()); + ModuleKey.create("D", "3.0"), + Module.builder().setName("D").setVersion("3.0").setRegistry(registry).build()); } @Test @@ -233,12 +173,12 @@ public void testCircularDependency() throws Exception { "bazel_dep(name='B',version='1.0')"); FakeRegistry registry = registryFactory - .newFakeRegistry("/foo") + .newFakeRegistry() .addModule( - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), "module(name='B', version='1.0');bazel_dep(name='C',version='2.0')") .addModule( - createModuleKey("C", "2.0"), + ModuleKey.create("C", "2.0"), "module(name='C', version='2.0');bazel_dep(name='B',version='1.0')"); ModuleFileFunction.REGISTRIES.set(differencer, ImmutableList.of(registry.getUrl())); @@ -251,24 +191,24 @@ public void testCircularDependency() throws Exception { assertThat(discoveryValue.getRootModuleName()).isEqualTo("A"); assertThat(discoveryValue.getDepGraph()) .containsExactly( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.parse("0.1")) - .addDep("B", createModuleKey("B", "1.0")) + .setVersion("0.1") + .addDep("B", ModuleKey.create("B", "1.0")) .build(), - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), Module.builder() .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "2.0")) + .setVersion("1.0") + .addDep("C", ModuleKey.create("C", "2.0")) .setRegistry(registry) .build(), - createModuleKey("C", "2.0"), + ModuleKey.create("C", "2.0"), Module.builder() .setName("C") - .setVersion(Version.parse("2.0")) - .addDep("B", createModuleKey("B", "1.0")) + .setVersion("2.0") + .addDep("B", ModuleKey.create("B", "1.0")) .setRegistry(registry) .build()); } @@ -281,11 +221,11 @@ public void testCircularDependencyOnRootModule() throws Exception { "bazel_dep(name='B',version='1.0')"); FakeRegistry registry = registryFactory - .newFakeRegistry("/foo") + .newFakeRegistry() .addModule( - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), "module(name='B', version='1.0');bazel_dep(name='A',version='2.0')") - .addModule(createModuleKey("A", "2.0"), "module(name='A', version='2.0')"); + .addModule(ModuleKey.create("A", "2.0"), "module(name='A', version='2.0')"); ModuleFileFunction.REGISTRIES.set(differencer, ImmutableList.of(registry.getUrl())); EvaluationResult result = @@ -297,17 +237,17 @@ public void testCircularDependencyOnRootModule() throws Exception { assertThat(discoveryValue.getRootModuleName()).isEqualTo("A"); assertThat(discoveryValue.getDepGraph()) .containsExactly( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.parse("0.1")) - .addDep("B", createModuleKey("B", "1.0")) + .setVersion("0.1") + .addDep("B", ModuleKey.create("B", "1.0")) .build(), - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), Module.builder() .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("A", createModuleKey("A", "")) + .setVersion("1.0") + .addDep("A", ModuleKey.create("A", "")) .setRegistry(registry) .build()); } @@ -321,12 +261,12 @@ public void testSingleVersionOverride() throws Exception { "single_version_override(module_name='C',version='2.0')"); FakeRegistry registry = registryFactory - .newFakeRegistry("/foo") + .newFakeRegistry() .addModule( - createModuleKey("B", "0.1"), + ModuleKey.create("B", "0.1"), "module(name='B', version='0.1');bazel_dep(name='C',version='1.0')") - .addModule(createModuleKey("C", "1.0"), "module(name='C', version='1.0');") - .addModule(createModuleKey("C", "2.0"), "module(name='C', version='2.0');"); + .addModule(ModuleKey.create("C", "1.0"), "module(name='C', version='1.0');") + .addModule(ModuleKey.create("C", "2.0"), "module(name='C', version='2.0');"); ModuleFileFunction.REGISTRIES.set(differencer, ImmutableList.of(registry.getUrl())); EvaluationResult result = @@ -338,41 +278,37 @@ public void testSingleVersionOverride() throws Exception { assertThat(discoveryValue.getRootModuleName()).isEqualTo("A"); assertThat(discoveryValue.getDepGraph()) .containsExactly( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.parse("0.1")) - .addDep("B", createModuleKey("B", "0.1")) + .setVersion("0.1") + .addDep("B", ModuleKey.create("B", "0.1")) .build(), - createModuleKey("B", "0.1"), + ModuleKey.create("B", "0.1"), Module.builder() .setName("B") - .setVersion(Version.parse("0.1")) - .addDep("C", createModuleKey("C", "2.0")) + .setVersion("0.1") + .addDep("C", ModuleKey.create("C", "2.0")) .setRegistry(registry) .build(), - createModuleKey("C", "2.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("2.0")) - .setRegistry(registry) - .build()); + ModuleKey.create("C", "2.0"), + Module.builder().setName("C").setVersion("2.0").setRegistry(registry).build()); } @Test public void testRegistryOverride() throws Exception { FakeRegistry registry1 = registryFactory - .newFakeRegistry("/foo") + .newFakeRegistry() .addModule( - createModuleKey("B", "0.1"), + ModuleKey.create("B", "0.1"), "module(name='B', version='0.1');bazel_dep(name='C',version='1.0')") - .addModule(createModuleKey("C", "1.0"), "module(name='C', version='1.0');"); + .addModule(ModuleKey.create("C", "1.0"), "module(name='C', version='1.0');"); FakeRegistry registry2 = registryFactory - .newFakeRegistry("/bar") + .newFakeRegistry() .addModule( - createModuleKey("C", "1.0"), + ModuleKey.create("C", "1.0"), "module(name='C', version='1.0');bazel_dep(name='B',version='0.1')"); scratch.file( workspaceRoot.getRelative("MODULE.bazel").getPathString(), @@ -390,71 +326,27 @@ public void testRegistryOverride() throws Exception { assertThat(discoveryValue.getRootModuleName()).isEqualTo("A"); assertThat(discoveryValue.getDepGraph()) .containsExactly( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.parse("0.1")) - .addDep("B", createModuleKey("B", "0.1")) + .setVersion("0.1") + .addDep("B", ModuleKey.create("B", "0.1")) .build(), - createModuleKey("B", "0.1"), + ModuleKey.create("B", "0.1"), Module.builder() .setName("B") - .setVersion(Version.parse("0.1")) - .addDep("C", createModuleKey("C", "1.0")) + .setVersion("0.1") + .addDep("C", ModuleKey.create("C", "1.0")) .setRegistry(registry1) .build(), - createModuleKey("C", "1.0"), + ModuleKey.create("C", "1.0"), Module.builder() .setName("C") - .setVersion(Version.parse("1.0")) - .addDep("B", createModuleKey("B", "0.1")) + .setVersion("1.0") + .addDep("B", ModuleKey.create("B", "0.1")) .setRegistry(registry2) .build()); } - @Test - public void testLocalPathOverride() throws Exception { - Path pathToC = scratch.dir("/pathToC"); - scratch.file( - pathToC.getRelative("MODULE.bazel").getPathString(), "module(name='C',version='2.0')"); - scratch.file(pathToC.getRelative("WORKSPACE").getPathString()); - scratch.file( - workspaceRoot.getRelative("MODULE.bazel").getPathString(), - "module(name='A',version='0.1')", - "bazel_dep(name='B',version='0.1')", - "local_path_override(module_name='C',path='" + pathToC.getPathString() + "')"); - FakeRegistry registry = - registryFactory - .newFakeRegistry("/foo") - .addModule( - createModuleKey("B", "0.1"), - "module(name='B', version='0.1');bazel_dep(name='C',version='1.0')") - .addModule(createModuleKey("C", "1.0"), "module(name='C', version='1.0');"); - ModuleFileFunction.REGISTRIES.set(differencer, ImmutableList.of(registry.getUrl())); - - EvaluationResult result = - driver.evaluate(ImmutableList.of(DiscoveryValue.KEY), evaluationContext); - if (result.hasError()) { - fail(result.getError().toString()); - } - DiscoveryValue discoveryValue = result.get(DiscoveryValue.KEY); - assertThat(discoveryValue.getRootModuleName()).isEqualTo("A"); - assertThat(discoveryValue.getDepGraph()) - .containsExactly( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.parse("0.1")) - .addDep("B", createModuleKey("B", "0.1")) - .build(), - createModuleKey("B", "0.1"), - Module.builder() - .setName("B") - .setVersion(Version.parse("0.1")) - .addDep("C", createModuleKey("C", "")) - .setRegistry(registry) - .build(), - createModuleKey("C", ""), - Module.builder().setName("C").setVersion(Version.parse("2.0")).build()); - } + // TODO(wyv): test local path override } diff --git a/dataset/GitHub_Java/bazelbuild.bazel/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionFunctionTest.java b/dataset/GitHub_Java/bazelbuild.bazel/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionFunctionTest.java index 6598dd48ad2..cceab189146 100644 --- a/dataset/GitHub_Java/bazelbuild.bazel/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionFunctionTest.java +++ b/dataset/GitHub_Java/bazelbuild.bazel/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionFunctionTest.java @@ -16,10 +16,8 @@ package com.google.devtools.build.lib.bazel.bzlmod; import static com.google.common.truth.Truth.assertThat; -import static com.google.devtools.build.lib.bazel.bzlmod.BzlmodTestUtil.createModuleKey; import static org.junit.Assert.fail; -import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.skyframe.SkyFunctions; @@ -55,34 +53,11 @@ public void setup() throws Exception { EvaluationContext.newBuilder().setNumThreads(8).setEventHandler(reporter).build(); } - private void setUpSkyFunctions( - String rootModuleName, - ImmutableMap depGraph, - ImmutableMap overrides) + private void setUpDiscoveryResult(String rootModuleName, ImmutableMap depGraph) throws Exception { MemoizingEvaluator evaluator = new InMemoryMemoizingEvaluator( ImmutableMap.builder() - .put( - SkyFunctions.MODULE_FILE, - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) { - Preconditions.checkArgument( - skyKey.equals(ModuleFileValue.keyForRootModule())); - return ModuleFileValue.create( - Module.builder() - .setName(rootModuleName) - .setVersion(Version.EMPTY) - .build(), - overrides); - } - - @Override - public String extractTag(SkyKey skyKey) { - return null; - } - }) .put( SkyFunctions.DISCOVERY, new SkyFunction() { @@ -104,47 +79,38 @@ public String extractTag(SkyKey skyKey) { @Test public void testSimpleDiamond() throws Exception { - setUpSkyFunctions( + setUpDiscoveryResult( "A", ImmutableMap.builder() .put( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.EMPTY) - .addDep("BfromA", createModuleKey("B", "1.0")) - .addDep("CfromA", createModuleKey("C", "2.0")) + .setVersion("") + .addDep("BfromA", ModuleKey.create("B", "1.0")) + .addDep("CfromA", ModuleKey.create("C", "2.0")) .build()) .put( - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), Module.builder() .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("DfromB", createModuleKey("D", "1.0")) + .setVersion("1.0") + .addDep("DfromB", ModuleKey.create("D", "1.0")) .build()) .put( - createModuleKey("C", "2.0"), + ModuleKey.create("C", "2.0"), Module.builder() .setName("C") - .setVersion(Version.parse("2.0")) - .addDep("DfromC", createModuleKey("D", "2.0")) + .setVersion("2.0") + .addDep("DfromC", ModuleKey.create("D", "2.0")) .build()) .put( - createModuleKey("D", "1.0"), - Module.builder() - .setName("D") - .setVersion(Version.parse("1.0")) - .setCompatibilityLevel(1) - .build()) + ModuleKey.create("D", "1.0"), + Module.builder().setName("D").setVersion("1.0").setCompatibilityLevel(1).build()) .put( - createModuleKey("D", "2.0"), - Module.builder() - .setName("D") - .setVersion(Version.parse("2.0")) - .setCompatibilityLevel(1) - .build()) - .build(), - ImmutableMap.of()); + ModuleKey.create("D", "2.0"), + Module.builder().setName("D").setVersion("2.0").setCompatibilityLevel(1).build()) + .build()); EvaluationResult result = driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); @@ -155,77 +121,72 @@ public void testSimpleDiamond() throws Exception { assertThat(selectionValue.getRootModuleName()).isEqualTo("A"); assertThat(selectionValue.getDepGraph()) .containsExactly( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.EMPTY) - .addDep("BfromA", createModuleKey("B", "1.0")) - .addDep("CfromA", createModuleKey("C", "2.0")) + .setVersion("") + .addDep("BfromA", ModuleKey.create("B", "1.0")) + .addDep("CfromA", ModuleKey.create("C", "2.0")) .build(), - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), Module.builder() .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("DfromB", createModuleKey("D", "2.0")) + .setVersion("1.0") + .addDep("DfromB", ModuleKey.create("D", "2.0")) .build(), - createModuleKey("C", "2.0"), + ModuleKey.create("C", "2.0"), Module.builder() .setName("C") - .setVersion(Version.parse("2.0")) - .addDep("DfromC", createModuleKey("D", "2.0")) + .setVersion("2.0") + .addDep("DfromC", ModuleKey.create("D", "2.0")) .build(), - createModuleKey("D", "2.0"), - Module.builder() - .setName("D") - .setVersion(Version.parse("2.0")) - .setCompatibilityLevel(1) - .build()); + ModuleKey.create("D", "2.0"), + Module.builder().setName("D").setVersion("2.0").setCompatibilityLevel(1).build()); } @Test public void testDiamondWithFurtherRemoval() throws Exception { - setUpSkyFunctions( + setUpDiscoveryResult( "A", ImmutableMap.builder() .put( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.EMPTY) - .addDep("B", createModuleKey("B", "1.0")) - .addDep("C", createModuleKey("C", "2.0")) + .setVersion("") + .addDep("B", ModuleKey.create("B", "1.0")) + .addDep("C", ModuleKey.create("C", "2.0")) .build()) .put( - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), Module.builder() .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("D", createModuleKey("D", "1.0")) + .setVersion("1.0") + .addDep("D", ModuleKey.create("D", "1.0")) .build()) .put( - createModuleKey("C", "2.0"), + ModuleKey.create("C", "2.0"), Module.builder() .setName("C") - .setVersion(Version.parse("2.0")) - .addDep("D", createModuleKey("D", "2.0")) + .setVersion("2.0") + .addDep("D", ModuleKey.create("D", "2.0")) .build()) .put( - createModuleKey("D", "1.0"), + ModuleKey.create("D", "1.0"), Module.builder() .setName("D") - .setVersion(Version.parse("1.0")) - .addDep("E", createModuleKey("E", "1.0")) + .setVersion("1.0") + .addDep("E", ModuleKey.create("E", "1.0")) .build()) .put( - createModuleKey("D", "2.0"), - Module.builder().setName("D").setVersion(Version.parse("2.0")).build()) + ModuleKey.create("D", "2.0"), + Module.builder().setName("D").setVersion("2.0").build()) // Only D@1.0 needs E. When D@1.0 is removed, E should be gone as well (even though // E@1.0 is selected for E). .put( - createModuleKey("E", "1.0"), - Module.builder().setName("E").setVersion(Version.parse("1.0")).build()) - .build(), - ImmutableMap.of()); + ModuleKey.create("E", "1.0"), + Module.builder().setName("E").setVersion("1.0").build()) + .build()); EvaluationResult result = driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); @@ -236,67 +197,66 @@ public void testDiamondWithFurtherRemoval() throws Exception { assertThat(selectionValue.getRootModuleName()).isEqualTo("A"); assertThat(selectionValue.getDepGraph()) .containsExactly( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.EMPTY) - .addDep("B", createModuleKey("B", "1.0")) - .addDep("C", createModuleKey("C", "2.0")) + .setVersion("") + .addDep("B", ModuleKey.create("B", "1.0")) + .addDep("C", ModuleKey.create("C", "2.0")) .build(), - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), Module.builder() .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("D", createModuleKey("D", "2.0")) + .setVersion("1.0") + .addDep("D", ModuleKey.create("D", "2.0")) .build(), - createModuleKey("C", "2.0"), + ModuleKey.create("C", "2.0"), Module.builder() .setName("C") - .setVersion(Version.parse("2.0")) - .addDep("D", createModuleKey("D", "2.0")) + .setVersion("2.0") + .addDep("D", ModuleKey.create("D", "2.0")) .build(), - createModuleKey("D", "2.0"), - Module.builder().setName("D").setVersion(Version.parse("2.0")).build()); + ModuleKey.create("D", "2.0"), + Module.builder().setName("D").setVersion("2.0").build()); } @Test public void testCircularDependencyDueToSelection() throws Exception { - setUpSkyFunctions( + setUpDiscoveryResult( "A", ImmutableMap.builder() .put( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.EMPTY) - .addDep("B", createModuleKey("B", "1.0")) + .setVersion("") + .addDep("B", ModuleKey.create("B", "1.0")) .build()) .put( - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), Module.builder() .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "2.0")) + .setVersion("1.0") + .addDep("C", ModuleKey.create("C", "2.0")) .build()) .put( - createModuleKey("C", "2.0"), + ModuleKey.create("C", "2.0"), Module.builder() .setName("C") - .setVersion(Version.parse("2.0")) - .addDep("B", createModuleKey("B", "1.0-pre")) + .setVersion("2.0") + .addDep("B", ModuleKey.create("B", "1.0-pre")) .build()) .put( - createModuleKey("B", "1.0-pre"), + ModuleKey.create("B", "1.0-pre"), Module.builder() .setName("B") - .setVersion(Version.parse("1.0-pre")) - .addDep("D", createModuleKey("D", "1.0")) + .setVersion("1.0-pre") + .addDep("D", ModuleKey.create("D", "1.0")) .build()) .put( - createModuleKey("D", "1.0"), - Module.builder().setName("D").setVersion(Version.parse("1.0")).build()) - .build(), - ImmutableMap.of()); + ModuleKey.create("D", "1.0"), + Module.builder().setName("D").setVersion("1.0").build()) + .build()); EvaluationResult result = driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); @@ -307,70 +267,61 @@ public void testCircularDependencyDueToSelection() throws Exception { assertThat(selectionValue.getRootModuleName()).isEqualTo("A"); assertThat(selectionValue.getDepGraph()) .containsExactly( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.EMPTY) - .addDep("B", createModuleKey("B", "1.0")) + .setVersion("") + .addDep("B", ModuleKey.create("B", "1.0")) .build(), - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), Module.builder() .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "2.0")) + .setVersion("1.0") + .addDep("C", ModuleKey.create("C", "2.0")) .build(), - createModuleKey("C", "2.0"), + ModuleKey.create("C", "2.0"), Module.builder() .setName("C") - .setVersion(Version.parse("2.0")) - .addDep("B", createModuleKey("B", "1.0")) + .setVersion("2.0") + .addDep("B", ModuleKey.create("B", "1.0")) .build()); // D is completely gone. } @Test public void differentCompatibilityLevelIsRejected() throws Exception { - setUpSkyFunctions( + setUpDiscoveryResult( "A", ImmutableMap.builder() .put( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.EMPTY) - .addDep("BfromA", createModuleKey("B", "1.0")) - .addDep("CfromA", createModuleKey("C", "2.0")) + .setVersion("") + .addDep("BfromA", ModuleKey.create("B", "1.0")) + .addDep("CfromA", ModuleKey.create("C", "2.0")) .build()) .put( - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), Module.builder() .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("DfromB", createModuleKey("D", "1.0")) + .setVersion("1.0") + .addDep("DfromB", ModuleKey.create("D", "1.0")) .build()) .put( - createModuleKey("C", "2.0"), + ModuleKey.create("C", "2.0"), Module.builder() .setName("C") - .setVersion(Version.parse("2.0")) - .addDep("DfromC", createModuleKey("D", "2.0")) + .setVersion("2.0") + .addDep("DfromC", ModuleKey.create("D", "2.0")) .build()) .put( - createModuleKey("D", "1.0"), - Module.builder() - .setName("D") - .setVersion(Version.parse("1.0")) - .setCompatibilityLevel(1) - .build()) + ModuleKey.create("D", "1.0"), + Module.builder().setName("D").setVersion("1.0").setCompatibilityLevel(1).build()) .put( - createModuleKey("D", "2.0"), - Module.builder() - .setName("D") - .setVersion(Version.parse("2.0")) - .setCompatibilityLevel(2) - .build()) - .build(), - ImmutableMap.of()); + ModuleKey.create("D", "2.0"), + Module.builder().setName("D").setVersion("2.0").setCompatibilityLevel(2).build()) + .build()); EvaluationResult result = driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); @@ -387,66 +338,53 @@ public void differentCompatibilityLevelIsOkIfUnreferenced() throws Exception { // \-> C 1.0 // \-> D 1.0 -> B 1.1 // \-> E 1.0 -> C 1.1 - setUpSkyFunctions( + setUpDiscoveryResult( "A", ImmutableMap.builder() .put( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.parse("1.0")) - .addDep("B", createModuleKey("B", "1.0")) - .addDep("C", createModuleKey("C", "1.0")) - .addDep("D", createModuleKey("D", "1.0")) - .addDep("E", createModuleKey("E", "1.0")) + .setVersion("1.0") + .addDep("B", ModuleKey.create("B", "1.0")) + .addDep("C", ModuleKey.create("C", "1.0")) + .addDep("D", ModuleKey.create("D", "1.0")) + .addDep("E", ModuleKey.create("E", "1.0")) .build()) .put( - createModuleKey("B", "1.0"), + ModuleKey.create("B", "1.0"), Module.builder() .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "2.0")) + .setVersion("1.0") + .addDep("C", ModuleKey.create("C", "2.0")) .build()) .put( - createModuleKey("C", "2.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("2.0")) - .setCompatibilityLevel(2) - .build()) + ModuleKey.create("C", "2.0"), + Module.builder().setName("C").setVersion("2.0").setCompatibilityLevel(2).build()) .put( - createModuleKey("C", "1.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.0")) - .setCompatibilityLevel(1) - .build()) + ModuleKey.create("C", "1.0"), + Module.builder().setName("C").setVersion("1.0").setCompatibilityLevel(1).build()) .put( - createModuleKey("D", "1.0"), + ModuleKey.create("D", "1.0"), Module.builder() .setName("D") - .setVersion(Version.parse("1.0")) - .addDep("B", createModuleKey("B", "1.1")) + .setVersion("1.0") + .addDep("B", ModuleKey.create("B", "1.1")) .build()) .put( - createModuleKey("B", "1.1"), - Module.builder().setName("B").setVersion(Version.parse("1.1")).build()) + ModuleKey.create("B", "1.1"), + Module.builder().setName("B").setVersion("1.1").build()) .put( - createModuleKey("E", "1.0"), + ModuleKey.create("E", "1.0"), Module.builder() .setName("E") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.1")) + .setVersion("1.0") + .addDep("C", ModuleKey.create("C", "1.1")) .build()) .put( - createModuleKey("C", "1.1"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.1")) - .setCompatibilityLevel(1) - .build()) - .build(), - ImmutableMap.of()); + ModuleKey.create("C", "1.1"), + Module.builder().setName("C").setVersion("1.1").setCompatibilityLevel(1).build()) + .build()); EvaluationResult result = driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); @@ -462,788 +400,30 @@ public void differentCompatibilityLevelIsOkIfUnreferenced() throws Exception { assertThat(selectionValue.getRootModuleName()).isEqualTo("A"); assertThat(selectionValue.getDepGraph()) .containsExactly( - createModuleKey("A", ""), + ModuleKey.create("A", ""), Module.builder() .setName("A") - .setVersion(Version.parse("1.0")) - .addDep("B", createModuleKey("B", "1.1")) - .addDep("C", createModuleKey("C", "1.1")) - .addDep("D", createModuleKey("D", "1.0")) - .addDep("E", createModuleKey("E", "1.0")) - .build(), - createModuleKey("B", "1.1"), - Module.builder().setName("B").setVersion(Version.parse("1.1")).build(), - createModuleKey("C", "1.1"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.1")) - .setCompatibilityLevel(1) - .build(), - createModuleKey("D", "1.0"), + .setVersion("1.0") + .addDep("B", ModuleKey.create("B", "1.1")) + .addDep("C", ModuleKey.create("C", "1.1")) + .addDep("D", ModuleKey.create("D", "1.0")) + .addDep("E", ModuleKey.create("E", "1.0")) + .build(), + ModuleKey.create("B", "1.1"), + Module.builder().setName("B").setVersion("1.1").build(), + ModuleKey.create("C", "1.1"), + Module.builder().setName("C").setVersion("1.1").setCompatibilityLevel(1).build(), + ModuleKey.create("D", "1.0"), Module.builder() .setName("D") - .setVersion(Version.parse("1.0")) - .addDep("B", createModuleKey("B", "1.1")) + .setVersion("1.0") + .addDep("B", ModuleKey.create("B", "1.1")) .build(), - createModuleKey("E", "1.0"), + ModuleKey.create("E", "1.0"), Module.builder() .setName("E") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.1")) - .build()); - } - - @Test - public void multipleVersionOverride_fork_allowedVersionMissingInDepGraph() throws Exception { - setUpSkyFunctions( - "A", - ImmutableMap.builder() - .put( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("B1", createModuleKey("B", "1.0")) - .addDep("B2", createModuleKey("B", "2.0")) - .build()) - .put( - createModuleKey("B", "1.0"), - Module.builder().setName("B").setVersion(Version.parse("1.0")).build()) - .put( - createModuleKey("B", "2.0"), - Module.builder().setName("B").setVersion(Version.parse("2.0")).build()) - .build(), - ImmutableMap.of( - "B", - MultipleVersionOverride.create( - ImmutableList.of(Version.parse("1.0"), Version.parse("2.0"), Version.parse("3.0")), - ""))); - - EvaluationResult result = - driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); - assertThat(result.hasError()).isTrue(); - String error = result.getError().toString(); - assertThat(error) - .contains( - "multiple_version_override for module B contains version 3.0, but it doesn't exist in" - + " the dependency graph"); - } - - @Test - public void multipleVersionOverride_fork_goodCase() throws Exception { - // For more complex good cases, see the "diamond" test cases below. - setUpSkyFunctions( - "A", - ImmutableMap.builder() - .put( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("B1", createModuleKey("B", "1.0")) - .addDep("B2", createModuleKey("B", "2.0")) - .build()) - .put( - createModuleKey("B", "1.0"), - Module.builder().setName("B").setVersion(Version.parse("1.0")).build()) - .put( - createModuleKey("B", "2.0"), - Module.builder().setName("B").setVersion(Version.parse("2.0")).build()) - .build(), - ImmutableMap.of( - "B", - MultipleVersionOverride.create( - ImmutableList.of(Version.parse("1.0"), Version.parse("2.0")), ""))); - - EvaluationResult result = - driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); - if (result.hasError()) { - fail(result.getError().toString()); - } - SelectionValue selectionValue = result.get(SelectionValue.KEY); - assertThat(selectionValue.getRootModuleName()).isEqualTo("A"); - assertThat(selectionValue.getDepGraph()) - .containsExactly( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("B1", createModuleKey("B", "1.0")) - .addDep("B2", createModuleKey("B", "2.0")) - .build(), - createModuleKey("B", "1.0"), - Module.builder().setName("B").setVersion(Version.parse("1.0")).build(), - createModuleKey("B", "2.0"), - Module.builder().setName("B").setVersion(Version.parse("2.0")).build()); - } - - @Test - public void multipleVersionOverride_fork_sameVersionUsedTwice() throws Exception { - setUpSkyFunctions( - "A", - ImmutableMap.builder() - .put( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("B1", createModuleKey("B", "1.0")) - .addDep("B2", createModuleKey("B", "1.3")) - .addDep("B3", createModuleKey("B", "1.5")) - .build()) - .put( - createModuleKey("B", "1.0"), - Module.builder().setName("B").setVersion(Version.parse("1.0")).build()) - .put( - createModuleKey("B", "1.3"), - Module.builder().setName("B").setVersion(Version.parse("1.3")).build()) - .put( - createModuleKey("B", "1.5"), - Module.builder().setName("B").setVersion(Version.parse("1.5")).build()) - .build(), - ImmutableMap.of( - "B", - MultipleVersionOverride.create( - ImmutableList.of(Version.parse("1.0"), Version.parse("1.5")), ""))); - - EvaluationResult result = - driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); - assertThat(result.hasError()).isTrue(); - String error = result.getError().toString(); - assertThat(error) - .containsMatch( - "A@_ depends on B@1.5 at least twice \\(with repo names (B2 and B3)|(B3 and B2)\\)"); - } - - @Test - public void multipleVersionOverride_diamond_differentCompatibilityLevels() throws Exception { - setUpSkyFunctions( - "A", - ImmutableMap.builder() - .put( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("BfromA", createModuleKey("B", "1.0")) - .addDep("CfromA", createModuleKey("C", "2.0")) - .build()) - .put( - createModuleKey("B", "1.0"), - Module.builder() - .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("DfromB", createModuleKey("D", "1.0")) - .build()) - .put( - createModuleKey("C", "2.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("2.0")) - .addDep("DfromC", createModuleKey("D", "2.0")) - .build()) - .put( - createModuleKey("D", "1.0"), - Module.builder() - .setName("D") - .setVersion(Version.parse("1.0")) - .setCompatibilityLevel(1) - .build()) - .put( - createModuleKey("D", "2.0"), - Module.builder() - .setName("D") - .setVersion(Version.parse("2.0")) - .setCompatibilityLevel(2) - .build()) - .build(), - ImmutableMap.of( - "D", - MultipleVersionOverride.create( - ImmutableList.of(Version.parse("1.0"), Version.parse("2.0")), ""))); - - EvaluationResult result = - driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); - if (result.hasError()) { - fail(result.getError().toString()); - } - SelectionValue selectionValue = result.get(SelectionValue.KEY); - assertThat(selectionValue.getRootModuleName()).isEqualTo("A"); - assertThat(selectionValue.getDepGraph()) - .containsExactly( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("BfromA", createModuleKey("B", "1.0")) - .addDep("CfromA", createModuleKey("C", "2.0")) - .build(), - createModuleKey("B", "1.0"), - Module.builder() - .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("DfromB", createModuleKey("D", "1.0")) - .build(), - createModuleKey("C", "2.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("2.0")) - .addDep("DfromC", createModuleKey("D", "2.0")) - .build(), - createModuleKey("D", "1.0"), - Module.builder() - .setName("D") - .setVersion(Version.parse("1.0")) - .setCompatibilityLevel(1) - .build(), - createModuleKey("D", "2.0"), - Module.builder() - .setName("D") - .setVersion(Version.parse("2.0")) - .setCompatibilityLevel(2) - .build()); - } - - @Test - public void multipleVersionOverride_diamond_sameCompatibilityLevel() throws Exception { - setUpSkyFunctions( - "A", - ImmutableMap.builder() - .put( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("BfromA", createModuleKey("B", "1.0")) - .addDep("CfromA", createModuleKey("C", "2.0")) - .build()) - .put( - createModuleKey("B", "1.0"), - Module.builder() - .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("DfromB", createModuleKey("D", "1.0")) - .build()) - .put( - createModuleKey("C", "2.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("2.0")) - .addDep("DfromC", createModuleKey("D", "2.0")) - .build()) - .put( - createModuleKey("D", "1.0"), - Module.builder().setName("D").setVersion(Version.parse("1.0")).build()) - .put( - createModuleKey("D", "2.0"), - Module.builder().setName("D").setVersion(Version.parse("2.0")).build()) - .build(), - ImmutableMap.of( - "D", - MultipleVersionOverride.create( - ImmutableList.of(Version.parse("1.0"), Version.parse("2.0")), ""))); - - EvaluationResult result = - driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); - if (result.hasError()) { - fail(result.getError().toString()); - } - SelectionValue selectionValue = result.get(SelectionValue.KEY); - assertThat(selectionValue.getRootModuleName()).isEqualTo("A"); - assertThat(selectionValue.getDepGraph()) - .containsExactly( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("BfromA", createModuleKey("B", "1.0")) - .addDep("CfromA", createModuleKey("C", "2.0")) - .build(), - createModuleKey("B", "1.0"), - Module.builder() - .setName("B") - .setVersion(Version.parse("1.0")) - .addDep("DfromB", createModuleKey("D", "1.0")) - .build(), - createModuleKey("C", "2.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("2.0")) - .addDep("DfromC", createModuleKey("D", "2.0")) - .build(), - createModuleKey("D", "1.0"), - Module.builder().setName("D").setVersion(Version.parse("1.0")).build(), - createModuleKey("D", "2.0"), - Module.builder().setName("D").setVersion(Version.parse("2.0")).build()); - } - - @Test - public void multipleVersionOverride_diamond_snappingToNextHighestVersion() throws Exception { - // A --> B1@1.0 -> C@1.0 - // \-> B2@1.0 -> C@1.3 [allowed] - // \-> B3@1.0 -> C@1.5 - // \-> B4@1.0 -> C@1.7 [allowed] - // \-> B5@1.0 -> C@2.0 [allowed] - setUpSkyFunctions( - "A", - ImmutableMap.builder() - .put( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("B1", createModuleKey("B1", "1.0")) - .addDep("B2", createModuleKey("B2", "1.0")) - .addDep("B3", createModuleKey("B3", "1.0")) - .addDep("B4", createModuleKey("B4", "1.0")) - .addDep("B5", createModuleKey("B5", "1.0")) - .build()) - .put( - createModuleKey("B1", "1.0"), - Module.builder() - .setName("B1") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.0")) - .build()) - .put( - createModuleKey("B2", "1.0"), - Module.builder() - .setName("B2") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.3")) - .build()) - .put( - createModuleKey("B3", "1.0"), - Module.builder() - .setName("B3") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.5")) - .build()) - .put( - createModuleKey("B4", "1.0"), - Module.builder() - .setName("B4") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.7")) - .build()) - .put( - createModuleKey("B5", "1.0"), - Module.builder() - .setName("B5") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "2.0")) - .build()) - .put( - createModuleKey("C", "1.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.0")) - .setCompatibilityLevel(1) - .build()) - .put( - createModuleKey("C", "1.3"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.3")) - .setCompatibilityLevel(1) - .build()) - .put( - createModuleKey("C", "1.5"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.5")) - .setCompatibilityLevel(1) - .build()) - .put( - createModuleKey("C", "1.7"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.7")) - .setCompatibilityLevel(1) - .build()) - .put( - createModuleKey("C", "2.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("2.0")) - .setCompatibilityLevel(2) - .build()) - .build(), - ImmutableMap.of( - "C", - MultipleVersionOverride.create( - ImmutableList.of(Version.parse("1.3"), Version.parse("1.7"), Version.parse("2.0")), - ""))); - - EvaluationResult result = - driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); - if (result.hasError()) { - fail(result.getError().toString()); - } - SelectionValue selectionValue = result.get(SelectionValue.KEY); - assertThat(selectionValue.getRootModuleName()).isEqualTo("A"); - // A --> B1@1.0 -> C@1.3 [originally C@1.0] - // \-> B2@1.0 -> C@1.3 [allowed] - // \-> B3@1.0 -> C@1.7 [originally C@1.5] - // \-> B4@1.0 -> C@1.7 [allowed] - // \-> B5@1.0 -> C@2.0 [allowed] - assertThat(selectionValue.getDepGraph()) - .containsExactly( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("B1", createModuleKey("B1", "1.0")) - .addDep("B2", createModuleKey("B2", "1.0")) - .addDep("B3", createModuleKey("B3", "1.0")) - .addDep("B4", createModuleKey("B4", "1.0")) - .addDep("B5", createModuleKey("B5", "1.0")) - .build(), - createModuleKey("B1", "1.0"), - Module.builder() - .setName("B1") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.3")) - .build(), - createModuleKey("B2", "1.0"), - Module.builder() - .setName("B2") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.3")) - .build(), - createModuleKey("B3", "1.0"), - Module.builder() - .setName("B3") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.7")) - .build(), - createModuleKey("B4", "1.0"), - Module.builder() - .setName("B4") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.7")) - .build(), - createModuleKey("B5", "1.0"), - Module.builder() - .setName("B5") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "2.0")) - .build(), - createModuleKey("C", "1.3"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.3")) - .setCompatibilityLevel(1) - .build(), - createModuleKey("C", "1.7"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.7")) - .setCompatibilityLevel(1) - .build(), - createModuleKey("C", "2.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("2.0")) - .setCompatibilityLevel(2) - .build()); - } - - @Test - public void multipleVersionOverride_diamond_dontSnapToDifferentCompatibility() throws Exception { - // A --> B1@1.0 -> C@1.0 [allowed] - // \-> B2@1.0 -> C@1.7 - // \-> B3@1.0 -> C@2.0 [allowed] - setUpSkyFunctions( - "A", - ImmutableMap.builder() - .put( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("B1", createModuleKey("B1", "1.0")) - .addDep("B2", createModuleKey("B2", "1.0")) - .addDep("B3", createModuleKey("B3", "1.0")) - .build()) - .put( - createModuleKey("B1", "1.0"), - Module.builder() - .setName("B1") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.0")) - .build()) - .put( - createModuleKey("B2", "1.0"), - Module.builder() - .setName("B2") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.7")) - .build()) - .put( - createModuleKey("B3", "1.0"), - Module.builder() - .setName("B3") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "2.0")) - .build()) - .put( - createModuleKey("C", "1.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.0")) - .setCompatibilityLevel(1) - .build()) - .put( - createModuleKey("C", "1.7"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.7")) - .setCompatibilityLevel(1) - .build()) - .put( - createModuleKey("C", "2.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("2.0")) - .setCompatibilityLevel(2) - .build()) - .build(), - ImmutableMap.of( - "C", - MultipleVersionOverride.create( - ImmutableList.of(Version.parse("1.0"), Version.parse("2.0")), ""))); - - EvaluationResult result = - driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); - assertThat(result.hasError()).isTrue(); - String error = result.getError().toString(); - assertThat(error) - .contains( - "B2@1.0 depends on C@1.7 which is not allowed by the multiple_version_override on C," - + " which allows only [1.0, 2.0]"); - } - - @Test - public void multipleVersionOverride_diamond_unknownCompatibility() throws Exception { - // A --> B1@1.0 -> C@1.0 [allowed] - // \-> B2@1.0 -> C@2.0 [allowed] - // \-> B3@1.0 -> C@3.0 - setUpSkyFunctions( - "A", - ImmutableMap.builder() - .put( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("B1", createModuleKey("B1", "1.0")) - .addDep("B2", createModuleKey("B2", "1.0")) - .addDep("B3", createModuleKey("B3", "1.0")) - .build()) - .put( - createModuleKey("B1", "1.0"), - Module.builder() - .setName("B1") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.0")) - .build()) - .put( - createModuleKey("B2", "1.0"), - Module.builder() - .setName("B2") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "2.0")) - .build()) - .put( - createModuleKey("B3", "1.0"), - Module.builder() - .setName("B3") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "3.0")) - .build()) - .put( - createModuleKey("C", "1.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.0")) - .setCompatibilityLevel(1) - .build()) - .put( - createModuleKey("C", "2.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("2.0")) - .setCompatibilityLevel(2) - .build()) - .put( - createModuleKey("C", "3.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("3.0")) - .setCompatibilityLevel(3) - .build()) - .build(), - ImmutableMap.of( - "C", - MultipleVersionOverride.create( - ImmutableList.of(Version.parse("1.0"), Version.parse("2.0")), ""))); - - EvaluationResult result = - driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); - assertThat(result.hasError()).isTrue(); - String error = result.getError().toString(); - assertThat(error) - .contains( - "B3@1.0 depends on C@3.0 which is not allowed by the multiple_version_override on C," - + " which allows only [1.0, 2.0]"); - } - - @Test - public void multipleVersionOverride_diamond_badVersionsAreOkayIfUnreferenced() throws Exception { - // A --> B1@1.0 --> C@1.0 [allowed] - // \ \-> B2@1.1 - // \-> B2@1.0 --> C@1.5 - // \-> B3@1.0 --> C@2.0 [allowed] - // \ \-> B4@1.1 - // \-> B4@1.0 --> C@3.0 - setUpSkyFunctions( - "A", - ImmutableMap.builder() - .put( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("B1", createModuleKey("B1", "1.0")) - .addDep("B2", createModuleKey("B2", "1.0")) - .addDep("B3", createModuleKey("B3", "1.0")) - .addDep("B4", createModuleKey("B4", "1.0")) - .build()) - .put( - createModuleKey("B1", "1.0"), - Module.builder() - .setName("B1") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.0")) - .addDep("B2", createModuleKey("B2", "1.1")) - .build()) - .put( - createModuleKey("B2", "1.0"), - Module.builder() - .setName("B2") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.5")) - .build()) - .put( - createModuleKey("B2", "1.1"), - Module.builder().setName("B2").setVersion(Version.parse("1.1")).build()) - .put( - createModuleKey("B3", "1.0"), - Module.builder() - .setName("B3") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "2.0")) - .addDep("B4", createModuleKey("B4", "1.1")) - .build()) - .put( - createModuleKey("B4", "1.0"), - Module.builder() - .setName("B4") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "3.0")) - .build()) - .put( - createModuleKey("B4", "1.1"), - Module.builder().setName("B4").setVersion(Version.parse("1.1")).build()) - .put( - createModuleKey("C", "1.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.0")) - .setCompatibilityLevel(1) - .build()) - .put( - createModuleKey("C", "1.5"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.5")) - .setCompatibilityLevel(1) - .build()) - .put( - createModuleKey("C", "2.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("2.0")) - .setCompatibilityLevel(2) - .build()) - .put( - createModuleKey("C", "3.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("3.0")) - .setCompatibilityLevel(3) - .build()) - .build(), - ImmutableMap.of( - "C", - MultipleVersionOverride.create( - ImmutableList.of(Version.parse("1.0"), Version.parse("2.0")), ""))); - - EvaluationResult result = - driver.evaluate(ImmutableList.of(SelectionValue.KEY), evaluationContext); - if (result.hasError()) { - fail(result.getError().toString()); - } - SelectionValue selectionValue = result.get(SelectionValue.KEY); - assertThat(selectionValue.getRootModuleName()).isEqualTo("A"); - // A --> B1@1.0 --> C@1.0 [allowed] - // \ \-> B2@1.1 - // \-> B2@1.1 - // \-> B3@1.0 --> C@2.0 [allowed] - // \ \-> B4@1.1 - // \-> B4@1.1 - // C@1.5 and C@3.0, the versions violating the allowlist, are gone. - assertThat(selectionValue.getDepGraph()) - .containsExactly( - createModuleKey("A", ""), - Module.builder() - .setName("A") - .setVersion(Version.EMPTY) - .addDep("B1", createModuleKey("B1", "1.0")) - .addDep("B2", createModuleKey("B2", "1.1")) - .addDep("B3", createModuleKey("B3", "1.0")) - .addDep("B4", createModuleKey("B4", "1.1")) - .build(), - createModuleKey("B1", "1.0"), - Module.builder() - .setName("B1") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "1.0")) - .addDep("B2", createModuleKey("B2", "1.1")) - .build(), - createModuleKey("B2", "1.1"), - Module.builder().setName("B2").setVersion(Version.parse("1.1")).build(), - createModuleKey("B3", "1.0"), - Module.builder() - .setName("B3") - .setVersion(Version.parse("1.0")) - .addDep("C", createModuleKey("C", "2.0")) - .addDep("B4", createModuleKey("B4", "1.1")) - .build(), - createModuleKey("B4", "1.1"), - Module.builder().setName("B4").setVersion(Version.parse("1.1")).build(), - createModuleKey("C", "1.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("1.0")) - .setCompatibilityLevel(1) - .build(), - createModuleKey("C", "2.0"), - Module.builder() - .setName("C") - .setVersion(Version.parse("2.0")) - .setCompatibilityLevel(2) + .setVersion("1.0") + .addDep("C", ModuleKey.create("C", "1.1")) .build()); } }