// Copyright 2021 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

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.assertThrows;
import static org.junit.Assert.fail;

import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableBiMap;
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.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.bzlmod.BzlmodTestUtil.InterimModuleBuilder;
import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileValue.RootModuleFileValue;
import com.google.devtools.build.lib.bazel.repository.RepositoryOptions.LockfileMode;
import com.google.devtools.build.lib.bazel.repository.starlark.StarlarkRepositoryModule;
import com.google.devtools.build.lib.clock.BlazeClock;
import com.google.devtools.build.lib.cmdline.LabelConstants;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions;
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.ClientEnvironmentFunction;
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.IgnoredPackagePrefixesFunction;
import com.google.devtools.build.lib.skyframe.LocalRepositoryLookupFunction;
import com.google.devtools.build.lib.skyframe.PackageLookupFunction;
import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossRepositoryLabelViolationStrategy;
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.FileStateKey;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
import com.google.devtools.build.lib.vfs.SyscallCache;
import com.google.devtools.build.skyframe.EvaluationContext;
import com.google.devtools.build.skyframe.EvaluationResult;
import com.google.devtools.build.skyframe.InMemoryMemoizingEvaluator;
import com.google.devtools.build.skyframe.MemoizingEvaluator;
import com.google.devtools.build.skyframe.RecordingDifferencer;
import com.google.devtools.build.skyframe.SequencedRecordingDifferencer;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import net.starlark.java.eval.Dict;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.StarlarkSemantics;
import net.starlark.java.syntax.Location;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link ModuleFileFunction}. */
@RunWith(JUnit4.class)
public class ModuleFileFunctionTest extends FoundationTestCase {

  private MemoizingEvaluator evaluator;
  private RecordingDifferencer differencer;
  private EvaluationContext evaluationContext;
  private FakeRegistry.Factory registryFactory;

  @Before
  public void setup() throws Exception {
    setUpWithBuiltinModules(ImmutableMap.of());
  }

  private void setUpWithBuiltinModules(ImmutableMap<String, NonRegistryOverride> builtinModules) {
    differencer = new SequencedRecordingDifferencer();
    evaluationContext =
        EvaluationContext.newBuilder().setParallelism(8).setEventHandler(reporter).build();
    registryFactory = new FakeRegistry.Factory();
    AtomicReference<PathPackageLocator> packageLocator =
        new AtomicReference<>(
            new PathPackageLocator(
                outputBase,
                ImmutableList.of(Root.fromPath(rootDirectory)),
                BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY));
    BlazeDirectories directories =
        new BlazeDirectories(
            new ServerDirectories(rootDirectory, outputBase, rootDirectory),
            rootDirectory,
            /* defaultSystemJavabase= */ null,
            AnalysisMock.get().getProductName());
    ExternalFilesHelper externalFilesHelper =
        ExternalFilesHelper.createForTesting(
            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();

    ImmutableMap<String, RepositoryFunction> repositoryHandlers =
        ImmutableMap.of(LocalRepositoryRule.NAME, new LocalRepositoryFunction());
    evaluator =
        new InMemoryMemoizingEvaluator(
            ImmutableMap.<SkyFunctionName, SkyFunction>builder()
                .put(FileValue.FILE, new FileFunction(packageLocator, directories))
                .put(
                    FileStateKey.FILE_STATE,
                    new FileStateFunction(
                        Suppliers.ofInstance(
                            new TimestampGranularityMonitor(BlazeClock.instance())),
                        SyscallCache.NO_CACHE,
                        externalFilesHelper))
                .put(SkyFunctions.BAZEL_LOCK_FILE, new BazelLockFileFunction(rootDirectory))
                .put(
                    SkyFunctions.MODULE_FILE,
                    new ModuleFileFunction(
                        ruleClassProvider.getBazelStarlarkEnvironment(),
                        rootDirectory,
                        builtinModules))
                .put(
                    SkyFunctions.PACKAGE_LOOKUP,
                    new PackageLookupFunction(
                        new AtomicReference<>(ImmutableSet.of()),
                        CrossRepositoryLabelViolationStrategy.ERROR,
                        BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY,
                        BazelSkyframeExecutorConstants.EXTERNAL_PACKAGE_HELPER))
                .put(
                    SkyFunctions.IGNORED_PACKAGE_PREFIXES,
                    new IgnoredPackagePrefixesFunction(
                        /* ignoredPackagePrefixesFile= */ PathFragment.EMPTY_FRAGMENT))
                .put(
                    SkyFunctions.LOCAL_REPOSITORY_LOOKUP,
                    new LocalRepositoryLookupFunction(
                        BazelSkyframeExecutorConstants.EXTERNAL_PACKAGE_HELPER))
                .put(SkyFunctions.PRECOMPUTED, new PrecomputedFunction())
                .put(
                    SkyFunctions.REPOSITORY_DIRECTORY,
                    new RepositoryDelegatorFunction(
                        repositoryHandlers,
                        null,
                        new AtomicBoolean(true),
                        ImmutableMap::of,
                        directories,
                        BazelSkyframeExecutorConstants.EXTERNAL_PACKAGE_HELPER))
                .put(
                    BzlmodRepoRuleValue.BZLMOD_REPO_RULE,
                    new BzlmodRepoRuleFunction(ruleClassProvider, directories))
                .put(
                    SkyFunctions.REGISTRY,
                    new RegistryFunction(registryFactory, directories.getWorkspace()))
                .put(SkyFunctions.REPO_SPEC, new RepoSpecFunction())
                .put(SkyFunctions.YANKED_VERSIONS, new YankedVersionsFunction())
                .put(
                    SkyFunctions.MODULE_EXTENSION_REPO_MAPPING_ENTRIES,
                    new ModuleExtensionRepoMappingEntriesFunction())
                .put(
                    SkyFunctions.CLIENT_ENVIRONMENT_VARIABLE,
                    new ClientEnvironmentFunction(new AtomicReference<>(ImmutableMap.of())))
                .buildOrThrow(),
            differencer);

    PrecomputedValue.STARLARK_SEMANTICS.set(
        differencer,
        StarlarkSemantics.builder().setBool(BuildLanguageOptions.ENABLE_BZLMOD, true).build());
    RepositoryDelegatorFunction.REPOSITORY_OVERRIDES.set(differencer, ImmutableMap.of());
    RepositoryDelegatorFunction.FORCE_FETCH.set(
        differencer, RepositoryDelegatorFunction.FORCE_FETCH_DISABLED);
    RepositoryDelegatorFunction.VENDOR_DIRECTORY.set(differencer, Optional.empty());

    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());
    ModuleFileFunction.IGNORE_DEV_DEPS.set(differencer, false);
    ModuleFileFunction.MODULE_OVERRIDES.set(differencer, ImmutableMap.of());
    YankedVersionsUtil.ALLOWED_YANKED_VERSIONS.set(differencer, ImmutableList.of());
    BazelLockFileFunction.LOCKFILE_MODE.set(differencer, LockfileMode.UPDATE);
  }

