// Copyright 2015 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.packages;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.events.Reporter;
import com.google.devtools.build.lib.packages.util.PackageFactoryApparatus;
import com.google.devtools.build.lib.packages.util.PackageFactoryTestBase;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.testutil.MoreAsserts;
import com.google.devtools.build.lib.testutil.TestUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Unit tests for {@code PackageFactory}.
 */
@RunWith(JUnit4.class)
public class PackageFactoryTest extends PackageFactoryTestBase {

  @Test
  public void testCreatePackage() throws Exception {
    Path buildFile = scratch.file("/pkgname/BUILD", "# empty build file ");
    Package pkg = packages.createPackage("pkgname", buildFile);
    assertThat(pkg.getName()).isEqualTo("pkgname");
    assertThat(Sets.newHashSet(pkg.getTargets(Rule.class))).isEmpty();
  }

  @Test
  public void testCreatePackageIsolatedFromOuterErrors() throws Exception {
    ExecutorService e = Executors.newCachedThreadPool();

    final Semaphore beforeError = new Semaphore(0);
    final Semaphore afterError = new Semaphore(0);
    Reporter reporter = new Reporter(new EventBus());
    ParsingTracker parser = new ParsingTracker(beforeError, afterError, reporter);
    final Logger log = Logger.getLogger(PackageFactory.class.getName());
    log.addHandler(parser);
    Level originalLevel = log.getLevel();
    log.setLevel(Level.FINE);

    e.execute(new ErrorReporter(reporter, beforeError, afterError));
    e.execute(parser);

    // wait for all to finish
    e.shutdown();
    assertThat(e.awaitTermination(TestUtils.WAIT_TIMEOUT_MILLISECONDS, TimeUnit.MILLISECONDS))
        .isTrue();
    log.removeHandler(parser);
    log.setLevel(originalLevel);
    assertThat(parser.hasParsed()).isTrue();
  }

  @Test
  public void testBadRuleName() throws Exception {
    events.setFailFast(false);

    Path buildFile = scratch.file("/badrulename/BUILD", "cc_library(name = 3)");
    Package pkg = packages.createPackage("badrulename", buildFile);

    events.assertContainsError("cc_library 'name' attribute must be a string");
    assertThat(pkg.containsErrors()).isTrue();
  }

  @Test
  public void testNoRuleName() throws Exception {
    events.setFailFast(false);

    Path buildFile = scratch.file("/badrulename/BUILD", "cc_library()");
    Package pkg = packages.createPackage("badrulename", buildFile);

    events.assertContainsError("cc_library rule has no 'name' attribute");
    assertThat(pkg.containsErrors()).isTrue();
  }

  @Test
  public void testBadPackageName() throws Exception {
    try {
      // PathFragment parsing de-double slashes, and normalization of the path fragment removes
      // up reference (/../), so use triple dot /.../ that will always be a forbidden package name.
      packages.createPackage("not even a legal/.../label",
          emptyBuildFile("not even a legal/.../label"));
      fail();
    } catch (NoSuchPackageException e) {
      assertThat(e)
          .hasMessageThat()
          .contains(
              "no such package 'not even a legal/.../label': "
                  + "illegal package name: 'not even a legal/.../label' ");
    }
  }

  @Test
  public void testColonInExportsFilesTargetName() throws Exception {
    events.setFailFast(false);
    Path path =
        scratch.file(
            "/googledata/cafe/BUILD",
            "exports_files(['houseads/house_ads:ca-aol_parenting_html'])");
    Package pkg = packages.createPackage("googledata/cafe", path);
    events.assertContainsError("target names may not contain ':'");
    assertThat(pkg.getTargets(FileTarget.class).toString())
        .doesNotContain("houseads/house_ads:ca-aol_parenting_html");
    assertThat(pkg.containsErrors()).isTrue();
  }

  @Test
  public void testPackageNameWithPROTECTEDIsOk() throws Exception {
    events.setFailFast(false);
    // One "PROTECTED":
    assertThat(isValidPackageName("foo/PROTECTED/bar")).isTrue();
    // Multiple "PROTECTED"s:
    assertThat(isValidPackageName("foo/PROTECTED/bar/PROTECTED/wiz")).isTrue();
  }

  @Test
  public void testDuplicateRuleName() throws Exception {
    events.setFailFast(false);
    Path buildFile =
        scratch.file(
            "/duplicaterulename/BUILD",
            "# -*- python -*-",
            "proto_library(name = 'spell_proto', srcs = ['spell.proto'], cc_api_version = 2)",
            "cc_library(name = 'spell_proto')");
    Package pkg = packages.createPackage("duplicaterulename", buildFile);

    events.assertContainsError(
        "cc_library rule 'spell_proto' in package "
            + "'duplicaterulename' conflicts with existing proto_library rule");
    assertThat(pkg.containsErrors()).isTrue();
  }

  @Test
  public void testDuplicatedDependencies() throws Exception {
    events.setFailFast(false);
    Path buildFile =
        scratch.file(
            "/has_dupe/BUILD",
            "cc_library(name='dep')",
            "cc_library(name='has_dupe', deps=[':dep', ':dep'])");

    Package pkg = packages.createPackage("has_dupe", buildFile);
    events.assertContainsError(
        "Label '//has_dupe:dep' is duplicated in the 'deps' " + "attribute of rule 'has_dupe'");
    assertThat(pkg.containsErrors()).isTrue();
    assertThat(pkg.getRule("has_dupe")).isNotNull();
    assertThat(pkg.getRule("dep")).isNotNull();
    assertThat(pkg.getRule("has_dupe").containsErrors()).isTrue();
    assertThat(pkg.getRule("dep").containsErrors()).isTrue(); // because all rules in an
    // errant package are
    // themselves errant.
  }

