blob: 2ab3fb6e7cb4799b5620386de4eeda51b527011a [file] [log] [blame]
/*
* Copyright 2012-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.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetPattern;
import com.facebook.buck.model.SingletonBuildTargetPattern;
import com.facebook.buck.model.SubdirectoryBuildTargetPattern;
import com.facebook.buck.parser.BuildTargetParser;
import com.facebook.buck.parser.NoSuchBuildTargetException;
import com.google.common.collect.ImmutableSet;
import org.junit.Test;
public class TargetNodeVisibilityTest {
private static final BuildTarget orcaTarget =
BuildTarget.builder("//src/com/facebook/orca", "orca").build();
private static final BuildTarget publicTarget =
BuildTarget.builder("//src/com/facebook/for", "everyone").build();
private static final BuildTarget nonPublicTarget1 =
BuildTarget.builder("//src/com/facebook/something1", "nonPublic").build();
private static final BuildTarget nonPublicTarget2 =
BuildTarget.builder("//src/com/facebook/something2", "nonPublic").build();
private static final ImmutableSet<BuildTargetPattern> noVisibilityPatterns = ImmutableSet.of();
@Test
public void testVisibilityPublic()
throws NoSuchBuildTargetException, TargetNode.InvalidSourcePathInputException {
TargetNode<?> publicTargetNode = createTargetNode(
publicTarget,
ImmutableSet.of(BuildTargetPattern.MATCH_ALL));
TargetNode<?> orcaRule = createTargetNode(
orcaTarget,
noVisibilityPatterns);
assertTrue(publicTargetNode.isVisibleTo(orcaTarget));
assertFalse(orcaRule.isVisibleTo(publicTarget));
}
@Test
public void testVisibilityNonPublic()
throws NoSuchBuildTargetException, TargetNode.InvalidSourcePathInputException {
TargetNode<?> nonPublicTargetNode1 = createTargetNode(
nonPublicTarget1,
ImmutableSet.<BuildTargetPattern>of(
new SingletonBuildTargetPattern(orcaTarget.getFullyQualifiedName())));
TargetNode<?> nonPublicTargetNode2 = createTargetNode(
nonPublicTarget2,
ImmutableSet.<BuildTargetPattern>of(
new SingletonBuildTargetPattern(orcaTarget.getFullyQualifiedName())));
TargetNode<?> orcaRule = createTargetNode(
orcaTarget, noVisibilityPatterns);
assertTrue(shouldBeVisibleMessage(nonPublicTargetNode1, orcaTarget),
nonPublicTargetNode1.isVisibleTo(orcaTarget));
assertTrue(shouldBeVisibleMessage(nonPublicTargetNode2, orcaTarget),
nonPublicTargetNode2.isVisibleTo(orcaTarget));
assertFalse(orcaRule.isVisibleTo(nonPublicTarget1));
assertFalse(orcaRule.isVisibleTo(nonPublicTarget2));
TargetNode<?> publicTargetNode = createTargetNode(
publicTarget,
ImmutableSet.of(BuildTargetPattern.MATCH_ALL));
assertTrue(publicTargetNode.isVisibleTo(nonPublicTarget1));
assertFalse(nonPublicTargetNode1.isVisibleTo(publicTarget));
}
@Test
public void testVisibilityNonPublicFailure()
throws NoSuchBuildTargetException, TargetNode.InvalidSourcePathInputException {
TargetNode<?> nonPublicTargetNode1 = createTargetNode(
nonPublicTarget1,
ImmutableSet.<BuildTargetPattern>of(
new SingletonBuildTargetPattern(orcaTarget.getFullyQualifiedName())));
try {
nonPublicTargetNode1.checkVisibility(publicTarget);
fail("checkVisibility() should throw an exception");
} catch (RuntimeException e) {
assertEquals(
String.format("%s depends on %s, which is not visible",
publicTarget,
nonPublicTargetNode1.getBuildTarget()),
e.getMessage());
}
}
@Test
public void testVisibilityMix()
throws NoSuchBuildTargetException, TargetNode.InvalidSourcePathInputException {
TargetNode<?> nonPublicTargetNode1 = createTargetNode(
nonPublicTarget1,
ImmutableSet.<BuildTargetPattern>of(
new SingletonBuildTargetPattern(orcaTarget.getFullyQualifiedName())));
TargetNode<?> nonPublicTargetNode2 = createTargetNode(
nonPublicTarget2,
ImmutableSet.<BuildTargetPattern>of(
new SingletonBuildTargetPattern(orcaTarget.getFullyQualifiedName())));
TargetNode<?> publicTargetNode = createTargetNode(
publicTarget,
ImmutableSet.of(BuildTargetPattern.MATCH_ALL));
TargetNode<?> orcaRule = createTargetNode(
orcaTarget,
noVisibilityPatterns);
assertTrue(shouldBeVisibleMessage(nonPublicTargetNode1, orcaTarget),
nonPublicTargetNode1.isVisibleTo(orcaTarget));
assertTrue(shouldBeVisibleMessage(nonPublicTargetNode2, orcaTarget),
nonPublicTargetNode2.isVisibleTo(orcaTarget));
assertTrue(publicTargetNode.isVisibleTo(orcaTarget));
assertFalse(orcaRule.isVisibleTo(nonPublicTarget1));
assertFalse(orcaRule.isVisibleTo(nonPublicTarget2));
assertFalse(orcaRule.isVisibleTo(publicTarget));
}
@Test
public void testVisibilityMixFailure()
throws NoSuchBuildTargetException, TargetNode.InvalidSourcePathInputException {
TargetNode<?> nonPublicTargetNode1 = createTargetNode(
nonPublicTarget1,
ImmutableSet.<BuildTargetPattern>of(
new SingletonBuildTargetPattern(orcaTarget.getFullyQualifiedName())));
TargetNode<?> nonPublicTargetNode2 = createTargetNode(
nonPublicTarget2,
ImmutableSet.<BuildTargetPattern>of(
new SingletonBuildTargetPattern("//some/other:target")));
TargetNode<?> publicTargetNode = createTargetNode(
publicTarget,
ImmutableSet.of(BuildTargetPattern.MATCH_ALL));
publicTargetNode.checkVisibility(orcaTarget);
nonPublicTargetNode1.checkVisibility(orcaTarget);
try {
nonPublicTargetNode2.checkVisibility(orcaTarget);
fail("checkVisibility() should throw an exception");
} catch (RuntimeException e) {
assertEquals(
String.format(
"%s depends on %s, which is not visible",
orcaTarget,
nonPublicTargetNode2.getBuildTarget()),
e.getMessage());
}
}
@Test
public void testVisibilityForDirectory()
throws NoSuchBuildTargetException, TargetNode.InvalidSourcePathInputException {
BuildTarget libTarget = BuildTarget.builder("//lib", "lib").build();
BuildTarget targetInSpecifiedDirectory =
BuildTarget.builder("//src/com/facebook", "test").build();
BuildTarget targetUnderSpecifiedDirectory =
BuildTarget.builder("//src/com/facebook/buck", "test").build();
BuildTarget targetInOtherDirectory = BuildTarget.builder("//src/com/instagram", "test").build();
BuildTarget targetInParentDirectory = BuildTarget.builder("//", "test").build();
// Build rule that visible to targets in or under directory src/come/facebook
TargetNode<?> directoryTargetNode = createTargetNode(
libTarget,
ImmutableSet.<BuildTargetPattern>of(
new SubdirectoryBuildTargetPattern("src/com/facebook/")));
assertTrue(directoryTargetNode.isVisibleTo(targetInSpecifiedDirectory));
assertTrue(directoryTargetNode.isVisibleTo(targetUnderSpecifiedDirectory));
assertFalse(directoryTargetNode.isVisibleTo(targetInOtherDirectory));
assertFalse(directoryTargetNode.isVisibleTo(targetInParentDirectory));
// Build rule that visible to all targets, equals to PUBLIC.
TargetNode<?> pubicTargetNode = createTargetNode(
libTarget,
ImmutableSet.<BuildTargetPattern>of(new SubdirectoryBuildTargetPattern("")));
assertTrue(pubicTargetNode.isVisibleTo(targetInSpecifiedDirectory));
assertTrue(pubicTargetNode.isVisibleTo(targetUnderSpecifiedDirectory));
assertTrue(pubicTargetNode.isVisibleTo(targetInOtherDirectory));
assertTrue(pubicTargetNode.isVisibleTo(targetInParentDirectory));
}
private String shouldBeVisibleMessage(TargetNode<?> rule, BuildTarget target) {
return String.format(
"%1$s should be visible to %2$s because the visibility list of %1$s contains %2$s",
rule.getBuildTarget(),
target);
}
public static class FakeDescription implements Description<FakeDescription.FakeArg> {
@Override
public BuildRuleType getBuildRuleType() {
return ImmutableBuildRuleType.of("fake_rule");
}
@Override
public FakeArg createUnpopulatedConstructorArg() {
return new FakeArg();
}
@Override
public <A extends FakeArg> BuildRule createBuildRule(
BuildRuleParams params,
BuildRuleResolver resolver,
A args) {
return new FakeBuildRule(params, new SourcePathResolver(resolver));
}
public static class FakeArg {
}
}
private static TargetNode<?> createTargetNode(
BuildTarget buildTarget,
ImmutableSet<BuildTargetPattern> visibilityPatterns)
throws NoSuchBuildTargetException, TargetNode.InvalidSourcePathInputException {
Description<FakeDescription.FakeArg> description = new FakeDescription();
FakeDescription.FakeArg arg = description.createUnpopulatedConstructorArg();
BuildRuleFactoryParams params =
NonCheckingBuildRuleFactoryParams.createNonCheckingBuildRuleFactoryParams(
new BuildTargetParser(),
buildTarget);
return new TargetNode<>(
description,
arg,
params,
ImmutableSet.<BuildTarget>of(),
visibilityPatterns);
}
}