// 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.pkgcache;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.pkgcache.FilteringPolicies.FILTER_TESTS;
import static org.junit.Assert.fail;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.ResolvedTargets;
import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.ModifiedFileSet;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
import java.util.Arrays;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link TargetPatternEvaluator}. */
@RunWith(JUnit4.class)
public class TargetPatternEvaluatorTest extends AbstractTargetPatternEvaluatorTest {
  private PathFragment fooOffset;

  private Set<Label> rulesBeneathFoo;
  private Set<Label> rulesInFoo;
  private Set<Label> targetsInFoo;
  private Set<Label> targetsInFooBar;
  private Set<Label> targetsBeneathFoo;
  private Set<Label> targetsInOtherrules;

  @Before
  public final void createFiles() throws Exception {
    // TODO(ulfjack): Also disable the implicit C++ outputs in Google's internal version.
    boolean hasImplicitCcOutputs = ruleClassProvider.getRuleClassMap().get("cc_library")
        .getDefaultImplicitOutputsFunction() != ImplicitOutputsFunction.NONE;

    scratch.file("BUILD",
        "filegroup(name = 'fg', srcs = glob(['*.cc']))");
    scratch.file("foo.cc");

    scratch.file("foo/BUILD",
        "cc_library(name = 'foo1', srcs = [ 'foo1.cc' ], hdrs = [ 'foo1.h' ])",
        "exports_files(['baz/bang'])");
    scratch.file("foo/bar/BUILD",
        "cc_library(name = 'bar1', alwayslink = 1)",
        "cc_library(name = 'bar2')",
        "exports_files(['wiz/bang', 'wiz/all', 'baz', 'baz/bang', 'undeclared.h'])");

    // 'filegroup' and 'test_suite' are rules, but 'exports_files' is not.
    scratch.file("otherrules/BUILD",
        "test_suite(name = 'suite1')",
        "filegroup(name='group', srcs=['suite/somefile'])",
        "exports_files(['suite/somefile'])",
        "cc_library(name = 'wiz', linkstatic = 1)");
    scratch.file("nosuchpkg/subdir/empty", "");

    Path foo = scratch.dir("foo");
    fooOffset = foo.relativeTo(rootDirectory);

    rulesBeneathFoo = labels("//foo:foo1", "//foo/bar:bar1", "//foo/bar:bar2");
    rulesInFoo = labels("//foo:foo1");

    targetsInFoo = labels(
        "//foo:foo1",
        "//foo:foo1",
        "//foo:foo1.cc",
        "//foo:foo1.h",
        "//foo:BUILD",
        "//foo:baz/bang");
    if (hasImplicitCcOutputs) {
      targetsInFoo.addAll(labels("//foo:libfoo1.a", "//foo:libfoo1.so"));
    }
    targetsInFooBar = labels(
        "//foo/bar:bar1",
        "//foo/bar:bar2",
        "//foo/bar:BUILD",
        "//foo/bar:wiz/bang",
        "//foo/bar:wiz/all",
        "//foo/bar:baz",
        "//foo/bar:baz/bang",
        "//foo/bar:undeclared.h");
    if (hasImplicitCcOutputs) {
      targetsInFooBar.addAll(labels("//foo/bar:libbar1.lo", "//foo/bar:libbar2.a"));
    }
    targetsBeneathFoo = Sets.newHashSet();
    targetsBeneathFoo.addAll(targetsInFoo);
    targetsBeneathFoo.addAll(targetsInFooBar);

    targetsInOtherrules = labels(
        "//otherrules:group",
        "//otherrules:wiz",
        "//otherrules:suite1",
        "//otherrules:BUILD",
        "//otherrules:suite/somefile",
        "//otherrules:wiz",
        "//otherrules:suite1");
    if (hasImplicitCcOutputs) {
      targetsInOtherrules.addAll(labels("//otherrules:libwiz.a"));
    }
  }

  private void invalidate(String file) throws InterruptedException {
    skyframeExecutor.invalidateFilesUnderPathForTesting(
        reporter,
        ModifiedFileSet.builder().modify(PathFragment.create(file)).build(),
        Root.fromPath(rootDirectory));
  }

  private void invalidate(ModifiedFileSet modifiedFileSet) throws InterruptedException {
    skyframeExecutor.invalidateFilesUnderPathForTesting(
        reporter, modifiedFileSet, Root.fromPath(rootDirectory));
  }