  @Test
  public void testPrefixWithinSameRule1() throws Exception {
    events.setFailFast(false);
    Path buildFile =
        scratch.file(
            "/fruit/orange/BUILD",
            "genrule(name='orange', srcs=[], outs=['a', 'a/b'], cmd='')");

    packages.createPackage("fruit/orange", buildFile);
    events.assertContainsError("rule 'orange' has conflicting output files 'a/b' and 'a");
  }

  @Test
  public void testPrefixWithinSameRule2() throws Exception {
    events.setFailFast(false);
    Path buildFile =
        scratch.file(
            "/fruit/orange/BUILD",
            "genrule(name='orange', srcs=[], outs=['a/b', 'a'], cmd='')");

    packages.createPackage("fruit/orange", buildFile);
    events.assertContainsError("rule 'orange' has conflicting output files 'a' and 'a/b");
  }

  @Test
  public void testPrefixBetweenRules1() throws Exception {
    events.setFailFast(false);
    Path buildFile =
        scratch.file(
            "/fruit/kiwi/BUILD",
            "genrule(name='kiwi1', srcs=[], outs=['a'], cmd='')",
            "genrule(name='kiwi2', srcs=[], outs=['a/b'], cmd='')");
    packages.createPackage("fruit/kiwi", buildFile);
    events.assertContainsError(
        "output file 'a/b' of rule 'kiwi2' conflicts " + "with output file 'a' of rule 'kiwi1'");
  }

  @Test
  public void testPrefixBetweenRules2() throws Exception {
    events.setFailFast(false);
    Path buildFile =
        scratch.file(
            "/fruit/kiwi/BUILD",
            "genrule(name='kiwi1', srcs=[], outs=['a/b'], cmd='')",
            "genrule(name='kiwi2', srcs=[], outs=['a'], cmd='')");
    packages.createPackage("fruit/kiwi", buildFile);
    events.assertContainsError(
        "output file 'a' of rule 'kiwi2' conflicts " + "with output file 'a/b' of rule 'kiwi1'");
  }

  @Test
  public void testPackageConstant() throws Exception {
    Path buildFile =
        scratch.file("/pina/BUILD", "cc_library(name=PACKAGE_NAME + '-colada')");

    Package pkg =
        packages.createPackage(
            "pina", buildFile, "--incompatible_package_name_is_a_function=false");
    events.assertNoWarningsOrErrors();
    assertThat(pkg.containsErrors()).isFalse();
    assertThat(pkg.getRule("pina-colada")).isNotNull();
    assertThat(pkg.getRule("pina-colada").containsErrors()).isFalse();
    assertThat(Sets.newHashSet(pkg.getTargets(Rule.class)).size()).isSameAs(1);
  }

  @Test
  public void testPackageConstantIsForbidden() throws Exception {
    events.setFailFast(false);
    Path buildFile = scratch.file("/pina/BUILD", "cc_library(name=PACKAGE_NAME + '-colada')");
    packages.createPackage("pina", buildFile, "--incompatible_package_name_is_a_function=true");
    events.assertContainsError("The value 'PACKAGE_NAME' has been removed");
  }

  @Test
  public void testPackageNameFunction() throws Exception {
    Path buildFile = scratch.file("/pina/BUILD", "cc_library(name=package_name() + '-colada')");

    Package pkg = packages.createPackage("pina", buildFile);
    events.assertNoWarningsOrErrors();
    assertThat(pkg.containsErrors()).isFalse();
    assertThat(pkg.getRule("pina-colada")).isNotNull();
    assertThat(pkg.getRule("pina-colada").containsErrors()).isFalse();
    assertThat(Sets.newHashSet(pkg.getTargets(Rule.class)).size()).isSameAs(1);
  }

  @Test
  public void testPackageConstantInExternalRepository() throws Exception {
    Path buildFile =
        scratch.file(
            "/external/a/b/BUILD",
            "genrule(name='c', srcs=[], outs=['ao'], cmd=REPOSITORY_NAME + ' ' + PACKAGE_NAME)");
    Package pkg =
        packages.createPackage(
            PackageIdentifier.create("@a", PathFragment.create("b")),
            buildFile,
            events.reporter(),
            "--incompatible_package_name_is_a_function=false");
    Rule c = pkg.getRule("c");
    assertThat(AggregatingAttributeMapper.of(c).get("cmd", Type.STRING)).isEqualTo("@a b");
  }

  @Test
  public void testPackageConstantInExternalRepositoryIsForbidden() throws Exception {
    events.setFailFast(false);
    Path buildFile =
        scratch.file(
            "/external/a/b/BUILD", "genrule(name='c', srcs=[], outs=['ao'], cmd=REPOSITORY_NAME)");
    packages.createPackage(
        PackageIdentifier.create("@a", PathFragment.create("b")),
        buildFile,
        events.reporter(),
        "--incompatible_package_name_is_a_function=true");
    events.assertContainsError("The value 'REPOSITORY_NAME' has been removed");
  }

  @Test
  public void testPackageFunctionInExternalRepository() throws Exception {
    Path buildFile =
        scratch.file(
            "/external/a/b/BUILD",
            "genrule(name='c', srcs=[], outs=['o'], cmd=repository_name() + ' ' + package_name())");
    Package pkg =
        packages.createPackage(
            PackageIdentifier.create("@a", PathFragment.create("b")), buildFile, events.reporter());
    Rule c = pkg.getRule("c");
    assertThat(AggregatingAttributeMapper.of(c).get("cmd", Type.STRING)).isEqualTo("@a b");
  }

  @Test
  public void testMultipleDuplicateRuleName() throws Exception {
    events.setFailFast(false);

    Path buildFile =
        scratch.file(
            "/multipleduplicaterulename/BUILD",
            "# -*- python -*-",
            "proto_library(name = 'spellcheck_proto',",
            "         srcs = ['spellcheck.proto'],",
            "         cc_api_version = 2)",
            "cc_library(name = 'spellcheck_proto')",
            "proto_library(name = 'spell_proto',",
            "         srcs = ['spell.proto'],",
            "         cc_api_version = 2)",
            "cc_library(name = 'spell_proto')");
    Package pkg = packages.createPackage("multipleduplicaterulename", buildFile);

    events.assertContainsError(
        "cc_library rule 'spellcheck_proto' in package "
            + "'multipleduplicaterulename' conflicts with existing proto_library rule");
    events.assertContainsError(
        "cc_library rule 'spell_proto' in package "
            + "'multipleduplicaterulename' conflicts with existing proto_library rule");
    assertThat(pkg.containsErrors()).isTrue();
  }

