/* * Copyright 2015-present Facebook, Inc. * * 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.facebook.buck.io; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import com.facebook.buck.testutil.integration.TemporaryPaths; import com.facebook.buck.util.environment.Platform; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Optional; import org.junit.Assume; import org.junit.Rule; import org.junit.Test; public class ExecutableFinderTest { @Rule public TemporaryPaths tmp = new TemporaryPaths(); @Test public void testSearchPathsFileFoundReturnsPath() throws IOException { Path dir1 = tmp.newFolder("foo"); Path dir2 = tmp.newFolder("bar"); Path dir3 = tmp.newFolder("baz"); Path file = createExecutable("bar/blech"); assertEquals( Optional.of(file), new ExecutableFinder() .getOptionalExecutable( Paths.get("blech"), ImmutableList.of(dir1, dir2, dir3), ImmutableList.of())); } @Test public void testSearchPathsNonExecutableFileIsIgnored() throws IOException { // file.canExecute() always true for Windows Assume.assumeFalse(Platform.detect() == Platform.WINDOWS); Path dir1 = tmp.newFolder("foo"); // Note this is not executable. tmp.newFile("foo/blech"); Path dir2 = tmp.newFolder("bar"); Path dir3 = tmp.newFolder("baz"); Path file = createExecutable("bar/blech"); assertEquals( Optional.of(file), new ExecutableFinder() .getOptionalExecutable( Paths.get("blech"), ImmutableList.of(dir1, dir2, dir3), ImmutableList.of())); } @Test public void testSearchPathsDirAndFileFoundReturnsFileNotDir() throws IOException { Path dir1 = tmp.newFolder("foo"); // We don't want to find this folder. tmp.newFolder("foo", "foo"); Path dir2 = tmp.newFolder("bar"); Path file = createExecutable("bar/foo"); assertEquals( Optional.of(file), new ExecutableFinder() .getOptionalExecutable( Paths.get("foo"), ImmutableList.of(dir1, dir2), ImmutableList.of())); } @Test public void testSearchPathsMultipleFileFoundReturnsFirstPath() throws IOException { Path dir1 = tmp.newFolder("foo"); Path dir2 = tmp.newFolder("bar"); Path dir3 = tmp.newFolder("baz"); Path file1 = createExecutable("bar/blech"); createExecutable("baz/blech"); assertEquals( Optional.of(file1), new ExecutableFinder() .getOptionalExecutable( Paths.get("blech"), ImmutableList.of(dir1, dir2, dir3), ImmutableList.of())); } @Test public void testSearchPathsSymlinkToExecutableInsidePathReturnsPath() throws IOException { Path dir2 = tmp.newFolder("bar"); createExecutable("bar/blech_target"); Path file1 = dir2.resolve("blech"); Files.createSymbolicLink(file1, Paths.get("blech_target")); assertEquals( Optional.of(file1), new ExecutableFinder() .getOptionalExecutable(Paths.get("blech"), ImmutableList.of(dir2), ImmutableList.of())); } @Test public void testSearchPathsSymlinkToExecutableOutsideSearchPathReturnsPath() throws IOException { Path dir1 = tmp.newFolder("foo"); Path dir2 = tmp.newFolder("bar"); Path dir3 = tmp.newFolder("baz"); tmp.newFolder("unsearched"); Path binary = createExecutable("unsearched/binary"); Path file1 = dir2.resolve("blech"); Files.createSymbolicLink(file1, binary); assertEquals( Optional.of(file1), new ExecutableFinder() .getOptionalExecutable( Paths.get("blech"), ImmutableList.of(dir1, dir2, dir3), ImmutableList.of())); } @Test public void testSearchPathsFileNotFoundReturnsAbsent() throws IOException { Path dir1 = tmp.newFolder("foo"); Path dir2 = tmp.newFolder("bar"); Path dir3 = tmp.newFolder("baz"); assertEquals( Optional.empty(), new ExecutableFinder() .getOptionalExecutable( Paths.get("blech"), ImmutableList.of(dir1, dir2, dir3), ImmutableList.of())); } @Test public void testSearchPathsEmptyReturnsAbsent() throws IOException { assertEquals( Optional.empty(), new ExecutableFinder() .getOptionalExecutable(Paths.get("blech"), ImmutableList.of(), ImmutableList.of())); } @Test public void testSearchPathsWithIsExecutableFunctionFailure() throws IOException { Assume.assumeFalse(Platform.detect() == Platform.WINDOWS); // Path to search Path baz = tmp.newFolder("baz"); // Unexecutable "executable" Path bar = baz.resolve("bar"); Files.write(bar, "".getBytes(UTF_8)); assertTrue(bar.toFile().setExecutable(false)); assertEquals( Optional.empty(), new ExecutableFinder() .getOptionalExecutable(Paths.get("bar"), ImmutableList.of(baz), ImmutableList.of())); } @Test public void testSearchPathsWithExtensions() throws IOException { Path dir = tmp.newFolder("foo"); Path file = createExecutable("foo/bar.EXE"); assertEquals( Optional.of(file), new ExecutableFinder() .getOptionalExecutable( Paths.get("bar"), ImmutableList.of(dir), ImmutableList.of(".BAT", ".EXE"))); } @Test public void testSearchPathsWithExtensionsNoMatch() throws IOException { Path dir = tmp.newFolder("foo"); createExecutable("foo/bar.COM"); assertEquals( Optional.empty(), new ExecutableFinder() .getOptionalExecutable( Paths.get("bar"), ImmutableList.of(dir), ImmutableList.of(".BAT", ".EXE"))); } @Test public void testThatADirectoryIsNotConsideredAnExecutable() throws IOException { Path dir = tmp.newFolder(); Path exe = dir.resolve("exe"); Files.createDirectories(exe); assertEquals( Optional.empty(), new ExecutableFinder().getOptionalExecutable(exe.toAbsolutePath(), ImmutableMap.of())); } @Test public void testThatDirectoryWithSwiftExecutableDoesHaveSwiftTool() throws IOException { Path dir = tmp.newFolder("foo"); createExecutable("foo/swift"); assertEquals( Optional.of(dir.resolve("swift")), new ExecutableFinder().getOptionalToolPath("swift", ImmutableList.of(dir))); } @Test public void testThatEmptyDirectoryDoesNotHaveSwift() throws IOException { assertEquals( Optional.empty(), new ExecutableFinder().getOptionalToolPath("swift", ImmutableList.of())); } private Path createExecutable(String executablePath) throws IOException { Path file = tmp.newFile(executablePath); MoreFiles.makeExecutable(file); return file; } }