  private void setDeletedPackages(Set<PackageIdentifier> deletedPackages) {
    skyframeExecutor.setDeletedPackages(deletedPackages);
  }

  private Set<Label> parseList(String... patterns)
      throws TargetParsingException, InterruptedException {
    return targetsToLabels(
        getFailFast(parseTargetPatternList(parser, parsingListener, Arrays.asList(patterns),
            false)));
  }

  private Set<Label> parseList(FilteringPolicy policy, String... patterns)
      throws TargetParsingException, InterruptedException {
    return targetsToLabels(
        getFailFast(
            parseTargetPatternList(
                PathFragment.EMPTY_FRAGMENT,
                parser,
                parsingListener,
                Arrays.asList(patterns),
                policy,
                false)));
  }

  private Set<Label> parseListKeepGoingExpectFailure(String... patterns)
      throws TargetParsingException, InterruptedException {
    ResolvedTargets<Target> result =
        parseTargetPatternList(parser, parsingListener, Arrays.asList(patterns), true);
    assertThat(result.hasError()).isTrue();
    return targetsToLabels(result.getTargets());
  }

  private Set<Label> parseListRelative(String... patterns)
      throws TargetParsingException, InterruptedException {
    return targetsToLabels(getFailFast(parseTargetPatternList(
        fooOffset, parser, parsingListener, Arrays.asList(patterns), false)));
  }

  private static Set<Target> getFailFast(ResolvedTargets<Target> result) {
    assertThat(result.hasError()).isFalse();
    return result.getTargets();
  }

  private void expectError(
      PathFragment offset,
      TargetPatternEvaluator parser,
      String expectedError,
      String target)
          throws InterruptedException {
    try {
      parseTargetPatternList(offset, parser, parsingListener, ImmutableList.of(target), false);
      fail("target='" + target + "', expected error: " + expectedError);
    } catch (TargetParsingException e) {
      assertThat(e).hasMessageThat().contains(expectedError);
    }
  }

  private void expectError(String expectedError, String target) throws InterruptedException {
    expectError(PathFragment.EMPTY_FRAGMENT, parser, expectedError, target);
  }

  private Label parseIndividualTarget(String targetLabel) throws Exception {
    return Iterables.getOnlyElement(
        getFailFast(
            parseTargetPatternList(parser, parsingListener, ImmutableList.of(targetLabel), false)))
        .getLabel();
  }

  @Test
  public void testModifiedBuildFile() throws Exception {
    assertThat(parseList("foo:all")).containsExactlyElementsIn(rulesInFoo);
    assertNoEvents();

    scratch.overwriteFile("foo/BUILD",
        "cc_library(name = 'foo1', srcs = [ 'foo1.cc' ], hdrs = [ 'foo1.h' ])",
        "cc_library(name = 'foo2', srcs = [ 'foo1.cc' ], hdrs = [ 'foo1.h' ])");
    invalidate("foo/BUILD");
    assertThat(parseList("foo:all")).containsExactlyElementsIn(labels("//foo:foo1", "//foo:foo2"));
  }

  /**
   * Test that the relative path label parsing behaves as stated in the target-syntax documentation.
   */
  @Test
  public void testRelativePathLabel() throws Exception {
    scratch.file("sub/BUILD", "exports_files(['dir2/dir2'])");
    scratch.file("sub/dir/BUILD", "exports_files(['dir2'])");
    scratch.file("sub/dir/dir/BUILD", "exports_files(['dir'])");
    // sub/dir/dir is a package
    assertThat(parseIndividualTarget("sub/dir/dir").toString()).isEqualTo("//sub/dir/dir:dir");
    // sub/dir is a package but not sub/dir/dir2
    assertThat(parseIndividualTarget("sub/dir/dir2").toString()).isEqualTo("//sub/dir:dir2");
    // sub is a package but not sub/dir2
    assertThat(parseIndividualTarget("sub/dir2/dir2").toString()).isEqualTo("//sub:dir2/dir2");
  }

  /** Regression test for a bug. */
  @Test
  public void testDotDotDotDoesntMatchDeletedPackages() throws Exception {
    scratch.file("x/y/BUILD", "cc_library(name='y')");
    scratch.file("x/z/BUILD", "cc_library(name='z')");
    setDeletedPackages(Sets.newHashSet(PackageIdentifier.createInMainRepo("x/y")));
    assertThat(parseList("x/..."))
        .isEqualTo(Sets.newHashSet(Label.parseAbsolute("//x/z", ImmutableMap.of())));
  }