  @Test
  public void testBuildFileTargetExists() throws Exception {
    Path buildFile = scratch.file("/foo/BUILD", "");
    Package pkg = packages.createPackage("foo", buildFile);

    Target target = pkg.getTarget("BUILD");
    assertThat(target.getName()).isEqualTo("BUILD");

    // Test that it's memoized:
    assertThat(pkg.getTarget("BUILD")).isSameAs(target);
  }

  @Test
  public void testCreationOfInputFiles() throws Exception {
    Path buildFile =
        scratch.file(
            "/foo/BUILD",
            "exports_files(['Z'])",
            "cc_library(name='W', deps=['X', 'Y'])",
            "cc_library(name='X', srcs=['X'])",
            "cc_library(name='Y')");
    Package pkg = packages.createPackage("foo", buildFile);
    assertThat(pkg.containsErrors()).isFalse();

    // X is a rule with a circular self-dependency.
    assertThat(pkg.getTarget("X").getClass()).isSameAs(Rule.class);

    // Y is a rule
    assertThat(pkg.getTarget("Y").getClass()).isSameAs(Rule.class);

    // Z is a file
    assertThat(pkg.getTarget("Z").getClass()).isSameAs(InputFile.class);

    // A is nothing
    try {
      pkg.getTarget("A");
      fail();
    } catch (NoSuchTargetException e) {
      assertThat(e)
          .hasMessage(
              "no such target '//foo:A': "
                  + "target 'A' not declared in package 'foo' defined by /foo/BUILD");
    }

    // These are the only input files: BUILD, Z
    Set<String> inputFiles = Sets.newTreeSet();
    for (InputFile inputFile : pkg.getTargets(InputFile.class)) {
      inputFiles.add(inputFile.getName());
    }
    assertThat(Lists.newArrayList(inputFiles)).containsExactly("BUILD", "Z").inOrder();
  }

  @Test
  public void testThirdPartyLicenseError() throws Exception {
    events.setFailFast(false);
    Path buildFile =
        scratch.file("/third_party/foo/BUILD", "# line 1", "cc_library(name='bar')", "# line 3");
    Package pkg = packages.createPackage("third_party/foo", buildFile);
    events.assertContainsError(
        "third-party rule '//third_party/foo:bar' lacks a license "
            + "declaration with one of the following types: "
            + "notice, reciprocal, permissive, restricted, unencumbered, by_exception_only");
    assertThat(pkg.containsErrors()).isTrue();
  }

  @Test
  public void testThirdPartyLicenseExportsFileError() throws Exception {
    events.setFailFast(false);
    Path buildFile = scratch.file("/third_party/foo/BUILD", "exports_files(['bar'])");
    Package pkg = packages.createPackage("third_party/foo", buildFile);
    events.assertContainsError(
        "third-party file 'bar' lacks a license "
            + "declaration with one of the following types: "
            + "notice, reciprocal, permissive, restricted, unencumbered, by_exception_only");
    assertThat(pkg.containsErrors()).isTrue();
  }

  @Test
  public void testDuplicateRuleIsNotAddedToPackage() throws Exception {
    events.setFailFast(false);
    Path path =
        scratch.file(
            "/dup/BUILD",
            "proto_library(name = 'dup_proto',",
            "              srcs  = ['dup.proto'],",
            "              cc_api_version = 2)",
            "",
            "cc_library(name = 'dup_proto',",
            "           srcs = ['dup.pb.cc', 'dup.pb.h'])");
    Package pkg = packages.createPackage("dup", path);
    events.assertContainsError(
        "cc_library rule 'dup_proto' in package 'dup' "
            + "conflicts with existing proto_library rule");
    assertThat(pkg.containsErrors()).isTrue();

    Rule dupProto = pkg.getRule("dup_proto");
    // Check that the first rule of the given name "wins", and that each of the
    // "winning" rule's outputs is a member of the package.
    assertThat(dupProto.getRuleClass()).isEqualTo("proto_library");
    for (OutputFile out : dupProto.getOutputFiles()) {
      assertThat(pkg.getTargets(FileTarget.class)).contains(out);
    }
  }

  @Test
  public void testConflictingRuleDoesNotUpdatePackage() throws Exception {
    events.setFailFast(false);

    // In this test, rule2's outputs conflict with rule1, so rule2 is rejected.
    // However, we must check that neither rule2, nor any of its inputs or
    // outputs is a member of the package, and that the conflicting output file
    // "out2" still has rule1 as its getGeneratingRule().
    Path path =
        scratch.file(
            "/conflict/BUILD",
            "genrule(name = 'rule1',",
            "        cmd = '',",
            "        srcs = ['in1', 'in2'],",
            "        outs = ['out1', 'out2'])",
            "genrule(name = 'rule2',",
            "        cmd = '',",
            "        srcs = ['in3', 'in4'],",
            "        outs = ['out3', 'out2'])");
    Package pkg = packages.createPackage("conflict", path);
    events.assertContainsError(
        "generated file 'out2' in rule 'rule2' "
            + "conflicts with existing generated file from rule 'rule1'");
    assertThat(pkg.containsErrors()).isTrue();

    assertThat(pkg.getRule("rule2")).isNull();

    // Ensure that rule2's "out2" didn't overwrite rule1's:
    assertThat(((OutputFile) pkg.getTarget("out2")).getGeneratingRule())
        .isSameAs(pkg.getRule("rule1"));

    // None of rule2, its inputs, or its outputs should belong to pkg:
    List<Target> found = new ArrayList<>();
    for (String targetName : ImmutableList.of("rule2", "in3", "in4", "out3")) {
      try {
        found.add(pkg.getTarget(targetName));
        // No fail() here: if there's no exception, we add the name to a list
        // and we check below that it's empty.
      } catch (NoSuchTargetException e) {
        /* good! */
      }
    }
    assertThat(found).isEmpty();
  }

