blob: 764bb8f2e5f11e77fe617386f0a6551e50029cde [file] [log] [blame]
// 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.Lists;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.packages.Globber.BadGlobException;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.testutil.TestUtils;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* Tests for {@link GlobCache}
*/
@RunWith(JUnit4.class)
public class GlobCacheTest {
private static final List<String> NONE = Collections.emptyList();
private Scratch scratch = new Scratch("/workspace");
private Path packageDirectory;
private Path buildFile;
private GlobCache cache;
@Before
public final void createFiles() throws Exception {
buildFile = scratch.file("isolated/BUILD",
"# contents don't matter in this test");
scratch.file("isolated/sub/BUILD",
"# contents don't matter in this test");
packageDirectory = buildFile.getParentDirectory();
scratch.file("isolated/first.txt",
"# this is first.txt");
scratch.file("isolated/second.txt",
"# this is second.txt");
scratch.file("isolated/first.js",
"# this is first.js");
scratch.file("isolated/second.js",
"# this is second.js");
// Files in subdirectories
scratch.file("isolated/foo/first.js",
"# this is foo/first.js");
scratch.file("isolated/foo/second.js",
"# this is foo/second.js");
scratch.file("isolated/bar/first.js",
"# this is bar/first.js");
scratch.file("isolated/bar/second.js",
"# this is bar/second.js");
scratch.file("isolated/sub/sub.js",
"# this is sub/sub.js");
cache =
new GlobCache(
packageDirectory,
PackageIdentifier.createInMainRepo("isolated"),
new CachingPackageLocator() {
@Override
public Path getBuildFileForPackage(PackageIdentifier packageId) {
String packageName = packageId.getPackageFragment().getPathString();
if (packageName.equals("isolated")) {
return scratch.resolve("isolated/BUILD");
} else if (packageName.equals("isolated/sub")) {
return scratch.resolve("isolated/sub/BUILD");
} else {
return null;
}
}
},
null,
TestUtils.getPool(),
-1);
}
@After
public final void deleteFiles() throws Exception {
FileSystemUtils.deleteTreesBelow(scratch.getFileSystem().getPath("/"));
}
@Test
public void testSafeGlob() throws Exception {
List<Path> paths = cache.safeGlobUnsorted("*.js", false).get();
assertPathsAre(paths,
"/workspace/isolated/first.js", "/workspace/isolated/second.js");
}
@Test
public void testSafeGlobInvalidPattern() throws Exception {
String invalidPattern = "Foo?.txt";
try {
cache.safeGlobUnsorted(invalidPattern, false);
fail("Expected pattern " + invalidPattern + " to fail");
} catch (BadGlobException expected) {
}
}
@Test
public void testGetGlob() throws Exception {
List<String> glob = cache.getGlobUnsorted("*.js");
assertThat(glob).containsExactly("first.js", "second.js");
}
@Test
public void testGetGlob_subdirectory() throws Exception {
List<String> glob = cache.getGlobUnsorted("foo/*.js");
assertThat(glob).containsExactly("foo/first.js", "foo/second.js");
}
@Test
public void testGetKeySet() throws Exception {
assertThat(cache.getKeySet()).isEmpty();
cache.getGlobUnsorted("*.java");
assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false));
cache.getGlobUnsorted("*.java");
assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false));
cache.getGlobUnsorted("*.js");
assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false), Pair.of("*.js", false));
cache.getGlobUnsorted("*.java", true);
assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false), Pair.of("*.js", false),
Pair.of("*.java", true));
try {
cache.getGlobUnsorted("invalid?");
fail("Expected an invalid regex exception");
} catch (BadGlobException expected) {
}
assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false), Pair.of("*.js", false),
Pair.of("*.java", true));
cache.getGlobUnsorted("foo/first.*");
assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false), Pair.of("*.java", true),
Pair.of("*.js", false), Pair.of("foo/first.*", false));
}
@Test
public void testGlob() throws Exception {
assertEmpty(cache.globUnsorted(list("*.java"), NONE, false));
assertThat(cache.globUnsorted(list("*.*"), NONE, false)).containsExactly(
"first.js", "first.txt", "second.js", "second.txt");
assertThat(cache.globUnsorted(list("*.*"), list("first.js"), false)).containsExactly(
"first.txt", "second.js", "second.txt");
assertThat(cache.globUnsorted(list("*.txt", "first.*"), NONE, false)).containsExactly(
"first.txt", "second.txt", "first.js");
}
@Test
public void testRecursiveGlobDoesNotMatchSubpackage() throws Exception {
List<String> glob = cache.getGlobUnsorted("**/*.js");
assertThat(glob).containsExactly("first.js", "second.js", "foo/first.js", "bar/first.js",
"foo/second.js", "bar/second.js");
}
@Test
public void testSingleFileExclude_Star() throws Exception {
assertThat(cache.globUnsorted(list("*"), list("first.txt"), false)).containsExactly(
"BUILD", "bar", "first.js", "foo", "second.js", "second.txt");
}
@Test
public void testSingleFileExclude_StarStar() throws Exception {
assertThat(cache.globUnsorted(list("**"), list("first.txt"), false)).containsExactly(
"BUILD", "bar", "bar/first.js", "bar/second.js", "first.js", "foo", "foo/first.js",
"foo/second.js", "second.js", "second.txt");
}
@Test
public void testExcludeAll_Star() throws Exception {
assertThat(cache.globUnsorted(list("*"), list("*"), false)).isEmpty();
}
@Test
public void testExcludeAll_Star_NoMatchesAnyway() throws Exception {
assertThat(cache.globUnsorted(list("nope"), list("*"), false)).isEmpty();
}
@Test
public void testExcludeAll_StarStar() throws Exception {
assertThat(cache.globUnsorted(list("**"), list("**"), false)).isEmpty();
}
@Test
public void testExcludeAll_Manual() throws Exception {
assertThat(cache.globUnsorted(list("**"), list("*", "*/*", "*/*/*"), false)).isEmpty();
}
@Test
public void testSingleFileExcludeDoesntMatch() throws Exception {
assertThat(cache.globUnsorted(list("first.txt"), list("nope.txt"), false)).containsExactly(
"first.txt");
}
@Test
public void testExcludeDirectory() throws Exception {
assertThat(cache.globUnsorted(list("foo/*"), NONE, true)).containsExactly(
"foo/first.js", "foo/second.js");
assertThat(cache.globUnsorted(list("foo/*"), list("foo"), false)).containsExactly(
"foo/first.js", "foo/second.js");
}
@Test
public void testChildGlobWithChildExclude() throws Exception {
assertThat(cache.globUnsorted(list("foo/*"), list("foo/*"), false)).isEmpty();
assertThat(
cache.globUnsorted(list("foo/first.js", "foo/second.js"), list("foo/*"), false)).isEmpty();
assertThat(cache.globUnsorted(list("foo/first.js"), list("foo/first.js"), false)).isEmpty();
assertThat(cache.globUnsorted(list("foo/first.js"), list("*/first.js"), false)).isEmpty();
assertThat(cache.globUnsorted(list("foo/first.js"), list("*/*"), false)).isEmpty();
}
private void assertEmpty(Collection<?> glob) {
assertThat(glob).isEmpty();
}
private void assertPathsAre(List<Path> paths, String... strings) {
List<String> pathStrings = new ArrayList<>();
for (Path path : paths) {
pathStrings.add(path.getPathString());
}
assertThat(pathStrings).containsExactlyElementsIn(Arrays.asList(strings));
}
/* syntactic shorthand for Lists.newArrayList(strings) */
private List<String> list(String... strings) {
return Lists.newArrayList(strings);
}
}