  @Test
  public void testDotDotDotDoesntMatchDeletedPackagesRelative() throws Exception {
    scratch.file("x/y/BUILD", "cc_library(name='y')");
    scratch.file("x/z/BUILD", "cc_library(name='z')");
    setDeletedPackages(Sets.newHashSet(PackageIdentifier.createInMainRepo("x/y")));

    assertThat(
            targetsToLabels(
                getFailFast(
                    parseTargetPatternList(
                        PathFragment.create("x"),
                        parser,
                        parsingListener,
                        ImmutableList.of("..."),
                        false))))
        .isEqualTo(Sets.newHashSet(Label.parseAbsolute("//x/z", ImmutableMap.of())));
  }

  @Test
  public void testDeletedPackagesIncrementality() throws Exception {
    scratch.file("x/y/BUILD", "cc_library(name='y')");
    scratch.file("x/z/BUILD", "cc_library(name='z')");

    assertThat(parseList("x/..."))
        .containsExactly(
            Label.parseAbsolute("//x/y", ImmutableMap.of()),
            Label.parseAbsolute("//x/z", ImmutableMap.of()));

    setDeletedPackages(Sets.newHashSet(PackageIdentifier.createInMainRepo("x/y")));
    assertThat(parseList("x/...")).containsExactly(Label.parseAbsolute("//x/z", ImmutableMap.of()));

    setDeletedPackages(ImmutableSet.<PackageIdentifier>of());
    assertThat(parseList("x/..."))
        .containsExactly(
            Label.parseAbsolute("//x/y", ImmutableMap.of()),
            Label.parseAbsolute("//x/z", ImmutableMap.of()));
  }

  @Test
  public void testSequenceOfTargetPatterns_Union() throws Exception {
    // No prefix negation operator => union.  Order is not significant.
    assertThat(parseList("foo/...", "foo/bar/...")).containsExactlyElementsIn(rulesBeneathFoo);
    assertThat(parseList("foo/bar/...", "foo/...")).containsExactlyElementsIn(rulesBeneathFoo);
  }

  @Test
  public void testSequenceOfTargetPatterns_SetDifference() throws Exception {
    // Prefix negation operator => set difference.  Order is significant.
    assertThat(parseList("foo/...", "-foo/bar/...")).containsExactlyElementsIn(rulesInFoo);
    assertThat(parseList("-foo/bar/...", "foo/...")).containsExactlyElementsIn(rulesBeneathFoo);
  }

  @Test
  public void testSequenceOfTargetPatterns_SetDifferenceRelative() throws Exception {
    // Prefix negation operator => set difference.  Order is significant.
    assertThat(parseListRelative("...", "-bar/...")).containsExactlyElementsIn(rulesInFoo);
    assertThat(parseListRelative("-bar/...", "...")).containsExactlyElementsIn(rulesBeneathFoo);
  }

  /** Regression test for bug: "Bogus 'helpful' error message" */
  @Test
  public void testHelpfulMessageForDirectoryWhichIsASubdirectoryOfAPackage() throws Exception {
    scratch.file("bar/BUILD");
    scratch.file("bar/quux/somefile");
    expectError("no such target '//bar:quux': target 'quux' not declared in package 'bar'; "
            + "however, a source directory of this name exists.  (Perhaps add "
            + "'exports_files([\"quux\"])' to bar/BUILD, or define a filegroup?) defined by "
            + "/workspace/bar/BUILD",
        "bar/quux");
  }

  @Test
  public void testKeepGoingPartiallyBadPackage() throws Exception {
    scratch.file("x/y/BUILD",
        "filegroup(name = 'a')",
        "BROKEN",
        "filegroup(name = 'b')");

    reporter.removeHandler(failFastHandler);
    Pair<Set<Label>, Boolean> result = parseListKeepGoing("//x/...");

    assertContainsEvent("name 'BROKEN' is not defined");
    assertThat(result.first)
        .containsExactlyElementsIn(
            Sets.newHashSet(
                Label.parseAbsolute("//x/y:a", ImmutableMap.of()),
                Label.parseAbsolute("//x/y:b", ImmutableMap.of())));
    assertThat(result.second).isFalse();
  }