  // Was: Regression test for bug "Rules declared after an error in
  // a package should be considered 'in error'".
  // Now: Regression test for bug "Why aren't ERRORS considered
  // fatal?*"
  @Test
  public void testAllRulesInErrantPackageAreInError() throws Exception {
    events.setFailFast(false);
    Path path =
        scratch.file(
            "/error/BUILD",
            "genrule(name = 'rule1',",
            "        cmd = ':',",
            "        outs = ['out.1'])",
            "list = ['bad']",
            "PopulateList(list)", // undefined => error
            "genrule(name = 'rule2',",
            "        cmd = ':',",
            "        outs = list)");
    Package pkg = packages.createPackage("error", path);
    events.assertContainsError("name 'PopulateList' is not defined");

    assertThat(pkg.containsErrors()).isTrue();

    // rule1 would be fine but is still marked as in error:
    assertThat(pkg.getRule("rule1").containsErrors()).isTrue();

    // rule2 is considered "in error" because it's after an error.
    // Indeed, it has the wrong "outs" set because the call to PopulateList
    // failed.
    Rule rule2 = pkg.getRule("rule2");
    assertThat(rule2.containsErrors()).isTrue();
    assertThat(Sets.newHashSet(rule2.getOutputFiles()))
        .isEqualTo(Sets.newHashSet(pkg.getTarget("bad")));
  }

  @Test
  public void testHelpfulErrorForMissingExportsFiles() throws Exception {
    Path path = scratch.file("/x/BUILD", "cc_library(name='x', srcs=['x.cc'])");
    scratch.file("/x/x.cc");
    scratch.file("/x/y.cc");
    scratch.file("/x/dir/dummy");

    Package pkg = packages.createPackage("x", path);

    assertThat(pkg.getTarget("x.cc")).isNotNull(); // existing and mentioned.

    try {
      pkg.getTarget("y.cc"); // existing but not mentioned.
      fail();
    } catch (NoSuchTargetException e) {
      assertThat(e)
          .hasMessage(
              "no such target '//x:y.cc': "
                  + "target 'y.cc' not declared in package 'x'; "
                  + "however, a source file of this name exists.  "
                  + "(Perhaps add 'exports_files([\"y.cc\"])' to x/BUILD?) "
                  + "defined by /x/BUILD");
    }

    try {
      pkg.getTarget("z.cc"); // non-existent and unmentioned.
      fail();
    } catch (NoSuchTargetException e) {
      assertThat(e)
          .hasMessage(
              "no such target '//x:z.cc': "
                  + "target 'z.cc' not declared in package 'x' (did you mean 'x.cc'?) "
                  + "defined by /x/BUILD");
    }

    try {
      pkg.getTarget("dir"); // existing directory but not mentioned.
      fail();
    } catch (NoSuchTargetException e) {
      assertThat(e)
          .hasMessage(
              "no such target '//x:dir': target 'dir' not declared in package 'x'; "
                  + "however, a source directory of this name exists.  "
                  + "(Perhaps add 'exports_files([\"dir\"])' to x/BUILD, "
                  + "or define a filegroup?) defined by /x/BUILD");
    }
  }

  @Test
  public void testTestSuitesImplicitlyDependOnAllRulesInPackage() throws Exception {
    Path path =
        scratch.file(
            "/x/BUILD",
            "java_test(name='j')",
            "test_suite(name='t1')",
            "test_suite(name='t2', tests=['//foo'])",
            "test_suite(name='t3', tests=['//foo'])",
            "cc_test(name='c')");
    Package pkg = packages.createPackage("x", path);

    // Things to note:
    // - the t1 refers to both :j and :c, even though :c is a forward reference.
    // - $implicit_tests is empty unless tests=[]

    assertThat(attributes(pkg.getRule("t1")).get("$implicit_tests", BuildType.LABEL_LIST))
        .containsExactlyElementsIn(
            Sets.newHashSet(
                Label.parseAbsolute("//x:c", ImmutableMap.of()),
                Label.parseAbsolute("//x:j", ImmutableMap.of())));
    assertThat(attributes(pkg.getRule("t2")).get("$implicit_tests", BuildType.LABEL_LIST))
        .isEmpty();
    assertThat(attributes(pkg.getRule("t3")).get("$implicit_tests", BuildType.LABEL_LIST))
        .isEmpty();
  }

  @Test
  public void testGlobDirectoryExclusion() throws Exception {
    emptyFile("/fruit/data/apple");
    emptyFile("/fruit/data/pear");
    emptyFile("/fruit/data/berry/black");
    emptyFile("/fruit/data/berry/blue");
    Path file =
        scratch.file(
            "/fruit/BUILD",
            "cc_library(name = 'yes', srcs = glob(['data/*']))",
            "cc_library(name = 'no',  srcs = glob(['data/*'], exclude_directories=0))");
    Package pkg = packages.eval("fruit", file);
    events.assertNoWarningsOrErrors();
    List<Label> yesFiles = attributes(pkg.getRule("yes")).get("srcs", BuildType.LABEL_LIST);
    List<Label> noFiles = attributes(pkg.getRule("no")).get("srcs", BuildType.LABEL_LIST);

    assertThat(yesFiles)
        .containsExactly(
            Label.parseAbsolute("@//fruit:data/apple", ImmutableMap.of()),
            Label.parseAbsolute("@//fruit:data/pear", ImmutableMap.of()));

    assertThat(noFiles)
        .containsExactly(
            Label.parseAbsolute("@//fruit:data/apple", ImmutableMap.of()),
            Label.parseAbsolute("@//fruit:data/pear", ImmutableMap.of()),
            Label.parseAbsolute("@//fruit:data/berry", ImmutableMap.of()));
  }

