| /* |
| * 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.shell; |
| |
| import static com.facebook.buck.util.BuckConstant.GEN_DIR; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| |
| import com.facebook.buck.event.BuckEventBusFactory; |
| import com.facebook.buck.java.DefaultJavaLibraryRule; |
| import com.facebook.buck.java.JavaBinaryRule; |
| import com.facebook.buck.java.JavaLibraryRule; |
| import com.facebook.buck.model.BuildTarget; |
| import com.facebook.buck.model.BuildTargetFactory; |
| import com.facebook.buck.model.BuildTargetPattern; |
| import com.facebook.buck.parser.BuildRuleFactoryParams; |
| import com.facebook.buck.parser.BuildTargetParser; |
| import com.facebook.buck.parser.NoSuchBuildTargetException; |
| import com.facebook.buck.parser.NonCheckingBuildRuleFactoryParams; |
| import com.facebook.buck.parser.ParseContext; |
| import com.facebook.buck.rules.BuildContext; |
| import com.facebook.buck.rules.BuildRule; |
| import com.facebook.buck.rules.BuildRuleResolver; |
| import com.facebook.buck.rules.BuildRuleType; |
| import com.facebook.buck.rules.FakeAbstractBuildRuleBuilderParams; |
| import com.facebook.buck.rules.FakeBuildableContext; |
| import com.facebook.buck.shell.Genrule.Builder; |
| import com.facebook.buck.step.ExecutionContext; |
| import com.facebook.buck.step.Step; |
| import com.facebook.buck.step.fs.MakeCleanDirectoryStep; |
| import com.facebook.buck.step.fs.MkdirAndSymlinkFileStep; |
| import com.facebook.buck.step.fs.MkdirStep; |
| import com.facebook.buck.step.fs.RmStep; |
| import com.facebook.buck.testutil.TestConsole; |
| import com.facebook.buck.util.AndroidPlatformTarget; |
| import com.facebook.buck.util.Ansi; |
| import com.facebook.buck.util.Console; |
| import com.facebook.buck.util.HumanReadableException; |
| import com.facebook.buck.util.ProjectFilesystem; |
| import com.facebook.buck.util.Verbosity; |
| import com.facebook.buck.util.environment.Platform; |
| import com.google.common.base.Function; |
| import com.google.common.base.Functions; |
| import com.google.common.base.Optional; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.ImmutableSortedSet; |
| |
| import org.easymock.EasyMock; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.regex.Pattern; |
| |
| public class GenruleTest { |
| |
| private static final String BASE_PATH = getAbsolutePathFor("/opt/local/fbandroid"); |
| |
| private static final Function<String, String> relativeToAbsolutePathFunction = |
| new Function<String, String>() { |
| @Override |
| public String apply(String path) { |
| return getAbsolutePathInBase(path); |
| } |
| }; |
| |
| private ProjectFilesystem fakeFilesystem; |
| |
| @Before |
| public void newFakeFilesystem() { |
| fakeFilesystem = EasyMock.createNiceMock(ProjectFilesystem.class); |
| EasyMock.expect(fakeFilesystem.getPathRelativizer()) |
| .andReturn(relativeToAbsolutePathFunction) |
| .times(0, 1); |
| EasyMock.replay(fakeFilesystem); |
| } |
| |
| @After |
| public void verifyFakeFilesystem() { |
| EasyMock.verify(fakeFilesystem); |
| } |
| |
| @Test |
| public void testCreateAndRunGenrule() throws IOException, NoSuchBuildTargetException { |
| /* |
| * Programmatically build up a Genrule that corresponds to: |
| * |
| * genrule( |
| * name = 'katana_manifest', |
| * srcs = [ |
| * 'convert_to_katana.py', |
| * 'AndroidManifest.xml', |
| * ], |
| * cmd = 'python $SRCDIR/* > $OUT', |
| * out = 'AndroidManifest.xml', |
| * ) |
| */ |
| |
| BuildRuleResolver ruleResolver = new BuildRuleResolver(); |
| createSampleJavaBinaryRule(ruleResolver); |
| |
| Map<String, ?> instance = ImmutableMap.of( |
| "name", "katana_manifest", |
| "srcs", ImmutableList.<String>of("convert_to_katana.py", "AndroidManifest.xml"), |
| "cmd", "python convert_to_katana.py AndroidManifest.xml > $OUT", |
| "out", "AndroidManifest.xml", |
| "deps", ImmutableList.<String>of("//java/com/facebook/util:util")); |
| |
| // From the Python object, create a GenruleBuildRuleFactory to create a Genrule.Builder |
| // that builds a Genrule from the Python object. |
| BuildTargetParser parser = EasyMock.createNiceMock(BuildTargetParser.class); |
| EasyMock.expect(parser.parse(EasyMock.eq("//java/com/facebook/util:util"), |
| EasyMock.anyObject(ParseContext.class))) |
| .andStubReturn(BuildTargetFactory.newInstance("//java/com/facebook/util:util")); |
| EasyMock.replay(parser); |
| |
| BuildTarget buildTarget = new BuildTarget("//src/com/facebook/katana", "katana_manifest"); |
| BuildRuleFactoryParams params = NonCheckingBuildRuleFactoryParams. |
| createNonCheckingBuildRuleFactoryParams( |
| instance, |
| parser, |
| buildTarget); |
| GenruleBuildRuleFactory factory = new GenruleBuildRuleFactory(); |
| Builder builder = factory.newInstance(params); |
| builder.setRelativeToAbsolutePathFunctionForTesting(relativeToAbsolutePathFunction); |
| Genrule genrule = ruleResolver.buildAndAddToIndex(builder); |
| |
| // Verify all of the observers of the Genrule. |
| assertEquals(BuildRuleType.GENRULE, genrule.getType()); |
| assertEquals(GEN_DIR + "/src/com/facebook/katana/AndroidManifest.xml", |
| genrule.getPathToOutputFile()); |
| assertEquals(getAbsolutePathInBase(GEN_DIR + "/src/com/facebook/katana/AndroidManifest.xml"), |
| genrule.getAbsoluteOutputFilePath()); |
| BuildContext buildContext = null; // unused since there are no deps |
| ImmutableSortedSet<String> inputsToCompareToOutputs = ImmutableSortedSet.of( |
| "src/com/facebook/katana/convert_to_katana.py", |
| "src/com/facebook/katana/AndroidManifest.xml"); |
| assertEquals(inputsToCompareToOutputs, |
| genrule.getInputsToCompareToOutput()); |
| |
| // Verify that the shell commands that the genrule produces are correct. |
| List<Step> steps = genrule.getBuildSteps(buildContext, new FakeBuildableContext()); |
| assertEquals(7, steps.size()); |
| |
| Step firstStep = steps.get(0); |
| assertTrue(firstStep instanceof RmStep); |
| RmStep rmCommand = (RmStep) firstStep; |
| ExecutionContext executionContext = newEmptyExecutionContext(); |
| assertEquals( |
| "First command should delete the output file to be written by the genrule.", |
| ImmutableList.of( |
| "rm", |
| "-f", |
| GEN_DIR + "/src/com/facebook/katana/AndroidManifest.xml"), |
| rmCommand.getShellCommand(executionContext)); |
| |
| Step secondStep = steps.get(1); |
| assertTrue(secondStep instanceof MkdirStep); |
| MkdirStep mkdirCommand = (MkdirStep) secondStep; |
| assertEquals( |
| "Second command should make sure the output directory exists.", |
| Paths.get(GEN_DIR + "/src/com/facebook/katana"), |
| mkdirCommand.getPath(executionContext)); |
| |
| Step mkTmpDir = steps.get(2); |
| assertTrue(mkTmpDir instanceof MakeCleanDirectoryStep); |
| MakeCleanDirectoryStep secondMkdirCommand = (MakeCleanDirectoryStep)mkTmpDir; |
| String pathToTmpDir = GEN_DIR + "/src/com/facebook/katana/katana_manifest__tmp"; |
| assertEquals( |
| "Third command should create the temp directory to be written by the genrule.", |
| pathToTmpDir, |
| secondMkdirCommand.getPath()); |
| |
| Step mkSrcDir = steps.get(3); |
| assertTrue(mkSrcDir instanceof MakeCleanDirectoryStep); |
| MakeCleanDirectoryStep thirdMkdirCommand = (MakeCleanDirectoryStep)mkTmpDir; |
| String pathToSrcDir = GEN_DIR + "/src/com/facebook/katana/katana_manifest__srcs"; |
| assertEquals( |
| "Fourth command should create the temp source directory to be written by the genrule.", |
| pathToTmpDir, |
| thirdMkdirCommand.getPath()); |
| |
| MkdirAndSymlinkFileStep linkSource1 = (MkdirAndSymlinkFileStep) steps.get(4); |
| assertEquals("src/com/facebook/katana/convert_to_katana.py", linkSource1.getSource()); |
| assertEquals(pathToSrcDir + "/convert_to_katana.py", linkSource1.getTarget()); |
| |
| MkdirAndSymlinkFileStep linkSource2 = (MkdirAndSymlinkFileStep) steps.get(5); |
| assertEquals("src/com/facebook/katana/AndroidManifest.xml", linkSource2.getSource()); |
| assertEquals(pathToSrcDir + "/AndroidManifest.xml", linkSource2.getTarget()); |
| |
| Step sixthStep = steps.get(6); |
| assertTrue(sixthStep instanceof ShellStep); |
| ShellStep genruleCommand = (ShellStep) sixthStep; |
| assertEquals("genrule", genruleCommand.getShortName()); |
| assertEquals(ImmutableMap.<String, String>builder() |
| .put("SRCS", |
| getAbsolutePathInBase("/src/com/facebook/katana/convert_to_katana.py ") + |
| getAbsolutePathInBase("/src/com/facebook/katana/AndroidManifest.xml")) |
| .put("OUT", |
| getAbsolutePathInBase(GEN_DIR + "/src/com/facebook/katana/AndroidManifest.xml")) |
| .put("GEN_DIR", |
| getAbsolutePathInBase(GEN_DIR)) |
| .put("DEPS", |
| "$GEN_DIR/java/com/facebook/util/lib__util__output/util.jar") |
| .put("TMP", |
| getAbsolutePathInBase(pathToTmpDir)) |
| .put("SRCDIR", |
| getAbsolutePathInBase(pathToSrcDir)) |
| .build(), |
| genruleCommand.getEnvironmentVariables(executionContext)); |
| assertEquals( |
| ImmutableList.of("/bin/bash", "-c", "python convert_to_katana.py AndroidManifest.xml > $OUT"), |
| genruleCommand.getShellCommand(executionContext)); |
| } |
| |
| private ExecutionContext newEmptyExecutionContext(Platform platform) { |
| return ExecutionContext.builder() |
| .setConsole(new Console(Verbosity.SILENT, System.out, System.err, Ansi.withoutTty())) |
| .setProjectFilesystem(new ProjectFilesystem(new File(".")) { |
| @Override |
| public Function<String, String> getPathRelativizer() { |
| return Functions.identity(); |
| } |
| |
| @Override |
| public Path resolve(Path path) { |
| return path; |
| } |
| }) |
| .setEventBus(BuckEventBusFactory.newInstance()) |
| .setPlatform(platform) |
| .build(); |
| } |
| |
| private ExecutionContext newEmptyExecutionContext() { |
| return newEmptyExecutionContext(Platform.detect()); |
| } |
| |
| @Test |
| public void testBuildTargetPattern() { |
| Pattern buildTargetPattern = AbstractGenruleStep.BUILD_TARGET_PATTERN; |
| assertTrue(buildTargetPattern.matcher("$(exe //first-party/orca/orcaapp:manifest)").find()); |
| assertFalse(buildTargetPattern.matcher("\\$(exe //first-party/orca/orcaapp:manifest)").find()); |
| assertFalse(buildTargetPattern.matcher("$(exe first-party/orca/orcaapp:manifest)").find()); |
| assertTrue(buildTargetPattern.matcher("$(exe :manifest)").find()); |
| assertTrue(buildTargetPattern.matcher("$(exe //:manifest)").find()); |
| assertTrue(buildTargetPattern.matcher( |
| "$(exe :some_manifest) inhouse $SRCDIR/AndroidManifest.xml $OUT").find()); |
| } |
| |
| @Test |
| public void testLocationBuildTargetPattern() { |
| Pattern buildTargetPattern = AbstractGenruleStep.BUILD_TARGET_PATTERN; |
| assertTrue(buildTargetPattern.matcher("$(location //first-party/orca/orcaapp:manifest)").find()); |
| assertFalse(buildTargetPattern.matcher("\\$(location //first-party/orca/orcaapp:manifest)").find()); |
| assertFalse(buildTargetPattern.matcher("$(location first-party/orca/orcaapp:manifest)").find()); |
| assertTrue(buildTargetPattern.matcher("$(location :manifest)").find()); |
| assertTrue(buildTargetPattern.matcher("$(location :manifest)").find()); |
| assertTrue(buildTargetPattern.matcher("$(location\t:manifest)").find()); |
| assertTrue(buildTargetPattern.matcher("$(location //:manifest)").find()); |
| assertTrue(buildTargetPattern.matcher( |
| "$(location :some_manifest) inhouse $SRCDIR/AndroidManifest.xml $OUT").find()); |
| } |
| |
| @Test |
| public void testReplaceBinaryBuildRuleRefsInCmd() { |
| BuildRuleResolver ruleResolver = new BuildRuleResolver(); |
| JavaBinaryRule javaBinary = createSampleJavaBinaryRule(ruleResolver); |
| |
| String originalCmd = "$(exe //java/com/facebook/util:ManifestGenerator) $OUT"; |
| String contextBasePath = "java/com/facebook/util"; |
| Set<? extends BuildRule> deps = ImmutableSet.of(javaBinary); |
| |
| Genrule rule = createGenrule(ruleResolver, originalCmd, contextBasePath, deps); |
| AbstractGenruleStep genruleStep = rule.createGenruleStep(); |
| |
| // Interpolate the build target in the genrule cmd string. |
| String transformedString = genruleStep.replaceMatches(fakeFilesystem, originalCmd); |
| |
| // Verify that the correct cmd was created. |
| String expectedClasspath = getAbsolutePathInBase( |
| GEN_DIR + "/java/com/facebook/util/lib__util__output/util.jar"); |
| |
| String expectedCmd = String.format( |
| "java -classpath %s com.facebook.util.ManifestGenerator $OUT", |
| expectedClasspath); |
| assertEquals(expectedCmd, transformedString); |
| } |
| |
| @Test |
| public void testReplaceRelativeBinaryBuildRuleRefsInCmd() { |
| BuildRuleResolver ruleResolver = new BuildRuleResolver(); |
| JavaBinaryRule javaBinary = createSampleJavaBinaryRule(ruleResolver); |
| |
| String originalCmd = "$(exe :ManifestGenerator) $OUT"; |
| String contextBasePath = "java/com/facebook/util"; |
| Set<? extends BuildRule> deps = ImmutableSet.of(javaBinary); |
| |
| Genrule rule = createGenrule(ruleResolver, originalCmd, contextBasePath, deps); |
| AbstractGenruleStep genruleStep = rule.createGenruleStep(); |
| |
| // Interpolate the build target in the genrule cmd string. |
| String transformedString = genruleStep.replaceMatches(fakeFilesystem, originalCmd); |
| |
| // Verify that the correct cmd was created. |
| String expectedClasspath = getAbsolutePathInBase( |
| GEN_DIR + "/java/com/facebook/util/lib__util__output/util.jar"); |
| String expectedCmd = String.format( |
| "java -classpath %s com.facebook.util.ManifestGenerator $OUT", |
| expectedClasspath); |
| assertEquals(expectedCmd, transformedString); |
| } |
| |
| @Test |
| public void replaceLocationOfFullyQualifiedBuildTarget() { |
| ProjectFilesystem filesystem = EasyMock.createNiceMock(ProjectFilesystem.class); |
| EasyMock.expect(filesystem.getPathRelativizer()).andStubReturn(relativeToAbsolutePathFunction); |
| EasyMock.replay(filesystem); |
| |
| BuildRuleResolver ruleResolver = new BuildRuleResolver(); |
| JavaBinaryRule javaBinary = createSampleJavaBinaryRule(ruleResolver); |
| |
| String originalCmd = String.format("$(location :%s) $(location %s) $OUT", |
| javaBinary.getBuildTarget().getShortName(), |
| javaBinary.getBuildTarget().getFullyQualifiedName()); |
| |
| String contextBasePath = javaBinary.getBuildTarget().getBasePath(); |
| Set<? extends BuildRule> deps = ImmutableSet.of(javaBinary); |
| |
| Genrule rule = createGenrule(ruleResolver, originalCmd, contextBasePath, deps); |
| AbstractGenruleStep genruleStep = rule.createGenruleStep(); |
| |
| // Interpolate the build target in the genrule cmd string. |
| String transformedString = genruleStep.replaceMatches(filesystem, originalCmd); |
| |
| // Verify that the correct cmd was created. |
| String pathToOutput = getAbsolutePathInBase( |
| GEN_DIR + "/java/com/facebook/util/ManifestGenerator.jar"); |
| String expectedCmd = String.format("%s %s $OUT", pathToOutput, pathToOutput); |
| assertEquals(expectedCmd, transformedString); |
| EasyMock.verify(filesystem); |
| } |
| |
| |
| @Test |
| public void testDepsGenrule() { |
| BuildRuleResolver ruleResolver = new BuildRuleResolver(); |
| JavaBinaryRule javaBinary = createSampleJavaBinaryRule(ruleResolver); |
| |
| // Interpolate the build target in the genrule cmd string. |
| String originalCmd = "$(exe :ManifestGenerator) $OUT"; |
| Set<? extends BuildRule> deps = ImmutableSet.of(javaBinary); |
| String contextBasePath = "java/com/facebook/util"; |
| |
| Genrule rule = createGenrule(ruleResolver, originalCmd, contextBasePath, deps); |
| AbstractGenruleStep genruleStep = rule.createGenruleStep(); |
| |
| String transformedString = genruleStep.replaceMatches(fakeFilesystem, originalCmd); |
| |
| // Verify that the correct cmd was created. |
| String expectedClasspath = getAbsolutePathInBase( |
| GEN_DIR + "/java/com/facebook/util/lib__util__output/util.jar"); |
| String expectedCmd = String.format( |
| "java -classpath %s com.facebook.util.ManifestGenerator $OUT", |
| expectedClasspath); |
| assertEquals(expectedCmd, transformedString); |
| } |
| |
| @Test |
| public void ensureFilesInSubdirectoriesAreKeptInSubDirectories() throws IOException { |
| BuildRuleResolver ruleResolver = new BuildRuleResolver(); |
| |
| BuildTarget target = BuildTargetFactory.newInstance("//:example"); |
| Genrule rule = ruleResolver.buildAndAddToIndex( |
| Genrule.newGenruleBuilder(new FakeAbstractBuildRuleBuilderParams()) |
| .setRelativeToAbsolutePathFunctionForTesting(relativeToAbsolutePathFunction) |
| .setBuildTarget(target) |
| .setBash(Optional.of("ignored")) |
| .addSrc("in-dir.txt") |
| .addSrc("foo/bar.html") |
| .addSrc("other/place.txt") |
| .setOut("example-file")); |
| |
| ImmutableList.Builder<Step> builder = ImmutableList.builder(); |
| rule.addSymlinkCommands(builder); |
| ImmutableList<Step> commands = builder.build(); |
| |
| String baseTmpPath = GEN_DIR + "/example__srcs/"; |
| |
| assertEquals(3, commands.size()); |
| MkdirAndSymlinkFileStep linkCmd = (MkdirAndSymlinkFileStep) commands.get(0); |
| assertEquals("in-dir.txt", linkCmd.getSource()); |
| assertEquals(baseTmpPath + "in-dir.txt", linkCmd.getTarget()); |
| |
| linkCmd = (MkdirAndSymlinkFileStep) commands.get(1); |
| assertEquals("foo/bar.html", linkCmd.getSource()); |
| assertEquals(baseTmpPath + "foo/bar.html", linkCmd.getTarget()); |
| |
| linkCmd = (MkdirAndSymlinkFileStep) commands.get(2); |
| assertEquals("other/place.txt", linkCmd.getSource()); |
| assertEquals(baseTmpPath + "other/place.txt", linkCmd.getTarget()); |
| } |
| |
| private JavaBinaryRule createSampleJavaBinaryRule(BuildRuleResolver ruleResolver) { |
| // Create a java_binary that depends on a java_library so it is possible to create a |
| // java_binary rule with a classpath entry and a main class. |
| JavaLibraryRule javaLibrary = ruleResolver.buildAndAddToIndex( |
| DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams()) |
| .setBuildTarget(BuildTargetFactory.newInstance("//java/com/facebook/util:util")) |
| .addVisibilityPattern(BuildTargetPattern.MATCH_ALL) |
| .addSrc("java/com/facebook/util/ManifestGenerator.java")); |
| |
| JavaBinaryRule javaBinary = ruleResolver.buildAndAddToIndex( |
| JavaBinaryRule.newJavaBinaryRuleBuilder(new FakeAbstractBuildRuleBuilderParams()) |
| .setBuildTarget(BuildTargetFactory.newInstance("//java/com/facebook/util:ManifestGenerator")) |
| .setMainClass("com.facebook.util.ManifestGenerator") |
| .addDep(javaLibrary.getBuildTarget())); |
| |
| return javaBinary; |
| } |
| |
| private Genrule createGenrule(BuildRuleResolver ruleResolver, |
| String originalCmd, |
| String contextBasePath, |
| Set<? extends BuildRule> deps) { |
| BuildTarget target = BuildTargetFactory.newInstance( |
| String.format("//%s:genrule", contextBasePath)); |
| |
| Builder ruleBuilder = Genrule.newGenruleBuilder(new FakeAbstractBuildRuleBuilderParams()) |
| .setRelativeToAbsolutePathFunctionForTesting(relativeToAbsolutePathFunction) |
| .setBuildTarget(target) |
| .setBash(Optional.of(originalCmd)) |
| .setOut("example-file"); |
| |
| for (BuildRule dep : deps) { |
| ruleBuilder.addDep(dep.getBuildTarget()); |
| } |
| |
| return ruleResolver.buildAndAddToIndex(ruleBuilder); |
| } |
| |
| @Test |
| public void testShouldIncludeDxInEnvironmentIfPresent() { |
| File fakeDx = new File("."); // We do no checks on whether dx is executable, but it must exist |
| AndroidPlatformTarget android = EasyMock.createNiceMock(AndroidPlatformTarget.class); |
| EasyMock.expect(android.getDxExecutable()).andStubReturn(fakeDx); |
| EasyMock.replay(android); |
| |
| Genrule rule = Genrule.newGenruleBuilder(new FakeAbstractBuildRuleBuilderParams()) |
| .setBuildTarget(BuildTargetFactory.newInstance("//example:genrule")) |
| .setBash(Optional.of("true")) |
| .setOut("/dev/null") |
| .build(new BuildRuleResolver()); |
| |
| ExecutionContext context = ExecutionContext.builder() |
| .setConsole(new TestConsole()) |
| .setProjectFilesystem(new ProjectFilesystem(new File("."))) |
| .setAndroidPlatformTarget(Optional.of(android)) |
| .setEventBus(BuckEventBusFactory.newInstance()) |
| .setPlatform(Platform.detect()) |
| .build(); |
| |
| ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); |
| rule.addEnvironmentVariables(context, builder); |
| ImmutableMap<String, String> env = builder.build(); |
| |
| assertEquals(fakeDx.getAbsolutePath(), env.get("DX")); |
| |
| EasyMock.verify(android); |
| } |
| |
| @Test |
| public void testGetShellCommand() { |
| String bash = "rm -rf /usr"; |
| String cmdExe = "rmdir /s /q C:\\Windows"; |
| String cmd = "echo \"Hello\""; |
| String genruleName = "//example:genrule"; |
| ExecutionContext linuxExecutionContext = newEmptyExecutionContext(Platform.LINUX); |
| ExecutionContext windowsExecutionContext = newEmptyExecutionContext(Platform.WINDOWS); |
| |
| // Test platform-specific |
| Genrule rule = Genrule.newGenruleBuilder(new FakeAbstractBuildRuleBuilderParams()) |
| .setBuildTarget(BuildTargetFactory.newInstance(genruleName)) |
| .setBash(Optional.of(bash)) |
| .setCmdExe(Optional.of(cmdExe)) |
| .setOut("out.txt") |
| .build(new BuildRuleResolver()); |
| |
| ImmutableList<String> command = rule.createGenruleStep().getShellCommand(linuxExecutionContext); |
| assertEquals(ImmutableList.of("/bin/bash", "-c", bash), command); |
| |
| command = rule.createGenruleStep().getShellCommand(windowsExecutionContext); |
| assertEquals(ImmutableList.of("cmd.exe", "/c", cmdExe), command); |
| |
| // Test fallback |
| rule = Genrule.newGenruleBuilder(new FakeAbstractBuildRuleBuilderParams()) |
| .setBuildTarget(BuildTargetFactory.newInstance("//example:genrule")) |
| .setCmd(Optional.of(cmd)) |
| .setOut("out.txt") |
| .build(new BuildRuleResolver()); |
| command = rule.createGenruleStep().getShellCommand(linuxExecutionContext); |
| assertEquals(ImmutableList.of("/bin/bash", "-c", cmd), command); |
| |
| command = rule.createGenruleStep().getShellCommand(windowsExecutionContext); |
| assertEquals(ImmutableList.of("cmd.exe", "/c", cmd), command); |
| |
| // Test command absent |
| rule = Genrule.newGenruleBuilder(new FakeAbstractBuildRuleBuilderParams()) |
| .setBuildTarget(BuildTargetFactory.newInstance("//example:genrule")) |
| .setOut("out.txt") |
| .build(new BuildRuleResolver()); |
| try { |
| rule.createGenruleStep().getShellCommand(linuxExecutionContext); |
| } catch (HumanReadableException e) { |
| assertEquals(String.format("You must specify either bash or cmd for genrule %s.", |
| genruleName), e.getHumanReadableErrorMessage()); |
| } |
| |
| try { |
| rule.createGenruleStep().getShellCommand(windowsExecutionContext); |
| } catch (HumanReadableException e) { |
| assertEquals(String.format("You must specify either cmd_exe or cmd for genrule %s.", |
| genruleName), e.getHumanReadableErrorMessage()); |
| } |
| } |
| |
| private static String getAbsolutePathFor(String path) { |
| return new File(path).getAbsolutePath(); |
| } |
| |
| private static String getAbsolutePathInBase(String path) { |
| return getAbsolutePathFor(String.format("%s/%s", BASE_PATH, path)); |
| } |
| } |