  @Test
  public void testKeepGoingMissingRecursiveDirectory() throws Exception {
    assertKeepGoing(rulesBeneathFoo,
        "Skipping 'nosuchpkg/...': no targets found beneath 'nosuchpkg'",
        "nosuchpkg/...", "foo/...");
    eventCollector.clear();
    assertKeepGoing(rulesBeneathFoo,
        "Skipping 'nosuchdirectory/...': no targets found beneath 'nosuchdirectory'",
        "nosuchdirectory/...", "foo/...");
  }

  @Test
  public void testKeepGoingMissingTarget() throws Exception {
    assertKeepGoing(rulesBeneathFoo,
        "Skipping '//otherrules:missing_target': no such target "
            + "'//otherrules:missing_target': target 'missing_target' not declared in "
            + "package 'otherrules'",
        "//otherrules:missing_target", "foo/...");
  }

  @Test
  public void testKeepGoingOnAllRulesBeneath() throws Exception {
    scratch.file("foo/bar/bad/BUILD", "invalid build file");

    reporter.removeHandler(failFastHandler);
    Pair<Set<Label>, Boolean> result = parseListKeepGoing("foo/...");
    assertThat(result.first).containsExactlyElementsIn(rulesBeneathFoo);
    assertContainsEvent("syntax error at 'build'");
    assertContainsEvent("package contains errors");
    reporter.addHandler(failFastHandler);

    // Even though there was a loading error in the package, parsing the target pattern was
    // successful.
    assertThat(result.second).isFalse();
  }

  @Test
  public void testKeepGoingBadFilenameTarget() throws Exception {
    assertKeepGoing(rulesBeneathFoo,
        "no such target '//:bad/filename/target'",
        "bad/filename/target", "foo/...");
  }

  @Test
  public void testMoreThanOneBadPatternFailFast() throws Exception {
    try {
      parseTargetPatternList(parser, parsingListener,
          ImmutableList.of("bad/filename/target", "other/bad/filename/target"),
          /*keepGoing=*/false);
      fail();
    } catch (TargetParsingException e) {
      assertThat(e).hasMessageThat().contains("no such target");
    }
  }

  @Test
  public void testMentioningBuildFile() throws Exception {
    ResolvedTargets<Target> result = parseTargetPatternList(parser, parsingListener,
        Arrays.asList("//foo/bar/BUILD"), false);

    assertThat(result.hasError()).isFalse();
    assertThat(result.getTargets()).hasSize(1);

    Label label = Iterables.getOnlyElement(result.getTargets()).getLabel();
    assertThat(label.getName()).isEqualTo("BUILD");
    assertThat(label.getPackageName()).isEqualTo("foo/bar");
  }

  /**
   * Regression test for bug: '"Target pattern parsing failed. Continuing anyway" appears, even
   * without --keep_going'
   */
  @Test
  public void testLoadingErrorsAreNotParsingErrors() throws Exception {
    reporter.removeHandler(failFastHandler);
    scratch.file("loading/BUILD",
        "cc_library(name='y', deps=['a'])",
        "cc_library(name='a', deps=['b'])",
        "cc_library(name='b', deps=['c'])",
        "genrule(name='c', outs=['c.out'])");

    Pair<Set<Label>, Boolean> result = parseListKeepGoing("//loading:y");
    assertThat(result.first).containsExactly(Label.parseAbsolute("//loading:y", ImmutableMap.of()));
    assertContainsEvent("missing value for mandatory attribute");
    assertThat(result.second).isFalse();
  }

  private void assertKeepGoing(Set<Label> expectedLabels, String expectedEvent, String... toParse)
      throws Exception {
    reporter.removeHandler(failFastHandler);
    assertThat(parseListKeepGoingExpectFailure(toParse)).containsExactlyElementsIn(expectedLabels);
    assertContainsEvent(expectedEvent);
    reporter.addHandler(failFastHandler);
  }

  /** Regression test for bug: "IllegalStateException in BuildTool.prepareToBuild()" */
  @Test
  public void testTestingIsSubset() throws Exception {
    scratch.file("test/BUILD",
        "cc_library(name = 'bar1')",
        "cc_test(name = 'test', deps = [':bar1'], tags = ['manual'])");

    assertThat(parseList(FILTER_TESTS, "//test:test", "-//test:all"))
        .containsExactlyElementsIn(labels());
  }