  // TODO(bazel-team): This is really a test for GlobCache.
  @Test
  public void testRecursiveGlob() throws Exception {
    emptyFile("/rg/a.cc");
    emptyFile("/rg/foo/bar.cc");
    emptyFile("/rg/foo/foo.cc");
    emptyFile("/rg/foo/wiz/bam.cc");
    emptyFile("/rg/foo/wiz/bum.cc");
    emptyFile("/rg/foo/wiz/quid/gav.cc");
    Path file =
        scratch.file(
            "/rg/BUILD",
            "cc_library(name = 'ri', srcs = glob(['**/*.cc']))",
            "cc_library(name = 're', srcs = glob(['*.cc'], exclude=['**/*.c']))");
    Package pkg = packages.eval("rg", file);
    events.assertNoWarningsOrErrors();

    assertEvaluates(
        pkg,
        ImmutableList.of(
            "BUILD",
            "a.cc",
            "foo",
            "foo/bar.cc",
            "foo/foo.cc",
            "foo/wiz",
            "foo/wiz/bam.cc",
            "foo/wiz/bum.cc",
            "foo/wiz/quid",
            "foo/wiz/quid/gav.cc"),
        "**");

    assertEvaluates(
        pkg,
        ImmutableList.of(
            "a.cc",
            "foo/bar.cc",
            "foo/foo.cc",
            "foo/wiz/bam.cc",
            "foo/wiz/bum.cc",
            "foo/wiz/quid/gav.cc"),
        "**/*.cc");
    assertEvaluates(
        pkg, ImmutableList.of("foo/bar.cc", "foo/wiz/bam.cc", "foo/wiz/bum.cc"), "**/b*.cc");
    assertEvaluates(
        pkg,
        ImmutableList.of(
            "foo/bar.cc", "foo/foo.cc", "foo/wiz/bam.cc", "foo/wiz/bum.cc", "foo/wiz/quid/gav.cc"),
        "**/*/*.cc");
    assertEvaluates(pkg, ImmutableList.of("foo/wiz/quid/gav.cc"), "foo/**/quid/*.cc");

    assertEvaluates(
        pkg,
        Collections.<String>emptyList(),
        ImmutableList.of("*.cc", "*/*.cc", "*/*/*.cc"),
        ImmutableList.of("**/*.cc"));
    assertEvaluates(
        pkg,
        Collections.<String>emptyList(),
        ImmutableList.of("**/*.cc"),
        ImmutableList.of("**/*.cc"));
    assertEvaluates(
        pkg,
        Collections.<String>emptyList(),
        ImmutableList.of("**/*.cc"),
        ImmutableList.of("*.cc", "*/*.cc", "*/*/*.cc", "*/*/*/*.cc"));
    assertEvaluates(
        pkg,
        Collections.<String>emptyList(),
        ImmutableList.of("**"),
        ImmutableList.of("*", "*/*", "*/*/*", "*/*/*/*"));
    assertEvaluates(
        pkg,
        ImmutableList.of(
            "foo/bar.cc", "foo/foo.cc", "foo/wiz/bam.cc", "foo/wiz/bum.cc", "foo/wiz/quid/gav.cc"),
        ImmutableList.of("**/*.cc"),
        ImmutableList.of("*.cc"));
    assertEvaluates(
        pkg,
        ImmutableList.of("a.cc", "foo/wiz/bam.cc", "foo/wiz/bum.cc", "foo/wiz/quid/gav.cc"),
        ImmutableList.of("**/*.cc"),
        ImmutableList.of("*/*.cc"));
    assertEvaluates(
        pkg,
        ImmutableList.of("a.cc", "foo/bar.cc", "foo/foo.cc", "foo/wiz/quid/gav.cc"),
        ImmutableList.of("**/*.cc"),
        ImmutableList.of("**/wiz/*.cc"));
  }

  @Test
  public void testInsufficientArgumentGlobErrors() throws Exception {
    events.setFailFast(false);
    assertGlobFails(
        "glob()",
        "insufficient arguments received by glob(include: sequence of strings, "
            + "*, exclude: sequence of strings = [], exclude_directories: int = 1) "
            + "(got 0, expected at least 1)");
  }

  @Test
  public void testGlobUnamedExclude() throws Exception {
    events.setFailFast(false);
    assertGlobFails(
        "glob(['a'], ['b'])",
        "too many (2) positional arguments in call to glob(include: sequence of strings, "
            + "*, exclude: sequence of strings = [], exclude_directories: int = 1)");
  }

  @Test
  public void testTooManyArgumentsGlobErrors() throws Exception {
    events.setFailFast(false);
    assertGlobFails(
        "glob(1,2,3,4)",
        "too many (4) positional arguments in call to glob(include: sequence of strings, "
            + "*, exclude: sequence of strings = [], exclude_directories: int = 1)");
  }

  @Test
  public void testGlobEnforcesListArgument() throws Exception {
    events.setFailFast(false);
    assertGlobFails(
        "glob(1, exclude=2)",
        "argument 'include' has type 'int', but should be 'sequence'\n"
            + "in call to builtin function glob(include, *, exclude, exclude_directories)");
  }

  @Test
  public void testGlobEnforcesListOfStringsArguments() throws Exception {
    events.setFailFast(false);
    assertGlobFails(
        "glob(['a', 'b'], exclude=['c', 42])",
        "expected value of type 'string' for element 1 of 'glob' argument, but got 42 (int)");
  }

  @Test
  public void testGlobNegativeTest() throws Exception {
    // Negative test that assertGlob does throw an error when asserting against the wrong values.
    try {
      assertGlobMatches(
          /*result=*/ ImmutableList.of("Wombat1.java", "This_file_doesn_t_exist.java"),
          /*includes=*/ ImmutableList.of("W*", "subdir"),
          /*excludes=*/ ImmutableList.<String>of(),
          /* excludeDirs= */ true);
      fail();
    } catch (IllegalArgumentException e) {
      assertThat(e).hasMessage("ERROR /globs/BUILD:2:73: name 'this_will_fail' is not defined");
    }
  }

