Supply temporary directory to java_test() Similar to genrule() give the test running JVM a temporary directory below buck-out that is uniquely named for this test target. Send the path in by both the TMP environment variable and java.io.tmpdir system property. Fixes https://github.com/facebook/buck/issues/13
diff --git a/src/com/facebook/buck/android/RobolectricTestRule.java b/src/com/facebook/buck/android/RobolectricTestRule.java index 168d916..8c98625 100644 --- a/src/com/facebook/buck/android/RobolectricTestRule.java +++ b/src/com/facebook/buck/android/RobolectricTestRule.java
@@ -25,6 +25,7 @@ import com.facebook.buck.rules.BuildRule; import com.facebook.buck.rules.BuildRuleType; import com.facebook.buck.rules.CachingBuildRuleParams; +import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -44,7 +45,8 @@ List<String> vmArgs, ImmutableSet<JavaLibraryRule> sourceUnderTest, String sourceLevel, - String targetLevel) { + String targetLevel, + Function<String, String> relativeToAbsolutePathFunction) { super(cachingBuildRuleParams, srcs, resources, @@ -54,7 +56,8 @@ vmArgs, sourceUnderTest, sourceLevel, - targetLevel); + targetLevel, + relativeToAbsolutePathFunction); } @Override @@ -96,7 +99,8 @@ allVmArgs.build(), sourceUnderTest, sourceLevel, - targetLevel); + targetLevel, + relativeToAbsolutePathFunction); } @Override
diff --git a/src/com/facebook/buck/java/JUnitStep.java b/src/com/facebook/buck/java/JUnitStep.java index d6193c8..62f8ad9 100644 --- a/src/com/facebook/buck/java/JUnitStep.java +++ b/src/com/facebook/buck/java/JUnitStep.java
@@ -24,6 +24,7 @@ import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; @@ -60,6 +61,8 @@ private final boolean isDebugEnabled; + private final String tmpDirectory; + private final String testRunnerClassesDirectory; /** @@ -69,12 +72,14 @@ * that will be run, as well as an entry for JUnit. * @param testClassNames the fully qualified names of the Java tests to run * @param directoryForTestResults directory where test results should be written + * @param tmpDirectory directory tests can use for local file scratch space. */ public JUnitStep( Set<String> classpathEntries, Set<String> testClassNames, List<String> vmArgs, String directoryForTestResults, + String tmpDirectory, boolean isCodeCoverageEnabled, boolean isDebugEnabled) { this(classpathEntries, @@ -83,6 +88,7 @@ directoryForTestResults, isCodeCoverageEnabled, isDebugEnabled, + tmpDirectory, System.getProperty("buck.testrunner_classes")); } @@ -94,6 +100,7 @@ String directoryForTestResults, boolean isCodeCoverageEnabled, boolean isDebugEnabled, + String tmpDirectory, String testRunnerClassesDirectory) { this.classpathEntries = ImmutableSet.copyOf(classpathEntries); this.testClassNames = ImmutableSet.copyOf(testClassNames); @@ -101,6 +108,7 @@ this.directoryForTestResults = Preconditions.checkNotNull(directoryForTestResults); this.isCodeCoverageEnabled = isCodeCoverageEnabled; this.isDebugEnabled = isDebugEnabled; + this.tmpDirectory = tmpDirectory; this.testRunnerClassesDirectory = Preconditions.checkNotNull(testRunnerClassesDirectory); } @@ -113,6 +121,7 @@ protected ImmutableList<String> getShellCommandInternal(ExecutionContext context) { ImmutableList.Builder<String> args = ImmutableList.builder(); args.add("java"); + args.add(String.format("-Djava.io.tmpdir=%s", tmpDirectory)); // Add the output property for EMMA so if the classes are instrumented, coverage.ec will be // placed in the EMMA output folder. @@ -176,6 +185,13 @@ return args.build(); } + @Override + public ImmutableMap<String, String> getEnvironmentVariables() { + ImmutableMap.Builder<String, String> env = ImmutableMap.builder(); + env.put("TMP", tmpDirectory); + return env.build(); + } + private void warnUser(ExecutionContext context, String message) { context.getStdErr().println(context.getAnsi().asWarningText(message)); }
diff --git a/src/com/facebook/buck/java/JavaTestRule.java b/src/com/facebook/buck/java/JavaTestRule.java index 2960d1d..dba71f5 100644 --- a/src/com/facebook/buck/java/JavaTestRule.java +++ b/src/com/facebook/buck/java/JavaTestRule.java
@@ -33,9 +33,11 @@ import com.facebook.buck.step.Step; import com.facebook.buck.step.fs.MakeCleanDirectoryStep; import com.facebook.buck.util.BuckConstant; +import com.facebook.buck.util.Functions; import com.facebook.buck.util.HumanReadableException; import com.facebook.buck.util.ZipFileTraversal; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; @@ -69,6 +71,8 @@ private final ImmutableSet<String> labels; + private final String tmpDirectory; + protected JavaTestRule(CachingBuildRuleParams cachingBuildRuleParams, Set<String> srcs, Set<String> resources, @@ -78,7 +82,8 @@ List<String> vmArgs, ImmutableSet<JavaLibraryRule> sourceUnderTest, String sourceLevel, - String targetLevel) { + String targetLevel, + Function<String, String> relativeToAbsolutePathFunction) { super(cachingBuildRuleParams, srcs, resources, @@ -90,6 +95,13 @@ this.vmArgs = ImmutableList.copyOf(vmArgs); this.sourceUnderTest = Preconditions.checkNotNull(sourceUnderTest); this.labels = ImmutableSet.copyOf(labels); + + String temp = String.format("%s/%s/%s__tmp", + BuckConstant.GEN_DIR, + cachingBuildRuleParams.getBuildTarget().getBasePath(), + getBuildTarget().getShortName() + ); + this.tmpDirectory = relativeToAbsolutePathFunction.apply(temp); } @Override @@ -163,8 +175,8 @@ ImmutableList.Builder<Step> steps = ImmutableList.builder(); String pathToTestOutput = getPathToTestOutput(); - MakeCleanDirectoryStep mkdirClean = new MakeCleanDirectoryStep(pathToTestOutput); - steps.add(mkdirClean); + steps.add(new MakeCleanDirectoryStep(pathToTestOutput)); + steps.add(new MakeCleanDirectoryStep(tmpDirectory)); // If there are android resources, then compile the uber R.java files and add them to the // classpath used to run the test runner. @@ -187,6 +199,7 @@ testClassNames, vmArgs, pathToTestOutput, + tmpDirectory, executionContext.isCodeCoverageEnabled, executionContext.isDebugEnabled()); steps.add(junit); @@ -364,6 +377,8 @@ @Nullable protected List<String> vmArgs = ImmutableList.of(); protected ImmutableSet<String> sourceUnderTestNames = ImmutableSet.of(); protected ImmutableSet<String> labels = ImmutableSet.of(); + protected Function<String, String> relativeToAbsolutePathFunction = + Functions.RELATIVE_TO_ABSOLUTE_PATH; protected Builder() {} @@ -380,7 +395,8 @@ vmArgs, sourceUnderTest, sourceLevel, - targetLevel); + targetLevel, + relativeToAbsolutePathFunction); } @Override @@ -423,6 +439,13 @@ return this; } + @VisibleForTesting + Builder setRelativeToAbsolutePathFunction( + Function<String, String> relativeToAbsolutePathFunction) { + this.relativeToAbsolutePathFunction = relativeToAbsolutePathFunction; + return this; + } + /** * Generates the set of build rules that contain the source that will be under test. */
diff --git a/test/com/facebook/buck/java/JUnitStepTest.java b/test/com/facebook/buck/java/JUnitStepTest.java index 8241e6b..97195d7 100644 --- a/test/com/facebook/buck/java/JUnitStepTest.java +++ b/test/com/facebook/buck/java/JUnitStepTest.java
@@ -52,6 +52,7 @@ List<String> vmArgs = ImmutableList.of(vmArg1, vmArg2); String directoryForTestResults = "buck-gen/theresults/"; + String directoryForTemp = "buck-gen/thetmp/"; boolean isCodeCoverageEnabled = false; boolean isDebugEnabled = false; String testRunnerClassesDirectory = "build/classes/junit"; @@ -63,6 +64,7 @@ directoryForTestResults, isCodeCoverageEnabled, isDebugEnabled, + directoryForTemp, testRunnerClassesDirectory); ExecutionContext executionContext = EasyMock.createMock(ExecutionContext.class); @@ -75,6 +77,7 @@ MoreAsserts.assertListEquals( ImmutableList.of( "java", + "-Djava.io.tmpdir=" + directoryForTemp, vmArg1, vmArg2, "-verbose", @@ -102,6 +105,7 @@ List<String> vmArgs = ImmutableList.of(vmArg1, vmArg2); String directoryForTestResults = "buck-gen/theresults/"; + String directoryForTemp = "buck-gen/thetmp/"; boolean isCodeCoverageEnabled = false; boolean isDebugEnabled = true; String testRunnerClassesDirectory = "build/classes/junit"; @@ -113,6 +117,7 @@ directoryForTestResults, isCodeCoverageEnabled, isDebugEnabled, + directoryForTemp, testRunnerClassesDirectory); @@ -135,6 +140,7 @@ MoreAsserts.assertListEquals( ImmutableList.of( "java", + "-Djava.io.tmpdir=" + directoryForTemp, "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005", vmArg1, vmArg2,