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 4f100ae..c192838 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.BuildRuleParams;
import com.facebook.buck.rules.BuildRuleType;
+import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -42,7 +43,8 @@
Optional<String> proguardConfig,
JavacOptions javacOptions,
List<String> vmArgs,
- ImmutableSet<JavaLibraryRule> sourceUnderTest) {
+ ImmutableSet<JavaLibraryRule> sourceUnderTest,
+ Function<String, String> relativeToAbsolutePathFunction) {
super(buildRuleParams,
srcs,
resources,
@@ -50,7 +52,8 @@
proguardConfig,
javacOptions,
vmArgs,
- sourceUnderTest);
+ sourceUnderTest,
+ relativeToAbsolutePathFunction);
}
@Override
@@ -93,7 +96,8 @@
proguardConfig,
javacOptions.build(),
allVmArgs.build(),
- sourceUnderTest);
+ sourceUnderTest,
+ relativeToAbsolutePathFunction);
}
@Override
diff --git a/src/com/facebook/buck/java/JUnitStep.java b/src/com/facebook/buck/java/JUnitStep.java
index 109d959..a4af578 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",
new File("build/testrunner/classes").getAbsolutePath()));
}
@@ -95,6 +101,7 @@
String directoryForTestResults,
boolean isCodeCoverageEnabled,
boolean isDebugEnabled,
+ String tmpDirectory,
String testRunnerClassesDirectory) {
this.classpathEntries = ImmutableSet.copyOf(classpathEntries);
this.testClassNames = ImmutableSet.copyOf(testClassNames);
@@ -102,6 +109,7 @@
this.directoryForTestResults = Preconditions.checkNotNull(directoryForTestResults);
this.isCodeCoverageEnabled = isCodeCoverageEnabled;
this.isDebugEnabled = isDebugEnabled;
+ this.tmpDirectory = tmpDirectory;
this.testRunnerClassesDirectory = Preconditions.checkNotNull(testRunnerClassesDirectory);
}
@@ -114,6 +122,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.
@@ -180,6 +189,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 612c389..410d70b 100644
--- a/src/com/facebook/buck/java/JavaTestRule.java
+++ b/src/com/facebook/buck/java/JavaTestRule.java
@@ -32,10 +32,12 @@
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.ProjectFilesystem;
import com.facebook.buck.util.ZipFileTraversal;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
@@ -68,6 +70,7 @@
private CompiledClassFileFinder compiledClassFileFinder;
private final ImmutableSet<String> labels;
+ private final String tmpDirectory;
protected JavaTestRule(BuildRuleParams buildRuleParams,
Set<String> srcs,
@@ -76,7 +79,8 @@
Optional<String> proguardConfig,
JavacOptions javacOptions,
List<String> vmArgs,
- ImmutableSet<JavaLibraryRule> sourceUnderTest) {
+ ImmutableSet<JavaLibraryRule> sourceUnderTest,
+ Function<String, String> relativeToAbsolutePathFunction) {
super(buildRuleParams,
srcs,
resources,
@@ -86,6 +90,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,
+ buildRuleParams.getBuildTarget().getBasePath(),
+ getBuildTarget().getShortName()
+ );
+ this.tmpDirectory = relativeToAbsolutePathFunction.apply(temp);
}
@Override
@@ -144,8 +155,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.
@@ -168,6 +179,7 @@
testClassNames,
vmArgs,
pathToTestOutput,
+ tmpDirectory,
executionContext.isCodeCoverageEnabled(),
executionContext.isDebugEnabled());
steps.add(junit);
@@ -343,6 +355,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() {}
@@ -360,7 +374,8 @@
proguardConfig,
javacOptions.build(),
vmArgs,
- sourceUnderTest);
+ sourceUnderTest,
+ relativeToAbsolutePathFunction);
}
@Override
@@ -397,6 +412,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 1993687..13b9a98 100644
--- a/test/com/facebook/buck/java/JUnitStepTest.java
+++ b/test/com/facebook/buck/java/JUnitStepTest.java
@@ -53,6 +53,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";
@@ -64,6 +65,7 @@
directoryForTestResults,
isCodeCoverageEnabled,
isDebugEnabled,
+ directoryForTemp,
testRunnerClassesDirectory);
ExecutionContext executionContext = EasyMock.createMock(ExecutionContext.class);
@@ -77,6 +79,7 @@
MoreAsserts.assertListEquals(
ImmutableList.of(
"java",
+ "-Djava.io.tmpdir=" + directoryForTemp,
vmArg1,
vmArg2,
"-verbose",
@@ -105,6 +108,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";
@@ -116,6 +120,7 @@
directoryForTestResults,
isCodeCoverageEnabled,
isDebugEnabled,
+ directoryForTemp,
testRunnerClassesDirectory);
@@ -134,6 +139,7 @@
MoreAsserts.assertListEquals(
ImmutableList.of(
"java",
+ "-Djava.io.tmpdir=" + directoryForTemp,
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005",
vmArg1,
vmArg2,