  @Test
  public void testGlobExcludeDirectories() throws Exception {
    assertGlobMatches(
        /*result=*/ ImmutableList.of("Wombat1.java", "Wombat2.java"),
        /*includes=*/ ImmutableList.of("W*", "subdir"),
        /*excludes=*/ ImmutableList.<String>of(),
        /* excludeDirs= */ true);
  }

  @Test
  public void testGlobDoesNotExcludeDirectories() throws Exception {
    assertGlobMatches(
        /*result=*/ ImmutableList.of("Wombat1.java", "Wombat2.java", "subdir"),
        /*includes=*/ ImmutableList.of("W*", "subdir"),
        /*excludes=*/ ImmutableList.<String>of(),
        /* excludeDirs= */ false);
  }

  @Test
  public void testGlobWithEmptyExcludedList() throws Exception {
    assertGlobMatches(
        /*result=*/ ImmutableList.of("Wombat1.java", "Wombat2.java"),
        /*includes=*/ ImmutableList.of("W*"),
        /*excludes=*/ Collections.<String>emptyList(),
        /* excludeDirs= */ false);
  }

  @Test
  public void testGlobWithQuestionMarkProducesError() throws Exception {
    assertGlobProducesError("Wombat?.java", true);
  }

  @Test
  public void testGlobWithoutQuestionMarkDoesntProduceError() throws Exception {
    assertGlobProducesError("Wombat*.java", false);
  }

  @Test
  public void testGlobWithNonMatchingExcludedList() throws Exception {
    assertGlobMatches(
        /*result=*/ ImmutableList.of("Wombat1.java"),
        /*includes=*/ ImmutableList.of("W*"),
        /*excludes=*/ ImmutableList.of("*2*"),
        /* excludeDirs= */ false);
  }

  @Test
  public void testGlobWithTwoMatchingGlobExpressionsAndNonmatchingExclusion() throws Exception {
    assertGlobMatches(
        /*result=*/ ImmutableList.of("Wombat1.java", "subdir/Wombat3.java"),
        /*includes=*/ ImmutableList.of("W*", "subdir/W*"),
        /*excludes=*/ ImmutableList.of("*2*"),
        /* excludeDirs= */ false);
  }

  @Test
  public void testGlobWithSubdirMatchAndExclusion() throws Exception {
    assertGlobMatches(
        /*result=*/ ImmutableList.of("subdir/Wombat3.java"),
        /*includes=*/ ImmutableList.of("W*", "subdir/W*"),
        /*excludes=*/ ImmutableList.of("Wombat*.java"),
        /* excludeDirs= */ false);
  }

  @Test
  public void testBadCharacterInGlob() throws Exception {
   events.setFailFast(false);
   assertGlobFails("glob(['?'])", "glob pattern '?' contains forbidden '?' wildcard");
  }

  /**
   * Tests that a glob evaluation that encounters an I/O error throws instead of constructing a
   * package.
   */
  @Test
  public void testGlobWithIOErrors() throws Exception {
    events.setFailFast(false);

    scratch.dir("/pkg");
    scratch.dir("/pkg/globs");
    Path unreadableSubdir = scratch.resolve("/pkg/globs/unreadable_subdir");
    unreadableSubdir.createDirectory();
    unreadableSubdir.setReadable(false);

    Path file = scratch.file("/pkg/BUILD", "cc_library(name = 'c', srcs = glob(['globs/**']))");
    MoreAsserts.assertThrows(NoSuchPackageException.class, () -> packages.eval("pkg", file));
    events.assertContainsError("Directory is not readable");
  }

  @Test
  public void testPackageGroupSpecMinimal() throws Exception {
    expectEvalSuccess("package_group(name='skin', packages=[])");
  }

  @Test
  public void testPackageGroupSpecSimple() throws Exception {
    expectEvalSuccess("package_group(name='skin', packages=['//group/abelian'])");
  }

  @Test
  public void testPackageGroupSpecEmpty() throws Exception {
    expectEvalSuccess("package_group(name='seed')");
  }

  @Test
  public void testPackageGroupSpecIncludes() throws Exception {
    expectEvalSuccess(
        "package_group(name='wine',",
        "              includes=['//wine:cabernet_sauvignon',",
        "                        '//wine:pinot_noir'])");
  }

  @Test
  public void testPackageGroupSpecBad() throws Exception {
    expectEvalError("invalid package name", "package_group(name='skin', packages=['--25:17--'])");
  }

  @Test
  public void testPackageGroupsWithSameName() throws Exception {
    expectEvalError(
        "conflicts with existing package group",
        "package_group(name='skin', packages=[])",
        "package_group(name='skin', packages=[])");
  }

  @Test
  public void testPackageGroupNamedArguments() throws Exception {
    expectEvalError("does not accept positional arguments", "package_group('skin')");
  }

  @Test
  public void testPackageSpecMinimal() throws Exception {
    Package pkg = expectEvalSuccess("package(default_visibility=[])");
    assertThat(pkg.getDefaultVisibility()).isNotNull();
  }

  @Test
  public void testPackageSpecSimple() throws Exception {
    expectEvalSuccess("package(default_visibility=['//group:lie'])");
  }

  @Test
  public void testPackageSpecBad() throws Exception {
    expectEvalError("invalid target name", "package(default_visibility=[':::'])");
  }

  @Test
  public void testDoublePackageSpecification() throws Exception {
    expectEvalError(
        "can only be used once",
        "package(default_visibility=[])",
        "package(default_visibility=[])");
  }

  @Test
  public void testEmptyPackageSpecification() throws Exception {
    expectEvalError("at least one argument must be given to the 'package' function", "package()");
  }

  @Test
  public void testDefaultTestonly() throws Exception {
    Package pkg = expectEvalSuccess("package(default_testonly = 1)");
    assertThat(pkg.getDefaultTestOnly()).isTrue();
  }