  @Test
  public void testAddedPkg() throws Exception {
    invalidate(ModifiedFileSet.EVERYTHING_MODIFIED);
    scratch.dir("h/i/j/k/BUILD");
    scratch.file("h/BUILD", "sh_library(name='h')");
    assertThat(parseList("//h/...")).containsExactlyElementsIn(labels("//h"));

    scratch.file("h/i/j/BUILD", "sh_library(name='j')");

    // Modifications not yet known.
    assertThat(parseList("//h/...")).containsExactlyElementsIn(labels("//h"));

    ModifiedFileSet modifiedFileSet = ModifiedFileSet.builder()
        .modify(PathFragment.create("h/i/j/BUILD")).build();
    invalidate(modifiedFileSet);

    assertThat(parseList("//h/..."))
        .containsExactly(
            Label.parseAbsolute("//h/i/j:j", ImmutableMap.of()),
            Label.parseAbsolute("//h", ImmutableMap.of()));
  }

  @Test
  public void testAddedFilesAndDotDotDot() throws Exception {
    invalidate(ModifiedFileSet.EVERYTHING_MODIFIED);
    reporter.removeHandler(failFastHandler);
    scratch.dir("h");
    try {
      parseList("//h/...");
      fail("TargetParsingException expected");
    } catch (TargetParsingException e) {
      // expected
    }

    scratch.file("h/i/j/k/BUILD", "sh_library(name='l')");
    ModifiedFileSet modifiedFileSet = ModifiedFileSet.builder()
        .modify(PathFragment.create("h"))
        .modify(PathFragment.create("h/i"))
        .modify(PathFragment.create("h/i/j"))
        .modify(PathFragment.create("h/i/j/k"))
        .modify(PathFragment.create("h/i/j/k/BUILD"))
        .build();
    invalidate(modifiedFileSet);
    reporter.addHandler(failFastHandler);
    Set<Label> nonEmptyResult = parseList("//h/...");
    assertThat(nonEmptyResult)
        .containsExactly(Label.parseAbsolute("//h/i/j/k:l", ImmutableMap.of()));
  }

  @Test
  public void testBrokenSymlinkRepaired() throws Exception {
    reporter.removeHandler(failFastHandler);
    Path tuv = scratch.dir("t/u/v");
    tuv.getChild("BUILD").createSymbolicLink(PathFragment.create("../../BUILD"));

    try {
      parseList("//t/...");
      fail("TargetParsingException expected");
    } catch (TargetParsingException e) {
      // expected
    }

    scratch.file("t/BUILD", "sh_library(name='t')");
    ModifiedFileSet modifiedFileSet = ModifiedFileSet.builder()
        .modify(PathFragment.create("t/BUILD"))
        .build();

    invalidate(modifiedFileSet);
    reporter.addHandler(failFastHandler);
    Set<Label> result = parseList("//t/...");

    assertThat(result)
        .containsExactly(
            Label.parseAbsolute("//t:t", ImmutableMap.of()),
            Label.parseAbsolute("//t/u/v:t", ImmutableMap.of()));
  }

  @Test
  public void testInfiniteTreeFromSymlinks() throws Exception {
    reporter.removeHandler(failFastHandler);
    Path ab = scratch.dir("a/b");
    ab.getChild("c").createSymbolicLink(PathFragment.create("../b"));
    scratch.file("a/b/BUILD", "filegroup(name='g')");
    ResolvedTargets<Target> result = parseTargetPatternList(parser, parsingListener,
        ImmutableList.of("//a/b/..."), true);
    assertThat(targetsToLabels(result.getTargets()))
        .containsExactly(Label.parseAbsolute("//a/b:g", ImmutableMap.of()));
  }

  @Test
  public void testSymlinkCycle() throws Exception {
    reporter.removeHandler(failFastHandler);
    Path ab = scratch.dir("a/b");
    ab.getChild("c").createSymbolicLink(PathFragment.create("c"));
    scratch.file("a/b/BUILD", "filegroup(name='g')");
    ResolvedTargets<Target> result = parseTargetPatternList(parser, parsingListener,
        ImmutableList.of("//a/b/..."), true);
    assertThat(targetsToLabels(result.getTargets()))
        .contains(Label.parseAbsolute("//a/b:g", ImmutableMap.of()));
  }

