/*
* Copyright 2016-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.rules;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import com.facebook.buck.config.ConfigBuilder;
import com.facebook.buck.util.environment.Platform;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
import org.hamcrest.Matchers;
import org.junit.Assume;
import org.junit.Test;
public class DefaultCellPathResolverTest {
private static final String REPOSITORIES_SECTION =
"[" + DefaultCellPathResolver.REPOSITORIES_SECTION + "]";
@Test
public void transtiveMappingForSimpleSetup() throws Exception {
FileSystem vfs = Jimfs.newFileSystem(Configuration.unix());
Path root = vfs.getPath("/opt/local/");
Path cell1Root = root.resolve("repo1");
Files.createDirectories(cell1Root);
Path cell2Root = root.resolve("repo2");
Files.createDirectories(cell2Root);
DefaultCellPathResolver cellPathResolver =
new DefaultCellPathResolver(
cell1Root,
ConfigBuilder.createFromText(
REPOSITORIES_SECTION, " simple = " + cell2Root.toString()));
assertThat(
cellPathResolver.getTransitivePathMapping(),
Matchers.equalTo(
ImmutableMap.of(
RelativeCellName.ROOT_CELL_NAME,
cell1Root,
RelativeCellName.of(ImmutableList.of("simple")),
cell2Root)));
}
@Test
public void transtiveMappingForNonexistantCell() throws Exception {
FileSystem vfs = Jimfs.newFileSystem(Configuration.unix());
Path root = vfs.getPath("/opt/local/");
Path cell1Root = root.resolve("repo1");
Files.createDirectories(cell1Root);
Path cell2Root = root.resolve("repo2");
DefaultCellPathResolver cellPathResolver =
new DefaultCellPathResolver(
cell1Root,
ConfigBuilder.createFromText(
REPOSITORIES_SECTION, " simple = " + cell2Root.toString()));
// Allow non-existant paths; Buck should allow paths whose .buckconfigs
// cannot be loaded.
assertThat(
cellPathResolver.getTransitivePathMapping(),
Matchers.equalTo(
ImmutableMap.of(
RelativeCellName.ROOT_CELL_NAME,
cell1Root,
RelativeCellName.of(ImmutableList.of("simple")),
cell2Root)));
}
@Test
public void transtiveMappingForSymlinkCycle() throws Exception {
Assume.assumeTrue(Platform.detect() != Platform.WINDOWS);
FileSystem vfs = Jimfs.newFileSystem(Configuration.unix());
Path root = vfs.getPath("/opt/local/");
Path cell1Root = root.resolve("repo1");
Files.createDirectories(cell1Root);
Path cell2Root = root.resolve("repo2");
Files.createDirectories(cell2Root);
Path symlinkPath = cell2Root.resolve("symlink");
Files.createSymbolicLink(symlinkPath, cell2Root);
DefaultCellPathResolver cellPathResolver =
new DefaultCellPathResolver(
cell1Root, ConfigBuilder.createFromText(REPOSITORIES_SECTION, " two = ../repo2"));
Files.write(
cell2Root.resolve(".buckconfig"),
ImmutableList.of(REPOSITORIES_SECTION, " three = symlink"),
StandardCharsets.UTF_8);
assertThat(
cellPathResolver.getTransitivePathMapping(),
Matchers.equalTo(
ImmutableMap.of(
RelativeCellName.ROOT_CELL_NAME,
cell1Root,
RelativeCellName.of(ImmutableList.of("two")),
cell2Root)));
}
@Test
public void transitiveMappingForCycle() throws Exception {
FileSystem vfs = Jimfs.newFileSystem(Configuration.unix());
Path root = vfs.getPath("/opt/local/");
Path cell1Root = root.resolve("repo1");
Files.createDirectories(cell1Root);
Path cell2Root = root.resolve("repo2");
Files.createDirectories(cell2Root);
Path cell3Root = root.resolve("repo3");
Files.createDirectories(cell3Root);
DefaultCellPathResolver cellPathResolver =
new DefaultCellPathResolver(
cell1Root,
ConfigBuilder.createFromText(
REPOSITORIES_SECTION, " simple = " + cell2Root.toString()));
Files.write(
cell2Root.resolve(".buckconfig"),
ImmutableList.of(REPOSITORIES_SECTION, " three = " + cell3Root.toString()),
StandardCharsets.UTF_8);
Files.write(
cell3Root.resolve(".buckconfig"),
ImmutableList.of(REPOSITORIES_SECTION, " cycle = " + cell1Root.toString()),
StandardCharsets.UTF_8);
assertThat(
cellPathResolver.getTransitivePathMapping(),
Matchers.equalTo(
ImmutableMap.of(
RelativeCellName.ROOT_CELL_NAME,
cell1Root,
RelativeCellName.of(ImmutableList.of("simple")),
cell2Root,
RelativeCellName.of(ImmutableList.of("simple", "three")),
cell3Root)));
}
@Test
public void transitiveMappingForDiamond() throws Exception {
FileSystem vfs = Jimfs.newFileSystem(Configuration.unix());
Path root = vfs.getPath("/opt/local/");
Path cell1Root = root.resolve("repo1");
Files.createDirectories(cell1Root);
Path cellLeftRoot = root.resolve("left");
Files.createDirectories(cellLeftRoot);
Path cellRightRoot = root.resolve("right");
Files.createDirectories(cellRightRoot);
Path cellCenterRoot = root.resolve("center");
Files.createDirectories(cellCenterRoot);
DefaultCellPathResolver cellPathResolver =
new DefaultCellPathResolver(
cell1Root,
ConfigBuilder.createFromText(
REPOSITORIES_SECTION,
" left = " + cellLeftRoot.toString(),
" right = " + cellRightRoot.toString()));
Files.write(
cellLeftRoot.resolve(".buckconfig"),
ImmutableList.of(REPOSITORIES_SECTION, " center = " + cellCenterRoot.toString()),
StandardCharsets.UTF_8);
Files.write(
cellRightRoot.resolve(".buckconfig"),
ImmutableList.of(REPOSITORIES_SECTION, " center = " + cellCenterRoot.toString()),
StandardCharsets.UTF_8);
assertThat(
cellPathResolver.getTransitivePathMapping(),
Matchers.equalTo(
ImmutableMap.<RelativeCellName, Path>builder()
.put(RelativeCellName.ROOT_CELL_NAME, cell1Root)
.put(RelativeCellName.of(ImmutableList.of("left")), cellLeftRoot)
.put(RelativeCellName.of(ImmutableList.of("left", "center")), cellCenterRoot)
.put(RelativeCellName.of(ImmutableList.of("right", "center")), cellCenterRoot)
.put(RelativeCellName.of(ImmutableList.of("right")), cellRightRoot)
.build()));
}
@Test
public void canonicalCellNameForRootIsEmpty() {
FileSystem vfs = Jimfs.newFileSystem(Configuration.unix());
DefaultCellPathResolver cellPathResolver =
new DefaultCellPathResolver(
vfs.getPath("/foo/root"), ImmutableMap.of("root", vfs.getPath("/foo/root")));
assertEquals(Optional.empty(), cellPathResolver.getCanonicalCellName(vfs.getPath("/foo/root")));
}
@Test
public void canonicalCellNameForCellIsLexicographicallySmallest() {
FileSystem vfs = Jimfs.newFileSystem(Configuration.unix());
DefaultCellPathResolver cellPathResolver =
new DefaultCellPathResolver(
vfs.getPath("/foo/root"),
ImmutableMap.of(
"root", vfs.getPath("/foo/root"),
"a", vfs.getPath("/foo/cell"),
"b", vfs.getPath("/foo/cell")));
assertEquals(Optional.of("a"), cellPathResolver.getCanonicalCellName(vfs.getPath("/foo/cell")));
cellPathResolver =
new DefaultCellPathResolver(
vfs.getPath("/foo/root"),
ImmutableMap.of(
"root", vfs.getPath("/foo/root"),
"b", vfs.getPath("/foo/cell"),
"a", vfs.getPath("/foo/cell")));
assertEquals(
"After flipping insertion order, still smallest.",
Optional.of("a"),
cellPathResolver.getCanonicalCellName(vfs.getPath("/foo/cell")));
}
}