Skip to content

Commit

Permalink
Make RobolectricTest list transitive resources as runtime deps.
Browse files Browse the repository at this point in the history
Summary:
Robolectric requires the resource folders for transitive resource rules to be
present in order to run. These are either PathSourcePaths or BuildTargetSourcePaths.
If they're the latter (for example GenRules) they need to be downloaded too.

Test Plan: CI
  • Loading branch information
mkosiba authored and Gray0Ed committed Oct 17, 2015
1 parent 976235e commit 7b480a2
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 2 deletions.
25 changes: 23 additions & 2 deletions src/com/facebook/buck/android/RobolectricTest.java
Expand Up @@ -32,6 +32,7 @@
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.TargetDevice;
import com.facebook.buck.util.Optionals;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Functions;
Expand Down Expand Up @@ -77,6 +78,22 @@ public Path apply(HasAndroidResourceDeps input) {
.get();
}
};
private final Function<DummyRDotJava, ImmutableSet<BuildRule>> resourceRulesFunction =
new Function<DummyRDotJava, ImmutableSet<BuildRule>>() {
@Override
public ImmutableSet<BuildRule> apply(DummyRDotJava input) {
ImmutableSet.Builder<BuildRule> resourceDeps = ImmutableSet.builder();
for (HasAndroidResourceDeps hasAndroidResourceDeps :
input.getAndroidResourceDeps()) {
SourcePath resSourcePath = hasAndroidResourceDeps.getRes();
if (resSourcePath == null) {
continue;
}
Optionals.addIfPresent(getResolver().getRule(resSourcePath), resourceDeps);
}
return resourceDeps.build();
}
};

protected RobolectricTest(
BuildRuleParams buildRuleParams,
Expand Down Expand Up @@ -188,8 +205,12 @@ public ImmutableSortedSet<BuildRule> getRuntimeDeps() {
// Inherit any runtime deps from `JavaTest`.
.addAll(super.getRuntimeDeps())
// On top of the runtime dependencies of a normal {@link JavaTest}, we need to make the
// {@link DummyRDotJava} is available locally, if it exists, to run this test.
.addAll(Optional.presentInstances(ImmutableList.of(optionalDummyRDotJava)))
// {@link DummyRDotJava} and any of its resource deps is available locally (if it exists)
// to run this test.
.addAll(optionalDummyRDotJava.asSet())
.addAll(optionalDummyRDotJava
.transform(resourceRulesFunction)
.or(ImmutableSet.<BuildRule>of()))
// It's possible that the user added some tool as a dependency, so make sure we promote
// this rules first-order deps to runtime deps, so that these potential tools are available
// when this test runs.
Expand Down
29 changes: 29 additions & 0 deletions test/com/facebook/buck/android/RobolectricTestRuleTest.java
Expand Up @@ -25,11 +25,14 @@
import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.BuildTargetSourcePath;
import com.facebook.buck.rules.PathSourcePath;
import com.facebook.buck.rules.Sha1HashCode;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.TestSourcePath;
import com.facebook.buck.shell.GenruleBuilder;
import com.facebook.buck.testutil.FakeProjectFilesystem;
import com.google.common.collect.ImmutableList;

Expand Down Expand Up @@ -179,4 +182,30 @@ public void testRobolectricThrowsIfResourceDirNotThere() throws IOException {
assertThat(e.getMessage(), Matchers.containsString("not_there"));
}
}

@Test
public void runtimeDepsIncludeTransitiveResources() throws IOException {
BuildRuleResolver resolver = new BuildRuleResolver();
ProjectFilesystem filesystem = new FakeProjectFilesystem(temporaryFolder.getRoot());

BuildTarget genRuleTarget = BuildTargetFactory.newInstance("//:gen");
BuildRule genRule = GenruleBuilder.newGenruleBuilder(genRuleTarget)
.setOut("out")
.build(resolver);

BuildTarget res2RuleTarget = BuildTargetFactory.newInstance("//:res2");
AndroidResourceBuilder.createBuilder(res2RuleTarget)
.setRes(new BuildTargetSourcePath(genRuleTarget))
.setRDotJavaPackage("foo.bar")
.build(resolver);

BuildTarget robolectricBuildTarget = BuildTargetFactory.newInstance(
"//java/src/com/facebook/base/robolectricTest:robolectricTest");
RobolectricTest robolectricTest = (RobolectricTest) RobolectricTestBuilder
.createBuilder(robolectricBuildTarget)
.addDep(res2RuleTarget)
.build(resolver, filesystem);

assertThat(robolectricTest.getRuntimeDeps(), Matchers.hasItem(genRule));
}
}

0 comments on commit 7b480a2

Please sign in to comment.