Skip to content

Commit

Permalink
Switches AndroidRobolectricTest to using .aars to provide transitive …
Browse files Browse the repository at this point in the history
…resources to the test runner instead of ResourceContainers. Update AndroidLibraryAarProvider to contain transitive closure of .aars. Provides an ~4x speed improvement in test startup time.

NEW: Switched to ordered maps in CompositeLibraryAndroidManifestLocator to prevent manifest ordering flakiness bug. Switched to ImmutableSetMultimap in CompositeLibraryAndroidManifestLocator to prevent IllegalArgumentExceptions from duplicate package aliases and added test.

RELNOTES: android_resources is no longer allowed as a dep for android_robolectric_test.

--
MOS_MIGRATED_REVID=101972311
  • Loading branch information
apelle03 authored and kchodorow committed Sep 1, 2015
1 parent a7deb78 commit d23b7fb
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.rules.android.AndroidLibraryAarProvider.Aar;
import com.google.devtools.build.lib.rules.android.AndroidResourcesProvider.ResourceContainer;
import com.google.devtools.build.lib.rules.android.AndroidResourcesProvider.ResourceType;
import com.google.devtools.build.lib.rules.cpp.LinkerInput;
Expand Down Expand Up @@ -68,6 +69,7 @@ public ConfiguredTarget create(RuleContext ruleContext) {
checkIdlRootImport(ruleContext);
NestedSet<AndroidResourcesProvider.ResourceContainer> transitiveResources =
collectTransitiveResources(ruleContext);
NestedSetBuilder<Aar> transitiveAars = collectTransitiveAars(ruleContext);
NestedSet<LinkerInput> transitiveNativeLibraries =
AndroidCommon.collectTransitiveNativeLibraries(deps);
NestedSet<Artifact> transitiveProguardConfigs =
Expand Down Expand Up @@ -123,6 +125,8 @@ public ConfiguredTarget create(RuleContext ruleContext) {
.setAAROut(aarOut)
.build(ruleContext);

Aar aar = new Aar(aarOut, applicationManifest.getManifest());

RuleConfiguredTargetBuilder builder = new RuleConfiguredTargetBuilder(ruleContext);
androidCommon.addTransitiveInfoProviders(builder);
androidSemantics.addTransitiveInfoProviders(
Expand All @@ -141,8 +145,8 @@ public ConfiguredTarget create(RuleContext ruleContext) {
.add(AndroidCcLinkParamsProvider.class,
new AndroidCcLinkParamsProvider(androidCommon.getCcLinkParamsStore()))
.add(ProguardSpecProvider.class, new ProguardSpecProvider(transitiveProguardConfigs))
.add(AndroidLibraryAarProvider.class, new AndroidLibraryAarProvider(aarOut,
applicationManifest.getManifest()))
.add(AndroidLibraryAarProvider.class, new AndroidLibraryAarProvider(aar,
transitiveAars.add(aar).build()))
.addOutputGroup(OutputGroupProvider.HIDDEN_TOP_LEVEL, transitiveProguardConfigs)
.build();
} catch (RuleConfigurationException e) {
Expand Down Expand Up @@ -196,8 +200,10 @@ public ConfiguredTarget create(RuleContext ruleContext) {
if (AndroidCommon.getAndroidResources(ruleContext) != null) {
primaryResources = Iterables.getOnlyElement(
AndroidCommon.getAndroidResources(ruleContext).getTransitiveAndroidResources());

Aar aar = new Aar(aarOut, primaryResources.getManifest());
targetBuilder.add(AndroidLibraryAarProvider.class, new AndroidLibraryAarProvider(
aarOut, primaryResources.getManifest()));
aar, transitiveAars.add(aar).build()));
} else {
// there are no local resources and resources attribute was not specified either
ApplicationManifest applicationManifest =
Expand Down Expand Up @@ -238,6 +244,9 @@ public ConfiguredTarget create(RuleContext ruleContext) {
ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT)
.setWorkingDirectory(ruleContext.getUniqueDirectory("_resources"))
.build(ruleContext);

targetBuilder.add(AndroidLibraryAarProvider.class, new AndroidLibraryAarProvider(
null, transitiveAars.build()));
}

new AarGeneratorBuilder(ruleContext)
Expand Down Expand Up @@ -342,6 +351,15 @@ private NestedSet<ResourceContainer> collectTransitiveResources(RuleContext rule
return builder.build();
}

private NestedSetBuilder<Aar> collectTransitiveAars(RuleContext ruleContext) {
NestedSetBuilder<Aar> builder = NestedSetBuilder.naiveLinkOrder();
for (AndroidLibraryAarProvider library :
ruleContext.getPrerequisites("deps", Mode.TARGET, AndroidLibraryAarProvider.class)) {
builder.addTransitive(library.getTransitiveAars());
}
return builder;
}

private boolean hasExplicitlySpecifiedIdlImportRoot(RuleContext ruleContext) {
return ruleContext.getRule().isAttributeValueExplicitlySpecified("idl_import_root");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,70 @@
import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;

import java.util.Objects;

/**
* A target that can provide the aar artifact of Android libraries and all the manifests that are
* merged into the main aar manifest.
*/
@Immutable
public final class AndroidLibraryAarProvider implements TransitiveInfoProvider {

private final Artifact aar;
private final Artifact manifest;
private final Aar aar;
private final NestedSet<Aar> transitiveAars;

public AndroidLibraryAarProvider(Artifact aar, Artifact manifest) {
this.aar = Preconditions.checkNotNull(aar);
this.manifest = Preconditions.checkNotNull(manifest);
public AndroidLibraryAarProvider(Aar aar, NestedSet<Aar> transitiveAars) {
this.aar = aar;
this.transitiveAars = transitiveAars;
}

public Artifact getAar() {
public Aar getAar() {
return aar;
}

public Artifact getManifest() {
return manifest;
public NestedSet<Aar> getTransitiveAars() {
return transitiveAars;
}

/**
* The .aar file and associated AndroidManifest.xml contributed by a single target.
*/
@Immutable
public static final class Aar {
private final Artifact aar;
private final Artifact manifest;

public Aar(Artifact aar, Artifact manifest) {
this.aar = Preconditions.checkNotNull(aar);
this.manifest = Preconditions.checkNotNull(manifest);
}

public Artifact getAar() {
return aar;
}

public Artifact getManifest() {
return manifest;
}

@Override
public int hashCode() {
return Objects.hash(aar, manifest);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Aar)) {
return false;
}
Aar other = (Aar) obj;
return aar.equals(other.aar) && manifest.equals(other.manifest);
}
}
}

0 comments on commit d23b7fb

Please sign in to comment.