  @Test
  public void testDefaultDeprecation() throws Exception {
    String testMessage = "OMG PONIES!";
    Package pkg = expectEvalSuccess("package(default_deprecation = \"" + testMessage + "\")");
    assertThat(pkg.getDefaultDeprecation()).isEqualTo(testMessage);
  }

  @Test
  public void testExportsBuildFile() throws Exception {
    Package pkg =
        expectEvalSuccess("exports_files(['BUILD'], visibility=['//visibility:private'])");
    assertThat(pkg.getTarget("BUILD")).isEqualTo(pkg.getBuildFile());
  }

  @Test
  public void testDefaultDeprecationPropagation() throws Exception {
    String msg = "I am completely operational, and all my circuits are functioning perfectly.";
    Path file =
        scratch.file(
            "/foo/BUILD",
            "package(default_deprecation = \"" + msg + "\")",
            "sh_library(name = 'bar', srcs=['b'])");
    Package pkg = packages.eval("foo", file);

    Rule fooRule = (Rule) pkg.getTarget("bar");
    String deprAttr =
        attributes(fooRule).get("deprecation", com.google.devtools.build.lib.syntax.Type.STRING);
    assertThat(deprAttr).isEqualTo(msg);
  }

  @Test
  public void testDefaultTestonlyPropagation() throws Exception {
    Path file =
        scratch.file(
            "/foo/BUILD",
            "package(default_testonly = 1)",
            "sh_library(name = 'foo', srcs=['b'])",
            "sh_library(name = 'bar', srcs=['b'], testonly = 0)");
    Package pkg = packages.eval("foo", file);

    Rule fooRule = (Rule) pkg.getTarget("foo");
    assertThat(
            attributes(fooRule).get("testonly", com.google.devtools.build.lib.syntax.Type.BOOLEAN))
        .isTrue();

    Rule barRule = (Rule) pkg.getTarget("bar");
    assertThat(
            attributes(barRule).get("testonly", com.google.devtools.build.lib.syntax.Type.BOOLEAN))
        .isFalse();
  }

  @Test
  public void testDefaultDeprecationOverriding() throws Exception {
    String msg = "I am completely operational, and all my circuits are functioning perfectly.";
    String deceive = "OMG PONIES!";
    Path file =
        scratch.file(
            "/foo/BUILD",
            "package(default_deprecation = \"" + deceive + "\")",
            "sh_library(name = 'bar', srcs=['b'], deprecation = \"" + msg + "\")");
    Package pkg = packages.eval("foo", file);

    Rule fooRule = (Rule) pkg.getTarget("bar");
    String deprAttr =
        attributes(fooRule).get("deprecation", com.google.devtools.build.lib.syntax.Type.STRING);
    assertThat(deprAttr).isEqualTo(msg);
  }

  @Test
  public void testPackageFeatures() throws Exception {
    Path file =
        scratch.file(
            "/a/BUILD",
            "sh_library(name='before')",
            "package(features=['b', 'c'])",
            "sh_library(name='after')");
    Package pkg = packages.eval("a", file);

    assertThat(pkg.getRule("before").getFeatures()).containsExactly("b", "c");
    assertThat(pkg.getRule("after").getFeatures()).containsExactly("b", "c");
    assertThat(pkg.getFeatures()).containsExactly("b", "c");
  }

  @Test
  public void testTransientErrorsInGlobbing() throws Exception {
    events.setFailFast(false);
    Path buildFile =
        scratch.file("/e/BUILD", "sh_library(name = 'e', data = glob(['*.txt']))");
    Path parentDir = buildFile.getParentDirectory();
    scratch.file("/e/data.txt");
    throwOnReaddir = parentDir;
    MoreAsserts.assertThrows(
        NoSuchPackageException.class, () -> packages.createPackage("e", buildFile));
    events.setFailFast(true);
    throwOnReaddir = null;
    Package pkg = packages.createPackage("e", buildFile);
    assertThat(pkg.containsErrors()).isFalse();
    assertThat(pkg.getRule("e")).isNotNull();
    List globList = (List) pkg.getRule("e").getAttributeContainer().getAttr("data");
    assertThat(globList).containsExactly(Label.parseAbsolute("//e:data.txt", ImmutableMap.of()));
  }

  @Test
  public void testExportTwicePublicOK() throws Exception {
    // In theory, this could be an error, but too many existing files rely on it
    // and it is okay.
    expectEvalSuccess(
        "exports_files([\"a.cc\"],",
        "    visibility = [ \"//visibility:public\" ])",
        "exports_files([\"a.cc\"],",
        "    visibility = [ \"//visibility:public\" ])");
  }

  @Test
  public void testExportTwicePublicOK2() throws Exception {
    expectEvalSuccess(
        "exports_files([\"a.cc\"],",
        "    visibility = [ \"//visibility:private\" ])",
        "exports_files([\"a.cc\"],",
        "    visibility = [ \"//visibility:private\" ])");
  }

  @Test
  public void testExportTwiceFail() throws Exception {
    expectEvalError(
        "visibility for exported file 'a.cc' declared twice",
        "exports_files([\"a.cc\"],",
        "    visibility = [ \"//visibility:private\" ])",
        "exports_files([\"a.cc\"],",
        "    visibility = [ \"//visibility:public\" ])");
  }

  @Test
  public void testExportTwiceFail2() throws Exception {
    expectEvalError(
        "visibility for exported file 'a.cc' declared twice",
        "exports_files([\"a.cc\"],",
        "    visibility = [ \"//visibility:public\" ])",
        "exports_files([\"a.cc\"],",
        "    visibility = [ \"//visibility:private\" ])");
  }

  @Test
  public void testExportLicenseTwice() throws Exception {
    expectEvalError(
        "licenses for exported file 'a.cc' declared twice",
        "exports_files([\"a.cc\"], licenses = [\"notice\"])",
        "exports_files([\"a.cc\"], licenses = [\"notice\"])");
  }