  @Test
  public void testRootModule() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(",
        "    name='aaa',",
        "    version='0.1',",
        "    compatibility_level=4,",
        ")",
        "bazel_dep(name='bbb',version='1.0')",
        "bazel_dep(name='ccc',version='2.0',repo_name='see')",
        "register_toolchains('//my:toolchain', '//my:toolchain2')",
        "register_execution_platforms('//my:platform', '//my:platform2')",
        "single_version_override(module_name='ddd',version='18')",
        "local_path_override(module_name='eee',path='somewhere/else')",
        "multiple_version_override(module_name='fff',versions=['1.0','2.0'])",
        "archive_override(module_name='ggg',urls=['https://hello.com/world.zip'])");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    if (result.hasError()) {
      fail(result.getError().toString());
    }
    RootModuleFileValue rootModuleFileValue = result.get(ModuleFileValue.KEY_FOR_ROOT_MODULE);
    assertThat(rootModuleFileValue.getModule())
        .isEqualTo(
            InterimModuleBuilder.create("aaa", "0.1", 4)
                .setKey(ModuleKey.ROOT)
                .addExecutionPlatformsToRegister(
                    ImmutableList.of("//my:platform", "//my:platform2"))
                .addToolchainsToRegister(ImmutableList.of("//my:toolchain", "//my:toolchain2"))
                .addDep("bbb", createModuleKey("bbb", "1.0"))
                .addDep("see", createModuleKey("ccc", "2.0"))
                .build());
    assertThat(rootModuleFileValue.getOverrides())
        .containsExactly(
            "ddd",
                SingleVersionOverride.create(
                    Version.parse("18"), "", ImmutableList.of(), ImmutableList.of(), 0),
            "eee", LocalPathOverride.create("somewhere/else"),
            "fff",
                MultipleVersionOverride.create(
                    ImmutableList.of(Version.parse("1.0"), Version.parse("2.0")), ""),
            "ggg",
                ArchiveOverride.create(
                    ImmutableList.of("https://hello.com/world.zip"),
                    ImmutableList.of(),
                    ImmutableList.of(),
                    "",
                    "",
                    0));
    assertThat(rootModuleFileValue.getNonRegistryOverrideCanonicalRepoNameLookup())
        .containsExactly(
            RepositoryName.create("eee~"), "eee",
            RepositoryName.create("ggg~"), "ggg");
  }

  @Test
  public void testRootModule_noModuleFunctionIsOkay() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "bazel_dep(name='bbb',version='1.0')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    if (result.hasError()) {
      fail(result.getError().toString());
    }
    RootModuleFileValue rootModuleFileValue = result.get(ModuleFileValue.KEY_FOR_ROOT_MODULE);
    assertThat(rootModuleFileValue.getModule())
        .isEqualTo(
            InterimModuleBuilder.create("", "")
                .setKey(ModuleKey.ROOT)
                .addDep("bbb", createModuleKey("bbb", "1.0"))
                .build());
    assertThat(rootModuleFileValue.getOverrides()).isEmpty();
    assertThat(rootModuleFileValue.getNonRegistryOverrideCanonicalRepoNameLookup()).isEmpty();
  }

  @Test
  public void testRootModule_badSelfOverride() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa')",
        "single_version_override(module_name='aaa',version='7')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertThat(result.hasError()).isTrue();
    assertThat(result.getError().toString()).contains("invalid override for the root module");
  }

  @Test
  public void testRootModule_overrideBuiltinModule() throws Exception {
    setUpWithBuiltinModules(
        ImmutableMap.of(
            "bazel_tools",
            LocalPathOverride.create(
                rootDirectory.getRelative("bazel_tools_original").getPathString())));
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa')",
        "local_path_override(module_name='bazel_tools',path='./bazel_tools_new')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    ModuleOverride bazelToolsOverride =
        result.get(ModuleFileValue.KEY_FOR_ROOT_MODULE).getOverrides().get("bazel_tools");
    assertThat(bazelToolsOverride).isInstanceOf(LocalPathOverride.class);
    assertThat(bazelToolsOverride).isEqualTo(LocalPathOverride.create("./bazel_tools_new"));
  }

  @Test
  public void testRootModule_include_good() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa')",
        "include('//java:java.MODULE.bazel')",
        "bazel_dep(name='foo', version='1.0')",
        "register_toolchains('//:whatever')",
        "include('//python:python.MODULE.bazel')");
    scratch.overwriteFile(rootDirectory.getRelative("java/BUILD").getPathString());
    scratch.overwriteFile(
        rootDirectory.getRelative("java/java.MODULE.bazel").getPathString(),
        "bazel_dep(name='java-foo', version='1.0')");
    scratch.overwriteFile(rootDirectory.getRelative("python/BUILD").getPathString());
    scratch.overwriteFile(
        rootDirectory.getRelative("python/python.MODULE.bazel").getPathString(),
        "bazel_dep(name='py-foo', version='1.0', repo_name='python-foo')",
        "single_version_override(module_name='java-foo', version='2.0')",
        "include('//python:toolchains/toolchains.MODULE.bazel')");
    scratch.overwriteFile(
        rootDirectory.getRelative("python/toolchains/toolchains.MODULE.bazel").getPathString(),
        "register_toolchains('//:python-whatever')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    if (result.hasError()) {
      fail(result.getError().toString());
    }
    RootModuleFileValue rootModuleFileValue = result.get(ModuleFileValue.KEY_FOR_ROOT_MODULE);
    InterimModule expectedModule =
        InterimModuleBuilder.create("aaa", "")
            .setKey(ModuleKey.ROOT)
            .addDep("java-foo", createModuleKey("java-foo", "1.0"))
            .addDep("foo", createModuleKey("foo", "1.0"))
            .addDep("python-foo", createModuleKey("py-foo", "1.0"))
            .addToolchainsToRegister(ImmutableList.of("//:whatever", "//:python-whatever"))
            .build();
    assertThat(rootModuleFileValue.getModule()).isEqualTo(expectedModule);
    // specifically assert the order of deps, which is significant; Map.equals semantics don't test
    // this.
    assertThat(rootModuleFileValue.getModule().getDeps())
        .containsExactlyEntriesIn(expectedModule.getDeps())
        .inOrder();
    assertThat(rootModuleFileValue.getOverrides())
        .containsExactly(
            "java-foo",
            SingleVersionOverride.create(
                Version.parse("2.0"), "", ImmutableList.of(), ImmutableList.of(), 0));
  }

  @Test
  public void testRootModule_include_bad_otherRepoLabel() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa')",
        "include('@haha//java:java.MODULE.bazel')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertThat(result.hasError()).isTrue();
    assertThat(result.getError().toString()).contains("starting with double slashes");
  }

  @Test
  public void testRootModule_include_bad_relativeLabel() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa')",
        "include(':relative.MODULE.bazel')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertThat(result.hasError()).isTrue();
    assertThat(result.getError().toString()).contains("starting with double slashes");
  }

  @Test
  public void testRootModule_include_bad_notEndingInModuleBazel() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa')",
        "include('//:MODULE.bazel.segment')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertThat(result.hasError()).isTrue();
    assertThat(result.getError().toString()).contains("have a name ending in '.MODULE.bazel'");
  }

  @Test
  public void testRootModule_include_bad_badLabelSyntax() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa')",
        "include('//haha/:::.MODULE.bazel')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    reporter.removeHandler(failFastHandler); // expect failures
    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertThat(result.hasError()).isTrue();
    assertThat(result.getError().toString()).contains("bad include label");
  }

  @Test
  public void testRootModule_include_bad_moduleAfterInclude() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "include('//java:java.MODULE.bazel')");
    scratch.overwriteFile(rootDirectory.getRelative("java/BUILD").getPathString());
    scratch.overwriteFile(
        rootDirectory.getRelative("java/java.MODULE.bazel").getPathString(),
        "module(name='bet-you-didnt-expect-this-didya')",
        "bazel_dep(name='java-foo', version='1.0', repo_name='foo')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    reporter.removeHandler(failFastHandler); // expect failures
    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertThat(result.hasError()).isTrue();
    assertContainsEvent("if module() is called, it must be called before any other functions");
  }

  @Test
  public void testRootModule_include_bad_repoNameCollision() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa')",
        "include('//java:java.MODULE.bazel')",
        "include('//python:python.MODULE.bazel')");
    scratch.overwriteFile(rootDirectory.getRelative("java/BUILD").getPathString());
    scratch.overwriteFile(
        rootDirectory.getRelative("java/java.MODULE.bazel").getPathString(),
        "bazel_dep(name='java-foo', version='1.0', repo_name='foo')");
    scratch.overwriteFile(rootDirectory.getRelative("python/BUILD").getPathString());
    scratch.overwriteFile(
        rootDirectory.getRelative("python/python.MODULE.bazel").getPathString(),
        "bazel_dep(name='python-foo', version='1.0', repo_name='foo')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    reporter.removeHandler(failFastHandler); // expect failures
    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertThat(result.hasError()).isTrue();
    assertContainsEvent("The repo name 'foo' is already being used");
  }

  @Test
  public void testRootModule_include_bad_tryingToLeakBindings() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa')",
        "FOO_NAME = 'foo'",
        "include('//java:java.MODULE.bazel')");
    scratch.overwriteFile(rootDirectory.getRelative("java/BUILD").getPathString());
    scratch.overwriteFile(
        rootDirectory.getRelative("java/java.MODULE.bazel").getPathString(),
        "bazel_dep(name=FOO_NAME, version='1.0')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    reporter.removeHandler(failFastHandler); // expect failures
    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertThat(result.hasError()).isTrue();
    assertContainsEvent("name 'FOO_NAME' is not defined");
  }

  @Test
  public void forgotVersion() throws Exception {
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    SkyKey skyKey = ModuleFileValue.key(createModuleKey("bbb", ""), null);
    EvaluationResult<ModuleFileValue> result =
        evaluator.evaluate(ImmutableList.of(skyKey), evaluationContext);
    assertThat(result.hasError()).isTrue();
    assertThat(result.getError().toString())
        .contains("bad bazel_dep on module 'bbb' with no version");
  }

  @Test
  public void testRegistriesCascade() throws Exception {
    // Registry1 has no module B@1.0; registry2 and registry3 both have it. We should be using the
    // B@1.0 from registry2.
    FakeRegistry registry1 = registryFactory.newFakeRegistry("/foo");
    FakeRegistry registry2 =
        registryFactory
            .newFakeRegistry("/bar")
            .addModule(
                createModuleKey("bbb", "1.0"),
                "module(name='bbb',version='1.0');bazel_dep(name='ccc',version='2.0')");
    FakeRegistry registry3 =
        registryFactory
            .newFakeRegistry("/baz")
            .addModule(
                createModuleKey("bbb", "1.0"),
                "module(name='bbb',version='1.0');bazel_dep(name='ddd',version='3.0')");
    ModuleFileFunction.REGISTRIES.set(
        differencer, ImmutableSet.of(registry1.getUrl(), registry2.getUrl(), registry3.getUrl()));

    SkyKey skyKey = ModuleFileValue.key(createModuleKey("bbb", "1.0"), null);
    EvaluationResult<ModuleFileValue> result =
        evaluator.evaluate(ImmutableList.of(skyKey), evaluationContext);
    if (result.hasError()) {
      fail(result.getError().toString());
    }
    ModuleFileValue moduleFileValue = result.get(skyKey);
    assertThat(moduleFileValue.getModule())
        .isEqualTo(
            InterimModuleBuilder.create("bbb", "1.0")
                .addDep("ccc", createModuleKey("ccc", "2.0"))
                .setRegistry(registry2)
                .build());
  }

  @Test
  public void testNonRootModuleCannotUseInclude() throws Exception {
    FakeRegistry registry =
        registryFactory
            .newFakeRegistry("/foo")
            .addModule(
                createModuleKey("foo", "1.0"),
                "module(name='foo',version='1.0')",
                "include('//java:MODULE.bazel.segment')");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.key(createModuleKey("foo", "1.0"), null)),
            evaluationContext);
    assertThat(result.hasError()).isTrue();
    assertThat(result.getError().toString()).contains("but it can only be used in the root module");
  }

  @Test
  public void testLocalPathOverride() throws Exception {
    // There is an override for B to use the local path "code_for_b", so we shouldn't even be
    // looking at the registry.
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa',version='0.1')",
        "local_path_override(module_name='bbb',path='code_for_b')");
    scratch.overwriteFile(
        rootDirectory.getRelative("code_for_b/MODULE.bazel").getPathString(),
        "module(name='bbb',version='1.0')",
        "bazel_dep(name='ccc',version='2.0')");
    scratch.overwriteFile(rootDirectory.getRelative("code_for_b/WORKSPACE").getPathString());
    FakeRegistry registry =
        registryFactory
            .newFakeRegistry("/foo")
            .addModule(
                createModuleKey("bbb", "1.0"),
                "module(name='bbb',version='1.0');bazel_dep(name='ccc',version='3.0')");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    // The version is empty here due to the override.
    SkyKey skyKey =
        ModuleFileValue.key(createModuleKey("bbb", ""), LocalPathOverride.create("code_for_b"));
    EvaluationResult<ModuleFileValue> result =
        evaluator.evaluate(ImmutableList.of(skyKey), evaluationContext);
    if (result.hasError()) {
      fail(result.getError().toString());
    }
    ModuleFileValue moduleFileValue = result.get(skyKey);
    assertThat(moduleFileValue.getModule())
        .isEqualTo(
            InterimModuleBuilder.create("bbb", "1.0")
                .setKey(createModuleKey("bbb", ""))
                .addDep("ccc", createModuleKey("ccc", "2.0"))
                .build());
  }

  @Test
  public void testCommandLineModuleOverrides() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa',version='0.1')",
        "bazel_dep(name = \"bbb\", version = \"1.0\")",
        "local_path_override(module_name='bbb', path='ignored_override')");

    // Command line override has the priority. Thus, "used_override" with dependency on 'ccc'
    // should be selected.
    scratch.overwriteFile(
        rootDirectory.getRelative("ignored_override/MODULE.bazel").getPathString(),
        "module(name='bbb',version='1.0')");
    scratch.overwriteFile(rootDirectory.getRelative("ignored_override/WORKSPACE").getPathString());
    scratch.overwriteFile(
        rootDirectory.getRelative("used_override/MODULE.bazel").getPathString(),
        "module(name='bbb',version='1.0')",
        "bazel_dep(name='ccc',version='2.0')");
    scratch.overwriteFile(rootDirectory.getRelative("used_override/WORKSPACE").getPathString());

    // ModuleFileFuncion.MODULE_OVERRIDES should be filled from command line options
    // Inject for testing
    Map<String, ModuleOverride> moduleOverride =
        new LinkedHashMap<>(ImmutableMap.of("bbb", LocalPathOverride.create("used_override")));
    ModuleFileFunction.MODULE_OVERRIDES.set(differencer, ImmutableMap.copyOf(moduleOverride));

    FakeRegistry registry =
        registryFactory
            .newFakeRegistry("/foo")
            .addModule(
                createModuleKey("bbb", "1.0"),
                "module(name='bbb',version='1.0');bazel_dep(name='ccc',version='3.0')");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    // The version is empty here due to the override.
    SkyKey skyKey =
        ModuleFileValue.key(createModuleKey("bbb", ""), LocalPathOverride.create("used_override"));
    EvaluationResult<ModuleFileValue> result =
        evaluator.evaluate(ImmutableList.of(skyKey), evaluationContext);
    if (result.hasError()) {
      fail(result.getError().toString());
    }
    ModuleFileValue moduleFileValue = result.get(skyKey);
    assertThat(moduleFileValue.getModule())
        .isEqualTo(
            InterimModuleBuilder.create("bbb", "1.0")
                .setKey(createModuleKey("bbb", ""))
                .addDep("ccc", createModuleKey("ccc", "2.0"))
                .build());
  }

  @Test
  public void testRegistryOverride() throws Exception {
    FakeRegistry registry1 =
        registryFactory
            .newFakeRegistry("/foo")
            .addModule(
                createModuleKey("bbb", "1.0"),
                "module(name='bbb',version='1.0',compatibility_level=4)",
                "bazel_dep(name='ccc',version='2.0')");
    FakeRegistry registry2 =
        registryFactory
            .newFakeRegistry("/foo")
            .addModule(
                createModuleKey("bbb", "1.0"),
                "module(name='bbb',version='1.0',compatibility_level=6)",
                "bazel_dep(name='ccc',version='3.0')");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry1.getUrl()));

    // Override the registry for B to be registry2 (instead of the default registry1).
    SkyKey skyKey =
        ModuleFileValue.key(
            createModuleKey("bbb", "1.0"),
            SingleVersionOverride.create(
                Version.EMPTY, registry2.getUrl(), ImmutableList.of(), ImmutableList.of(), 0));
    EvaluationResult<ModuleFileValue> result =
        evaluator.evaluate(ImmutableList.of(skyKey), evaluationContext);
    if (result.hasError()) {
      fail(result.getError().toString());
    }
    ModuleFileValue moduleFileValue = result.get(skyKey);
    assertThat(moduleFileValue.getModule())
        .isEqualTo(
            InterimModuleBuilder.create("bbb", "1.0", 6)
                .addDep("ccc", createModuleKey("ccc", "3.0"))
                .setRegistry(registry2)
                .build());
  }

  @Test
  public void testModuleExtensions_good() throws Exception {
    FakeRegistry registry =
        registryFactory
            .newFakeRegistry("/foo")
            .addModule(
                createModuleKey("mymod", "1.0"),
                "module(name='mymod',version='1.0')",
                "myext1 = use_extension('//:defs.bzl','myext1')",
                "use_repo(myext1, 'repo1')",
                "myext1.tag(key='val')",
                "myext2 = use_extension('//:defs.bzl','myext2')",
                "use_repo(myext2, 'repo2', other_repo1='repo1')",
                "myext2.tag1(key1='val1')",
                "myext2.tag2(key2='val2')",
                "bazel_dep(name='rules_jvm_external',version='2.0')",
                "maven = use_extension('@rules_jvm_external//:defs.bzl','maven')",
                "use_repo(maven, mvn='maven')",
                "maven.dep(coord='junit')",
                "use_repo(maven, 'junit', 'guava')",
                "maven.dep(coord='guava')");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    ModuleKey myMod = createModuleKey("mymod", "1.0");
    SkyKey skyKey = ModuleFileValue.key(myMod, null);
    EvaluationResult<ModuleFileValue> result =
        evaluator.evaluate(ImmutableList.of(skyKey), evaluationContext);
    if (result.hasError()) {
      throw result.getError().getException();
    }
    ModuleFileValue moduleFileValue = result.get(skyKey);
    assertThat(moduleFileValue.getModule())
        .isEqualTo(
            InterimModuleBuilder.create("mymod", "1.0")
                .addDep("rules_jvm_external", createModuleKey("rules_jvm_external", "2.0"))
                .setRegistry(registry)
                .addExtensionUsage(
                    ModuleExtensionUsage.builder()
                        .setExtensionBzlFile("@mymod//:defs.bzl")
                        .setExtensionName("myext1")
                        .setIsolationKey(Optional.empty())
                        .setUsingModule(myMod)
                        .addProxy(
                            ModuleExtensionUsage.Proxy.builder()
                                .setLocation(
                                    Location.fromFileLineColumn(
                                        "fake:0/modules/mymod/1.0/MODULE.bazel", 2, 23))
                                .setDevDependency(false)
                                .setProxyName("myext1")
                                .setImports(ImmutableBiMap.of("repo1", "repo1"))
                                .setContainingModuleFilePath(
                                    LabelConstants.MODULE_DOT_BAZEL_FILE_NAME)
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("tag")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("key", "val")
                                            .buildImmutable()))
                                .setDevDependency(false)
                                .setLocation(
                                    Location.fromFileLineColumn(
                                        "fake:0/modules/mymod/1.0/MODULE.bazel", 4, 11))
                                .build())
                        .build())
                .addExtensionUsage(
                    ModuleExtensionUsage.builder()
                        .setExtensionBzlFile("@mymod//:defs.bzl")
                        .setExtensionName("myext2")
                        .setIsolationKey(Optional.empty())
                        .setUsingModule(myMod)
                        .addProxy(
                            ModuleExtensionUsage.Proxy.builder()
                                .setLocation(
                                    Location.fromFileLineColumn(
                                        "fake:0/modules/mymod/1.0/MODULE.bazel", 5, 23))
                                .setDevDependency(false)
                                .setProxyName("myext2")
                                .setImports(
                                    ImmutableBiMap.of("other_repo1", "repo1", "repo2", "repo2"))
                                .setContainingModuleFilePath(
                                    LabelConstants.MODULE_DOT_BAZEL_FILE_NAME)
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("tag1")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("key1", "val1")
                                            .buildImmutable()))
                                .setDevDependency(false)
                                .setLocation(
                                    Location.fromFileLineColumn(
                                        "fake:0/modules/mymod/1.0/MODULE.bazel", 7, 12))
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("tag2")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("key2", "val2")
                                            .buildImmutable()))
                                .setDevDependency(false)
                                .setLocation(
                                    Location.fromFileLineColumn(
                                        "fake:0/modules/mymod/1.0/MODULE.bazel", 8, 12))
                                .build())
                        .build())
                .addExtensionUsage(
                    ModuleExtensionUsage.builder()
                        .setExtensionBzlFile("@rules_jvm_external//:defs.bzl")
                        .setExtensionName("maven")
                        .setIsolationKey(Optional.empty())
                        .setUsingModule(myMod)
                        .addProxy(
                            ModuleExtensionUsage.Proxy.builder()
                                .setLocation(
                                    Location.fromFileLineColumn(
                                        "fake:0/modules/mymod/1.0/MODULE.bazel", 10, 22))
                                .setDevDependency(false)
                                .setProxyName("maven")
                                .setImports(
                                    ImmutableBiMap.of(
                                        "mvn", "maven", "junit", "junit", "guava", "guava"))
                                .setContainingModuleFilePath(
                                    LabelConstants.MODULE_DOT_BAZEL_FILE_NAME)
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("dep")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("coord", "junit")
                                            .buildImmutable()))
                                .setDevDependency(false)
                                .setLocation(
                                    Location.fromFileLineColumn(
                                        "fake:0/modules/mymod/1.0/MODULE.bazel", 12, 10))
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("dep")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("coord", "guava")
                                            .buildImmutable()))
                                .setDevDependency(false)
                                .setLocation(
                                    Location.fromFileLineColumn(
                                        "fake:0/modules/mymod/1.0/MODULE.bazel", 14, 10))
                                .build())
                        .build())
                .build());
  }

  @Test
  public void testModuleExtensions_duplicateProxy_asRoot() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "myext1 = use_extension('//:defs.bzl','myext',dev_dependency=True)",
        "myext1.tag(name = 'tag1')",
        "use_repo(myext1, 'alpha')",
        "myext2 = use_extension('//:defs.bzl','myext')",
        "myext2.tag(name = 'tag2')",
        "use_repo(myext2, 'beta')",
        "myext3 = use_extension('//:defs.bzl','myext',dev_dependency=True)",
        "myext3.tag(name = 'tag3')",
        "use_repo(myext3, 'gamma')",
        "myext4 = use_extension('//:defs.bzl','myext')",
        "myext4.tag(name = 'tag4')",
        "use_repo(myext4, 'delta')");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of());

    SkyKey skyKey = ModuleFileValue.KEY_FOR_ROOT_MODULE;
    EvaluationResult<ModuleFileValue> result =
        evaluator.evaluate(ImmutableList.of(skyKey), evaluationContext);
    if (result.hasError()) {
      throw result.getError().getException();
    }
    ModuleFileValue moduleFileValue = result.get(skyKey);
    assertThat(moduleFileValue.getModule())
        .isEqualTo(
            InterimModuleBuilder.create("", "")
                .setKey(ModuleKey.ROOT)
                .addExtensionUsage(
                    ModuleExtensionUsage.builder()
                        .setExtensionBzlFile("@//:defs.bzl")
                        .setExtensionName("myext")
                        .setIsolationKey(Optional.empty())
                        .setUsingModule(ModuleKey.ROOT)
                        .addProxy(
                            ModuleExtensionUsage.Proxy.builder()
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 1, 23))
                                .setDevDependency(true)
                                .setProxyName("myext1")
                                .addImport("alpha", "alpha")
                                .setContainingModuleFilePath(
                                    LabelConstants.MODULE_DOT_BAZEL_FILE_NAME)
                                .build())
                        .addProxy(
                            ModuleExtensionUsage.Proxy.builder()
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 4, 23))
                                .setDevDependency(false)
                                .setProxyName("myext2")
                                .addImport("beta", "beta")
                                .setContainingModuleFilePath(
                                    LabelConstants.MODULE_DOT_BAZEL_FILE_NAME)
                                .build())
                        .addProxy(
                            ModuleExtensionUsage.Proxy.builder()
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 7, 23))
                                .setDevDependency(true)
                                .setProxyName("myext3")
                                .addImport("gamma", "gamma")
                                .setContainingModuleFilePath(
                                    LabelConstants.MODULE_DOT_BAZEL_FILE_NAME)
                                .build())
                        .addProxy(
                            ModuleExtensionUsage.Proxy.builder()
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 10, 23))
                                .setDevDependency(false)
                                .setProxyName("myext4")
                                .addImport("delta", "delta")
                                .setContainingModuleFilePath(
                                    LabelConstants.MODULE_DOT_BAZEL_FILE_NAME)
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("tag")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("name", "tag1")
                                            .buildImmutable()))
                                .setDevDependency(true)
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 2, 11))
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("tag")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("name", "tag2")
                                            .buildImmutable()))
                                .setDevDependency(false)
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 5, 11))
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("tag")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("name", "tag3")
                                            .buildImmutable()))
                                .setDevDependency(true)
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 8, 11))
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("tag")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("name", "tag4")
                                            .buildImmutable()))
                                .setDevDependency(false)
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 11, 11))
                                .build())
                        .build())
                .build());
  }

  @Test
  public void testModuleExtensions_duplicateProxy_asDep() throws Exception {
    FakeRegistry registry =
        registryFactory
            .newFakeRegistry("/foo")
            .addModule(
                createModuleKey("mymod", "1.0"),
                "module(name='mymod',version='1.0')",
                "myext1 = use_extension('//:defs.bzl','myext',dev_dependency=True)",
                "myext1.tag(name = 'tag1')",
                "use_repo(myext1, 'alpha')",
                "myext2 = use_extension('//:defs.bzl','myext')",
                "myext2.tag(name = 'tag2')",
                "use_repo(myext2, 'beta')",
                "myext3 = use_extension('//:defs.bzl','myext',dev_dependency=True)",
                "myext3.tag(name = 'tag3')",
                "use_repo(myext3, 'gamma')",
                "myext4 = use_extension('//:defs.bzl','myext')",
                "myext4.tag(name = 'tag4')",
                "use_repo(myext4, 'delta')");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    ModuleKey myMod = createModuleKey("mymod", "1.0");
    SkyKey skyKey = ModuleFileValue.key(myMod, null);
    EvaluationResult<ModuleFileValue> result =
        evaluator.evaluate(ImmutableList.of(skyKey), evaluationContext);
    if (result.hasError()) {
      throw result.getError().getException();
    }
    ModuleFileValue moduleFileValue = result.get(skyKey);
    assertThat(moduleFileValue.getModule())
        .isEqualTo(
            InterimModuleBuilder.create("mymod", "1.0")
                .setRegistry(registry)
                .addExtensionUsage(
                    ModuleExtensionUsage.builder()
                        .setExtensionBzlFile("@mymod//:defs.bzl")
                        .setExtensionName("myext")
                        .setIsolationKey(Optional.empty())
                        .setUsingModule(myMod)
                        .addProxy(
                            ModuleExtensionUsage.Proxy.builder()
                                .setLocation(
                                    Location.fromFileLineColumn(
                                        "fake:0/modules/mymod/1.0/MODULE.bazel", 5, 23))
                                .setDevDependency(false)
                                .setProxyName("myext2")
                                .addImport("beta", "beta")
                                .setContainingModuleFilePath(
                                    LabelConstants.MODULE_DOT_BAZEL_FILE_NAME)
                                .build())
                        .addProxy(
                            ModuleExtensionUsage.Proxy.builder()
                                .setLocation(
                                    Location.fromFileLineColumn(
                                        "fake:0/modules/mymod/1.0/MODULE.bazel", 11, 23))
                                .setDevDependency(false)
                                .setProxyName("myext4")
                                .addImport("delta", "delta")
                                .setContainingModuleFilePath(
                                    LabelConstants.MODULE_DOT_BAZEL_FILE_NAME)
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("tag")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("name", "tag2")
                                            .buildImmutable()))
                                .setDevDependency(false)
                                .setLocation(
                                    Location.fromFileLineColumn(
                                        "fake:0/modules/mymod/1.0/MODULE.bazel", 6, 11))
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("tag")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("name", "tag4")
                                            .buildImmutable()))
                                .setDevDependency(false)
                                .setLocation(
                                    Location.fromFileLineColumn(
                                        "fake:0/modules/mymod/1.0/MODULE.bazel", 12, 11))
                                .build())
                        .build())
                .build());
  }

  @Test
  public void testModuleExtensions_repoNameCollision_localRepoName() throws Exception {
    FakeRegistry registry =
        registryFactory
            .newFakeRegistry("/foo")
            .addModule(
                createModuleKey("mymod", "1.0"),
                "module(name='mymod',version='1.0')",
                "myext = use_extension('//:defs.bzl','myext')",
                "use_repo(myext, mymod='some_repo')");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    SkyKey skyKey = ModuleFileValue.key(createModuleKey("mymod", "1.0"), null);
    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(skyKey), evaluationContext);

    assertContainsEvent(
        "The repo name 'mymod' is already being used as the current module name at");
  }

  @Test
  public void testModuleExtensions_repoNameCollision_exportedRepoName() throws Exception {
    FakeRegistry registry =
        registryFactory
            .newFakeRegistry("/foo")
            .addModule(
                createModuleKey("mymod", "1.0"),
                "module(name='mymod',version='1.0')",
                "myext = use_extension('//:defs.bzl','myext')",
                "use_repo(myext, 'some_repo', again='some_repo')");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    SkyKey skyKey = ModuleFileValue.key(createModuleKey("mymod", "1.0"), null);
    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(skyKey), evaluationContext);

    assertContainsEvent(
        "The repo exported as 'some_repo' by module extension 'myext' is already imported at");
  }

  @Test
  public void testModuleExtensions_innate() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "repo = use_repo_rule('//:repo.bzl','repo')",
        "repo(name='repo_name', value='something')",
        "http_archive = use_repo_rule('@bazel_tools//:http.bzl','http_archive')",
        "http_archive(name='guava',url='guava.com')",
        "http_archive(name='vuaga',url='vuaga.com',dev_dependency=True)");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of());

    SkyKey skyKey = ModuleFileValue.KEY_FOR_ROOT_MODULE;
    EvaluationResult<ModuleFileValue> result =
        evaluator.evaluate(ImmutableList.of(skyKey), evaluationContext);
    if (result.hasError()) {
      throw result.getError().getException();
    }
    ModuleFileValue moduleFileValue = result.get(skyKey);
    assertThat(moduleFileValue.getModule())
        .isEqualTo(
            InterimModuleBuilder.create("", "")
                .setKey(ModuleKey.ROOT)
                .addExtensionUsage(
                    ModuleExtensionUsage.builder()
                        .setExtensionBzlFile("//:MODULE.bazel")
                        .setExtensionName("_repo_rules")
                        .setIsolationKey(Optional.empty())
                        .setUsingModule(ModuleKey.ROOT)
                        .addProxy(
                            ModuleExtensionUsage.Proxy.builder()
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 2, 5))
                                .setDevDependency(false)
                                .addImport("repo_name", "repo_name")
                                .setContainingModuleFilePath(
                                    LabelConstants.MODULE_DOT_BAZEL_FILE_NAME)
                                .build())
                        .addProxy(
                            ModuleExtensionUsage.Proxy.builder()
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 4, 13))
                                .setDevDependency(false)
                                .addImport("guava", "guava")
                                .setContainingModuleFilePath(
                                    LabelConstants.MODULE_DOT_BAZEL_FILE_NAME)
                                .build())
                        .addProxy(
                            ModuleExtensionUsage.Proxy.builder()
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 5, 13))
                                .setDevDependency(true)
                                .addImport("vuaga", "vuaga")
                                .setContainingModuleFilePath(
                                    LabelConstants.MODULE_DOT_BAZEL_FILE_NAME)
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("//:repo.bzl%repo")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("name", "repo_name")
                                            .put("value", "something")
                                            .buildImmutable()))
                                .setDevDependency(false)
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 2, 5))
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("@bazel_tools//:http.bzl%http_archive")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("name", "guava")
                                            .put("url", "guava.com")
                                            .buildImmutable()))
                                .setDevDependency(false)
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 4, 13))
                                .build())
                        .addTag(
                            Tag.builder()
                                .setTagName("@bazel_tools//:http.bzl%http_archive")
                                .setAttributeValues(
                                    AttributeValues.create(
                                        Dict.<String, Object>builder()
                                            .put("name", "vuaga")
                                            .put("url", "vuaga.com")
                                            .buildImmutable()))
                                .setDevDependency(true)
                                .setLocation(
                                    Location.fromFileLineColumn("/workspace/MODULE.bazel", 5, 13))
                                .build())
                        .build())
                .build());
  }

  @Test
  public void testModuleFileExecute_syntaxError() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa',version='0.1',compatibility_level=4)",
        "foo()");

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertContainsEvent("name 'foo' is not defined");
  }

  @Test
  public void testModuleFileExecute_evalError() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa',version='0.1',compatibility_level=\"4\")");

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);

    assertContainsEvent("parameter 'compatibility_level' got value of type 'string', want 'int'");
  }

  @Test
  public void validateModuleName() throws Exception {
    ModuleFileGlobals.validateModuleName("abc");
    ModuleFileGlobals.validateModuleName("a3");
    ModuleFileGlobals.validateModuleName("a.e");
    ModuleFileGlobals.validateModuleName("a.-_e");
    ModuleFileGlobals.validateModuleName("a");

    assertThrows(EvalException.class, () -> ModuleFileGlobals.validateModuleName(""));
    assertThrows(EvalException.class, () -> ModuleFileGlobals.validateModuleName("fooBar"));
    assertThrows(EvalException.class, () -> ModuleFileGlobals.validateModuleName("_foo"));
    assertThrows(EvalException.class, () -> ModuleFileGlobals.validateModuleName("foo#bar"));
    assertThrows(EvalException.class, () -> ModuleFileGlobals.validateModuleName("foo~bar"));
  }

  @Test
  public void badModuleName_module() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='f.',version='0.1')");

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);

    assertContainsEvent("invalid module name 'f.'");
  }

  @Test
  public void badModuleName_bazelDep() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "bazel_dep(name='f.',version='0.1')");

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);

    assertContainsEvent("invalid module name 'f.'");
  }

  @Test
  public void badRepoName_module() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='foo',version='0.1',repo_name='_foo')");

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);

    assertContainsEvent("invalid user-provided repo name '_foo'");
  }

  @Test
  public void badRepoName_bazelDep() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "bazel_dep(name='foo',version='0.1',repo_name='_foo')");

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);

    assertContainsEvent("invalid user-provided repo name '_foo'");
  }

  @Test
  public void badRepoName_useRepo() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "ext=use_extension('//:hello.bzl', 'ext')",
        "use_repo(ext, foo='_foo')");

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);

    assertContainsEvent("invalid user-provided repo name '_foo'");
  }

  @Test
  public void badRepoName_useRepo_assignedName() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "ext=use_extension('//:hello.bzl', 'ext')",
        "use_repo(ext, _foo='foo')");

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);

    assertContainsEvent("invalid user-provided repo name '_foo'");
  }

  @Test
  public void testBuiltinModules_forRoot() throws Exception {
    ImmutableMap<String, NonRegistryOverride> builtinModules =
        ImmutableMap.of(
            "bazel_tools",
            LocalPathOverride.create("/tools"),
            "local_config_platform",
            LocalPathOverride.create("/local_config_platform"));
    setUpWithBuiltinModules(builtinModules);
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "bazel_dep(name='foo',version='1.0')");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of());

    SkyKey skyKey = ModuleFileValue.KEY_FOR_ROOT_MODULE;
    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(ImmutableList.of(skyKey), evaluationContext);
    if (result.hasError()) {
      throw result.getError().getException();
    }
    RootModuleFileValue moduleFileValue = result.get(skyKey);
    assertThat(moduleFileValue.getModule())
        .isEqualTo(
            InterimModuleBuilder.create("", "")
                .addDep("bazel_tools", createModuleKey("bazel_tools", ""))
                .addDep("local_config_platform", createModuleKey("local_config_platform", ""))
                .addDep("foo", createModuleKey("foo", "1.0"))
                .build());
    assertThat(moduleFileValue.getOverrides()).containsExactlyEntriesIn(builtinModules);
  }

  @Test
  public void testBuiltinModules_forBuiltinModules() throws Exception {
    ImmutableMap<String, NonRegistryOverride> builtinModules =
        ImmutableMap.of(
            "bazel_tools",
            LocalPathOverride.create(rootDirectory.getRelative("tools").getPathString()),
            "local_config_platform",
            LocalPathOverride.create("/local_config_platform"));
    setUpWithBuiltinModules(builtinModules);
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "bazel_dep(name='foo',version='1.0')");
    scratch.overwriteFile(rootDirectory.getRelative("tools/WORKSPACE").getPathString());
    scratch.overwriteFile(
        rootDirectory.getRelative("tools/MODULE.bazel").getPathString(),
        "module(name='bazel_tools',version='1.0')",
        "bazel_dep(name='foo',version='2.0')");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of());

    SkyKey skyKey =
        ModuleFileValue.key(createModuleKey("bazel_tools", ""), builtinModules.get("bazel_tools"));
    EvaluationResult<ModuleFileValue> result =
        evaluator.evaluate(ImmutableList.of(skyKey), evaluationContext);
    if (result.hasError()) {
      throw result.getError().getException();
    }
    ModuleFileValue moduleFileValue = result.get(skyKey);
    assertThat(moduleFileValue.getModule())
        .isEqualTo(
            InterimModuleBuilder.create("bazel_tools", "1.0")
                .setKey(createModuleKey("bazel_tools", ""))
                .addDep("local_config_platform", createModuleKey("local_config_platform", ""))
                .addDep("foo", createModuleKey("foo", "2.0"))
                .build());
  }

  @Test
  public void moduleRepoName() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa',version='0.1',repo_name='bbb')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    if (result.hasError()) {
      fail(result.getError().toString());
    }
    RootModuleFileValue rootModuleFileValue = result.get(ModuleFileValue.KEY_FOR_ROOT_MODULE);
    assertThat(rootModuleFileValue.getModule())
        .isEqualTo(
            InterimModuleBuilder.create("aaa", "0.1")
                .setKey(ModuleKey.ROOT)
                .setRepoName("bbb")
                .build());
  }

  @Test
  public void moduleRepoName_conflict() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa',version='0.1',repo_name='bbb')",
        "bazel_dep(name='bbb',version='1.0')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);

    assertContainsEvent("The repo name 'bbb' is already being used as the module's own repo name");
  }

  @Test
  public void module_calledTwice() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa',version='0.1',repo_name='bbb')",
        "module(name='aaa',version='0.1',repo_name='bbb')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);

    assertContainsEvent("the module() directive can only be called once");
  }

  @Test
  public void module_calledLate() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "use_extension('//:extensions.bzl', 'my_ext')",
        "module(name='aaa',version='0.1',repo_name='bbb')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);

    assertContainsEvent("if module() is called, it must be called before any other functions");
  }

  @Test
  public void restrictedSyntax() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "if 3+5>7: module(name='aaa',version='0.1',repo_name='bbb')");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);

    assertContainsEvent(
        "`if` statements are not allowed in MODULE.bazel files. You may use an `if` expression for"
            + " simple cases");
  }

  @Test
  public void isolatedUsageWithoutImports() throws Exception {
    PrecomputedValue.STARLARK_SEMANTICS.set(
        differencer,
        StarlarkSemantics.builder()
            .setBool(BuildLanguageOptions.ENABLE_BZLMOD, true)
            .setBool(BuildLanguageOptions.EXPERIMENTAL_ISOLATED_EXTENSION_USAGES, true)
            .build());

    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "isolated_ext = use_extension('//:extensions.bzl', 'my_ext', isolate = True)");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertThat(result.hasError()).isTrue();
    assertThat(result.getError().toString())
        .contains(
            "the isolated usage at /workspace/MODULE.bazel:1:29 of extension my_ext defined in "
                + "@//:extensions.bzl has no effect as no repositories are imported from it. "
                + "Either import one or more repositories generated by the extension with "
                + "use_repo or remove the usage.");
  }

  @Test
  public void isolatedUsageNotExported() throws Exception {
    PrecomputedValue.STARLARK_SEMANTICS.set(
        differencer,
        StarlarkSemantics.builder()
            .setBool(BuildLanguageOptions.ENABLE_BZLMOD, true)
            .setBool(BuildLanguageOptions.EXPERIMENTAL_ISOLATED_EXTENSION_USAGES, true)
            .build());

    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "use_extension('//:extensions.bzl', 'my_ext', isolate = True)");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertContainsEvent(
        "Isolated extension usage at /workspace/MODULE.bazel:1:14 must be assigned to a "
            + "top-level variable");
  }

  @Test
  public void isolatedUsage_notEnabled() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "use_extension('//:extensions.bzl', 'my_ext', isolate = True)");
    FakeRegistry registry = registryFactory.newFakeRegistry("/foo");
    ModuleFileFunction.REGISTRIES.set(differencer, ImmutableSet.of(registry.getUrl()));

    reporter.removeHandler(failFastHandler); // expect failures
    evaluator.evaluate(ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertContainsEvent(
        "Error in use_extension: in call to use_extension(), parameter 'isolate' is experimental "
            + "and thus unavailable with the current flags. It may be enabled by setting "
            + "--experimental_isolated_extension_usages");
  }

  @Test
  public void testNoUsages() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa')",
        "http_archive = use_repo_rule('@bazel_tools//tools/build_defs/repo:http.bzl',"
            + " 'http_archive')");

    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertThat(result.hasError()).isFalse();
  }

  @Test
  public void testInvalidRepoInPatches() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa')",
        "single_version_override(",
        "    module_name = 'bbb',",
        "    version = '1.0',",
        "    patches = ['@unknown_repo//:patch.bzl'],",
        ")");

    reporter.removeHandler(failFastHandler);
    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertThat(result.hasError()).isTrue();

    assertContainsEvent(
        "Error in single_version_override: invalid label in 'patches': only patches in the main"
            + " repository can be applied, not from '@unknown_repo'");
  }

  @Test
  public void testInvalidUseExtensionLabel() throws Exception {
    scratch.overwriteFile(
        rootDirectory.getRelative("MODULE.bazel").getPathString(),
        "module(name='aaa')",
        "use_extension('@foo/bar:extensions.bzl', 'my_ext')");

    reporter.removeHandler(failFastHandler);
    EvaluationResult<RootModuleFileValue> result =
        evaluator.evaluate(
            ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext);
    assertThat(result.hasError()).isTrue();

    assertContainsEvent(
        "Error in use_extension: invalid label \"@foo/bar:extensions.bzl\": invalid repository"
            + " name 'foo/bar:extensions.bzl': repo names may contain only A-Z, a-z, 0-9, '-',"
            + " '_', '.' and '~' and must not start with '~'");
  }
}