  @Test
  public void testPerDirectorySymlinkTraversalOptOut() throws Exception {
    scratch.dir("from-b");
    scratch.file("from-b/BUILD", "filegroup(name = 'from-b')");
    scratch.dir("from-c");
    scratch.file("from-c/BUILD", "filegroup(name = 'from-c')");
    Path ab = scratch.dir("a/b");
    ab.getChild("symlink").createSymbolicLink(PathFragment.create("../../from-b"));
    scratch.dir("a/b/not-a-symlink");
    scratch.file("a/b/not-a-symlink/BUILD", "filegroup(name = 'not-a-symlink')");
    scratch.file(
        "a/b/DONT_FOLLOW_SYMLINKS_WHEN_TRAVERSING_THIS_DIRECTORY_VIA_A_RECURSIVE_TARGET_PATTERN");
    Path ac = scratch.dir("a/c");
    ac.getChild("symlink").createSymbolicLink(PathFragment.create("../../from-c"));
    ResolvedTargets<Target> result = parseTargetPatternList(parser, parsingListener,
        ImmutableList.of("//a/..."), true);
    assertThat(targetsToLabels(result.getTargets()))
        .containsExactly(
            Label.parseAbsolute("//a/c/symlink:from-c", ImmutableMap.of()),
            Label.parseAbsolute("//a/b/not-a-symlink:not-a-symlink", ImmutableMap.of()));
  }

  @Test
  public void testDoesNotRecurseIntoSymlinksToOutputBase() throws Exception {
    Path outputBaseBuildFile = outputBase.getRelative("execroot/workspace/test/BUILD");
    scratch.file(outputBaseBuildFile.getPathString(), "filegroup(name='c')");
    PathFragment targetFragment = outputBase.asFragment().getRelative("execroot/workspace/test");
    Path d = scratch.dir("d");
    d.getChild("c").createSymbolicLink(targetFragment);
    rootDirectory.getChild("convenience").createSymbolicLink(targetFragment);
    Set<Label> result = parseList("//...");
    assertThat(result).doesNotContain(Label.parseAbsolute("//convenience:c", ImmutableMap.of()));
    assertThat(result).doesNotContain(Label.parseAbsolute("//d/c:c", ImmutableMap.of()));
  }

  @Test
  public void testExternalPackage() throws Exception {
    parseList("external:all");
  }

  @Test
  public void testTopLevelPackage_Relative_BuildFile() throws Exception {
    Set<Label> result = parseList("BUILD");
    assertThat(result).containsExactly(Label.parseAbsolute("//:BUILD", ImmutableMap.of()));
  }

  @Test
  public void testTopLevelPackage_Relative_DeclaredTarget() throws Exception {
    Set<Label> result = parseList("fg");
    assertThat(result).containsExactly(Label.parseAbsolute("//:fg", ImmutableMap.of()));
  }

  @Test
  public void testTopLevelPackage_Relative_All() throws Exception {
    expectError("no such target '//:all'", "all");
  }

  @Test
  public void testTopLevelPackage_Relative_ColonAll() throws Exception {
    Set<Label> result = parseList(":all");
    assertThat(result).containsExactly(Label.parseAbsolute("//:fg", ImmutableMap.of()));
  }

  @Test
  public void testTopLevelPackage_Relative_InputFile() throws Exception {
    Set<Label> result = parseList("foo.cc");
    assertThat(result).containsExactly(Label.parseAbsolute("//:foo.cc", ImmutableMap.of()));
  }

  @Test
  public void testTopLevelPackage_Relative_InputFile_NoSuchInputFile() throws Exception {
    expectError("no such target '//:nope.cc'", "nope.cc");
  }

  @Test
  public void testTopLevelPackage_Absolute_BuildFile() throws Exception {
    Set<Label> result = parseList("//:BUILD");
    assertThat(result).containsExactly(Label.parseAbsolute("//:BUILD", ImmutableMap.of()));
  }

  @Test
  public void testTopLevelPackage_Absolute_DeclaredTarget() throws Exception {
    Set<Label> result = parseList("//:fg");
    assertThat(result).containsExactly(Label.parseAbsolute("//:fg", ImmutableMap.of()));
  }

  @Test
  public void testTopLevelPackage_Absolute_All() throws Exception {
    Set<Label> result = parseList("//:all");
    assertThat(result).containsExactly(Label.parseAbsolute("//:fg", ImmutableMap.of()));
  }

  @Test
  public void testTopLevelPackage_Absolute_InputFile() throws Exception {
    Set<Label> result = parseList("//:foo.cc");
    assertThat(result).containsExactly(Label.parseAbsolute("//:foo.cc", ImmutableMap.of()));
  }

  @Test
  public void testTopLevelPackage_Absolute_InputFile_NoSuchInputFile() throws Exception {
    expectError("no such target '//:nope.cc'", "//:nope.cc");
  }
}
