diff --git a/src/main/java/com/google/devtools/build/lib/testing/common/DirectoryListingHelper.java b/src/main/java/com/google/devtools/build/lib/testing/common/DirectoryListingHelper.java index 459572ee5686b9..c5e1ce048a7407 100644 --- a/src/main/java/com/google/devtools/build/lib/testing/common/DirectoryListingHelper.java +++ b/src/main/java/com/google/devtools/build/lib/testing/common/DirectoryListingHelper.java @@ -24,6 +24,11 @@ public final class DirectoryListingHelper { private DirectoryListingHelper() {} + /** Shorthand for {@link Dirent} of {@link Dirent.Type#FILE} type with a given name. */ + public static Dirent file(String name) { + return new Dirent(name, Dirent.Type.FILE); + } + /** Shorthand for {@link Dirent} of {@link Dirent.Type#DIRECTORY} type with a given name. */ public static Dirent directory(String name) { return new Dirent(name, Dirent.Type.DIRECTORY); @@ -52,16 +57,19 @@ private static void leafDirectoryEntriesInternal( Path path, String prefix, ImmutableList.Builder entries) throws IOException { boolean isEmpty = true; for (Dirent dirent : path.readdir(Symlinks.NOFOLLOW)) { + isEmpty = false; + String entryName = prefix.isEmpty() ? dirent.getName() : prefix + "/" + dirent.getName(); + if (dirent.getType() == Dirent.Type.DIRECTORY) { - leafDirectoryEntriesInternal( - path.getChild(dirent.getName()), - prefix.isEmpty() ? dirent.getName() : prefix + "/" + dirent.getName(), - entries); + leafDirectoryEntriesInternal(path.getChild(dirent.getName()), entryName, entries); + continue; } - isEmpty = false; + + entries.add(new Dirent(entryName, dirent.getType())); } - if (isEmpty) { + // Skip adding the root if it's empty. + if (isEmpty && !prefix.isEmpty()) { entries.add(new Dirent(prefix, Dirent.Type.DIRECTORY)); } } diff --git a/src/test/java/com/google/devtools/build/lib/testing/common/BUILD b/src/test/java/com/google/devtools/build/lib/testing/common/BUILD index ca01b123d9ebab..30a687e781cee9 100644 --- a/src/test/java/com/google/devtools/build/lib/testing/common/BUILD +++ b/src/test/java/com/google/devtools/build/lib/testing/common/BUILD @@ -1,7 +1,7 @@ load("@rules_java//java:defs.bzl", "java_test") package( - default_testonly = 1, + default_testonly = True, default_visibility = ["//src:__subpackages__"], ) @@ -9,11 +9,23 @@ licenses(["notice"]) filegroup( name = "srcs", - testonly = 0, + testonly = False, srcs = glob(["**"]), visibility = ["//src:__subpackages__"], ) +java_test( + name = "DirectoryListingHelperTest", + srcs = ["DirectoryListingHelperTest.java"], + deps = [ + "//src/main/java/com/google/devtools/build/lib/testing/common:directory_listing_helper", + "//src/main/java/com/google/devtools/build/lib/vfs", + "//src/test/java/com/google/devtools/build/lib/testutil", + "//third_party:junit4", + "//third_party:truth", + ], +) + java_test( name = "FakeOptionsTest", srcs = ["FakeOptionsTest.java"], diff --git a/src/test/java/com/google/devtools/build/lib/testing/common/DirectoryListingHelperTest.java b/src/test/java/com/google/devtools/build/lib/testing/common/DirectoryListingHelperTest.java new file mode 100644 index 00000000000000..584b0f0536cc42 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/testing/common/DirectoryListingHelperTest.java @@ -0,0 +1,89 @@ +// 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.testing.common; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.devtools.build.lib.testing.common.DirectoryListingHelper.directory; +import static com.google.devtools.build.lib.testing.common.DirectoryListingHelper.file; +import static com.google.devtools.build.lib.testing.common.DirectoryListingHelper.leafDirectoryEntries; +import static org.junit.Assert.assertThrows; + +import com.google.devtools.build.lib.testutil.Scratch; +import com.google.devtools.build.lib.vfs.Path; +import java.io.FileNotFoundException; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link com.google.devtools.build.lib.testing.common.DirectoryListingHelper}. */ +@RunWith(JUnit4.class) +public final class DirectoryListingHelperTest { + + private final Scratch scratch = new Scratch(); + private final Path root = scratch.getFileSystem().getPath("/"); + + @Test + public void leafDirectoryEntries_emptyDirectory_returnsEmptyList() throws Exception { + assertThat(leafDirectoryEntries(root)).isEmpty(); + } + + @Test + public void leafDirectoryEntries_returnsFile() throws Exception { + scratch.file("/file"); + assertThat(leafDirectoryEntries(root)).containsExactly(file("file")); + } + + @Test + public void leafDirectoryEntries_fileInSubfolders_returnsFileOnly() throws Exception { + scratch.file("/dir1/dir2/file"); + assertThat(leafDirectoryEntries(root)).containsExactly(file("dir1/dir2/file")); + } + + @Test + public void leafDirectoryEntries_returnsEmptyDirectory() throws Exception { + scratch.dir("/dir"); + assertThat(leafDirectoryEntries(root)).containsExactly(directory("dir")); + } + + @Test + public void leafDirectoryEntries_mixedEmptyDirectoriesAndFiles_returnsAllEntries() + throws Exception { + scratch.dir("/dir/empty1"); + scratch.dir("/dir/subdir/empty2"); + scratch.file("/dir2/file3"); + scratch.file("/dir2/file4"); + + assertThat(leafDirectoryEntries(root)) + .containsExactly( + directory("dir/empty1"), + directory("dir/subdir/empty2"), + file("dir2/file3"), + file("dir2/file4")); + } + + @Test + public void leafDirectoryEntries_returnsEntriesUnderProvidedPathOnly() throws Exception { + scratch.file("/dir/file1"); + scratch.file("/dir2/file2"); + Path dir = scratch.dir("/dir"); + + assertThat(leafDirectoryEntries(dir)).containsExactly(file("file1")); + } + + @Test + public void leafDirectoryEntries_missingDirectory_fails() { + Path nonexistent = scratch.getFileSystem().getPath("/nonexistent"); + assertThrows(FileNotFoundException.class, () -> leafDirectoryEntries(nonexistent)); + } +}