/*
* 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.rules;
import static org.junit.Assert.assertThat;
import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.rules.args.SourcePathArg;
import com.facebook.buck.rules.keys.DefaultRuleKeyFactory;
import com.facebook.buck.rules.keys.UncachedRuleKeyBuilder;
import com.facebook.buck.shell.GenruleBuilder;
import com.facebook.buck.testutil.FakeFileHashCache;
import com.facebook.buck.testutil.FakeProjectFilesystem;
import com.facebook.buck.util.cache.FileHashCache;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.nio.file.Paths;
import org.hamcrest.Matchers;
import org.junit.Test;
public class CommandToolTest {
@Test
public void buildTargetSourcePath() throws Exception {
BuildRuleResolver resolver =
new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
ProjectFilesystem filesystem = new FakeProjectFilesystem();
// Build a source path which wraps a build rule.
BuildRule rule =
GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:rule"))
.setOut("output")
.build(resolver, filesystem);
SourcePath path = rule.getSourcePathToOutput();
// Test command and inputs for just passing the source path.
CommandTool tool = new CommandTool.Builder().addArg(SourcePathArg.of(path)).build();
assertThat(
tool.getCommandPrefix(pathResolver),
Matchers.contains(
pathResolver
.getAbsolutePath(Preconditions.checkNotNull(rule.getSourcePathToOutput()))
.toString()));
assertThat(tool.getDeps(ruleFinder), Matchers.contains(rule));
assertThat(tool.getInputs(), Matchers.contains(path));
}
@Test
public void pathSourcePath() {
BuildRuleResolver resolver =
new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
SourcePathResolver pathResolver = new SourcePathResolver(new SourcePathRuleFinder(resolver));
ProjectFilesystem filesystem = new FakeProjectFilesystem();
// Build a source path which wraps a build rule.
SourcePath path = new PathSourcePath(filesystem, Paths.get("output"));
// Test command and inputs for just passing the source path.
CommandTool tool = new CommandTool.Builder().addArg(SourcePathArg.of(path)).build();
assertThat(
tool.getCommandPrefix(pathResolver),
Matchers.contains(pathResolver.getAbsolutePath(path).toString()));
}
@Test
public void extraInputs() {
BuildRuleResolver ruleResolver =
new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(ruleResolver);
SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
FakeBuildRule rule = new FakeBuildRule("//some:target", pathResolver);
rule.setOutputFile("foo");
ruleResolver.addToIndex(rule);
SourcePath path = rule.getSourcePathToOutput();
CommandTool tool = new CommandTool.Builder().addInputs(ImmutableList.of(path)).build();
assertThat(tool.getDeps(ruleFinder), Matchers.contains(rule));
assertThat(tool.getInputs(), Matchers.contains(path));
}
@Test
public void environment() {
BuildRuleResolver resolver =
new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
SourcePathResolver pathResolver = new SourcePathResolver(new SourcePathRuleFinder(resolver));
SourcePath path = new FakeSourcePath("input");
CommandTool tool =
new CommandTool.Builder().addArg("runit").addEnv("PATH", SourcePathArg.of(path)).build();
assertThat(
tool.getEnvironment(pathResolver),
Matchers.hasEntry(Matchers.equalTo("PATH"), Matchers.containsString("input")));
}
@Test
public void sourcePathsContributeToRuleKeys() {
BuildRuleResolver resolver =
new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
SourcePath path = new FakeSourcePath("input");
CommandTool tool = new CommandTool.Builder().addArg(SourcePathArg.of(path)).build();
FileHashCache hashCache =
FakeFileHashCache.createFromStrings(ImmutableMap.of("input", Strings.repeat("a", 40)));
DefaultRuleKeyFactory ruleKeyFactory =
new DefaultRuleKeyFactory(0, hashCache, pathResolver, ruleFinder);
RuleKey ruleKey =
new UncachedRuleKeyBuilder(ruleFinder, pathResolver, hashCache, ruleKeyFactory)
.setReflectively("key", tool)
.build(RuleKey::new);
hashCache =
FakeFileHashCache.createFromStrings(ImmutableMap.of("input", Strings.repeat("b", 40)));
ruleKeyFactory = new DefaultRuleKeyFactory(0, hashCache, pathResolver, ruleFinder);
RuleKey changedRuleKey =
new UncachedRuleKeyBuilder(ruleFinder, pathResolver, hashCache, ruleKeyFactory)
.setReflectively("key", tool)
.build(RuleKey::new);
assertThat(ruleKey, Matchers.not(Matchers.equalTo(changedRuleKey)));
}
}