  @Test
  public void testExportGenruleConflict() throws Exception {
    expectEvalError(
        "generated file 'a.cc' in rule 'foo' conflicts with existing source file",
        "exports_files([\"a.cc\"],",
        "    visibility = [ \"//visibility:public\" ])",
        "genrule(name = 'foo',",
        "    outs = ['a.cc'],",
        "    cmd = '')");
  }

  @Test
  public void testGenruleExportConflict() throws Exception {
    expectEvalError(
        "generated label '//pkg:a.cc' conflicts with existing generated file",
        "genrule(name = 'foo',",
        "    outs = ['a.cc'],",
        "    cmd = '')",
        "exports_files([\"a.cc\"],",
        "    visibility = [ \"//visibility:public\" ])");
  }

  @Test
  public void testValidEnvironmentGroup() throws Exception {
    expectEvalSuccess(
        "environment(name = 'foo')",
        "environment_group(name='group', environments = [':foo'], defaults = [':foo'])");
  }

  @Test
  public void testIncompleteEnvironmentGroup() throws Exception {
    expectEvalError(
        "missing mandatory named-only argument 'defaults' while calling "
            + "environment_group(*, name: string, ",
        "environment(name = 'foo')",
        "environment_group(name='group', environments = [':foo'])");
  }

  @Test
  public void testEnvironmentGroupMissingTarget() throws Exception {
    expectEvalError(
        "environment //pkg:foo does not exist",
        "environment_group(name='group', environments = [':foo'], defaults = [':foo'])");
  }

  @Test
  public void testEnvironmentGroupWrongTargetType() throws Exception {
    expectEvalError(
        "//pkg:foo is not a valid environment",
        "cc_library(name = 'foo')",
        "environment_group(name='group', environments = [':foo'], defaults = [':foo'])");
  }

  @Test
  public void testEnvironmentGroupWrongPackage() throws Exception {
    expectEvalError(
        "//foo:foo is not in the same package as group //pkg:group",
        "environment_group(name='group', environments = ['//foo'], defaults = ['//foo'])");
  }

  @Test
  public void testEnvironmentGroupInvalidDefault() throws Exception {
    expectEvalError(
        "default //pkg:bar is not a declared environment for group //pkg:group",
        "environment(name = 'foo')",
        "environment(name = 'bar')",
        "environment_group(name='group', environments = [':foo'], defaults = [':bar'])");
  }

  @Test
  public void testEnvironmentGroupDuplicateEnvironments() throws Exception {
    expectEvalError(
        "label '//pkg:foo' is duplicated in the 'environments' list of 'group'",
        "environment(name = 'foo')",
        "environment_group(name='group', environments = [':foo', ':foo'], defaults = [':foo'])");
  }

  @Test
  public void testEnvironmentGroupDuplicateDefaults() throws Exception {
    expectEvalError(
        "label '//pkg:foo' is duplicated in the 'defaults' list of 'group'",
        "environment(name = 'foo')",
        "environment_group(name='group', environments = [':foo'], defaults = [':foo', ':foo'])");
  }

  @Test
  public void testMultipleEnvironmentGroupsValidMembership() throws Exception {
    expectEvalSuccess(
        "environment(name = 'foo')",
        "environment(name = 'bar')",
        "environment_group(name='foo_group', environments = [':foo'], defaults = [':foo'])",
        "environment_group(name='bar_group', environments = [':bar'], defaults = [':bar'])");
  }

  @Test
  public void testMultipleEnvironmentGroupsConflictingMembership() throws Exception {
    expectEvalError(
        "environment //pkg:foo belongs to both //pkg:bar_group and //pkg:foo_group",
        "environment(name = 'foo')",
        "environment(name = 'bar')",
        "environment_group(name='foo_group', environments = [':foo'], defaults = [':foo'])",
        "environment_group(name='bar_group', environments = [':foo'], defaults = [':foo'])");
  }

  @Test
  public void testFulfillsReferencesWrongTargetType() throws Exception {
    expectEvalError(
        "in \"fulfills\" attribute of //pkg:foo: //pkg:bar is not a valid environment",
        "environment(name = 'foo', fulfills = [':bar'])",
        "cc_library(name = 'bar')",
        "environment_group(name='foo_group', environments = [':foo'], defaults = [])");
  }

  @Test
  public void testFulfillsNotInEnvironmentGroup() throws Exception {
    expectEvalError(
        "in \"fulfills\" attribute of //pkg:foo: //pkg:bar is not a member of this group",
        "environment(name = 'foo', fulfills = [':bar'])",
        "environment(name = 'bar')",
        "environment_group(name='foo_group', environments = [':foo'], defaults = [])");
  }

  @Test
  public void testPackageDefaultEnvironments() throws Exception {
    Package pkg =
        expectEvalSuccess(
            "package(",
            "    default_compatible_with=['//foo'],",
            "    default_restricted_to=['//bar'],",
            ")");
    assertThat(pkg.getDefaultCompatibleWith())
        .containsExactly(Label.parseAbsolute("//foo", ImmutableMap.of()));
    assertThat(pkg.getDefaultRestrictedTo())
        .containsExactly(Label.parseAbsolute("//bar", ImmutableMap.of()));
  }

  @Test
  public void testPackageDefaultCompatibilityDuplicates() throws Exception {
    expectEvalError(
        "'//foo:foo' is duplicated in the 'default_compatible_with' list",
        "package(default_compatible_with=['//foo', '//bar', '//foo'])");
  }

  @Test
  public void testPackageDefaultRestrictionDuplicates() throws Exception {
    expectEvalError(
        "'//foo:foo' is duplicated in the 'default_restricted_to' list",
        "package(default_restricted_to=['//foo', '//bar', '//foo'])");
  }

  @Override
  protected PackageFactoryApparatus createPackageFactoryApparatus() {
    return new PackageFactoryApparatus(events.reporter());
  }

  @Override
  protected String getPathPrefix() {
    return "";
  }
}
