diff options
8 files changed, 464 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java index 922d87e7dc..f8aebaefd4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java @@ -64,6 +64,7 @@ import com.google.devtools.build.lib.rules.java.JavaUtil; import com.google.devtools.build.lib.rules.java.proto.GeneratedExtensionRegistryProvider; import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.InstrumentationSpec; import com.google.devtools.build.lib.syntax.Type; +import com.google.devtools.build.lib.util.FileType; import com.google.devtools.build.lib.util.Preconditions; import com.google.devtools.build.lib.vfs.PathFragment; import java.util.ArrayList; @@ -962,4 +963,26 @@ public class AndroidCommon { return new JavaCommon(ruleContext, semantics, srcs, compileDeps, runtimeDeps, bothDeps); } + + /** + * Gets the transitive support APKs required by this rule through the {@code support_apks} + * attribute. + */ + static NestedSet<Artifact> getSupportApks(RuleContext ruleContext) { + NestedSetBuilder<Artifact> supportApks = NestedSetBuilder.stableOrder(); + for (TransitiveInfoCollection dep : ruleContext.getPrerequisites("support_apks", Mode.TARGET)) { + ApkProvider apkProvider = dep.getProvider(ApkProvider.class); + FileProvider fileProvider = dep.getProvider(FileProvider.class); + // If ApkProvider is present, do not check FileProvider for .apk files. For example, + // android_binary creates a FileProvider containing both the signed and unsigned APKs. + if (apkProvider != null) { + supportApks.addTransitive(apkProvider.getTransitiveApks()); + } else if (fileProvider != null) { + // The rule definition should enforce that only .apk files are allowed, however, it can't + // hurt to double check. + supportApks.addAll(FileType.filter(fileProvider.getFilesToBuild(), AndroidRuleClasses.APK)); + } + } + return supportApks.build(); + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixture.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixture.java new file mode 100644 index 0000000000..648b282831 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixture.java @@ -0,0 +1,85 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// 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.google.devtools.build.lib.rules.android; + +import com.google.common.collect.Iterables; +import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.analysis.FileProvider; +import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; +import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; +import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.RunfilesProvider; +import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; +import com.google.devtools.build.lib.analysis.actions.FileWriteAction; +import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; +import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory; +import com.google.devtools.build.lib.syntax.Type; + +/** An implementation of the {@code android_device_script_fixture} rule. */ +public class AndroidDeviceScriptFixture implements RuleConfiguredTargetFactory { + + @Override + public ConfiguredTarget create(RuleContext ruleContext) + throws InterruptedException, RuleErrorException { + Artifact fixtureScript = getFixtureScript(ruleContext); + return new RuleConfiguredTargetBuilder(ruleContext) + .setFilesToBuild(NestedSetBuilder.<Artifact>stableOrder().add(fixtureScript).build()) + .addProvider(RunfilesProvider.class, RunfilesProvider.EMPTY) + .addNativeDeclaredProvider( + new AndroidDeviceScriptFixtureInfoProvider( + fixtureScript, + AndroidCommon.getSupportApks(ruleContext), + ruleContext.attributes().get("daemon", Type.BOOLEAN), + ruleContext.attributes().get("strict_exit", Type.BOOLEAN))) + .build(); + } + + /** + * Gets the fixture script from the {@code script} attribute if set or else writes a file + * containing the contents of the {@code cmd} attribute. Also, checks that exactly one of {@code + * script} and {@code cmd} is set. + */ + private static Artifact getFixtureScript(RuleContext ruleContext) + throws RuleErrorException, InterruptedException { + String cmd = null; + if (ruleContext.attributes().isAttributeValueExplicitlySpecified("cmd")) { + cmd = ruleContext.attributes().get("cmd", Type.STRING); + } + TransitiveInfoCollection script = ruleContext.getPrerequisite("script", Mode.TARGET); + + if (((cmd == null) && (script == null)) || ((cmd != null) && (script != null))) { + ruleContext.throwWithRuleError( + "android_host_service_fixture requires that exactly one of the script and cmd attributes " + + "be specified"); + } + + if (cmd == null) { + // The fact that there is only one file and that it has the right extension is enforced by the + // rule definition. + return Iterables.getOnlyElement(script.getProvider(FileProvider.class).getFilesToBuild()); + } else { + return writeFixtureScript(ruleContext, cmd); + } + } + + private static Artifact writeFixtureScript(RuleContext ruleContext, String cmd) + throws InterruptedException { + Artifact output = + ruleContext.getUniqueDirectoryArtifact( + "cmd_device_fixtures", "cmd.sh", ruleContext.getBinOrGenfilesDirectory()); + ruleContext.registerAction(FileWriteAction.create(ruleContext, output, cmd, false)); + return output; + } +} diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixtureInfoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixtureInfoProvider.java new file mode 100644 index 0000000000..42b7b11a70 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixtureInfoProvider.java @@ -0,0 +1,65 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// 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.google.devtools.build.lib.rules.android; + +import com.google.common.collect.ImmutableMap; +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 com.google.devtools.build.lib.packages.NativeClassObjectConstructor; +import com.google.devtools.build.lib.packages.SkylarkClassObject; + +/** + * Information about an {@code android_device_script_fixture} to run as part of an {@code + * android_instrumentation_test}. + */ +@Immutable +public class AndroidDeviceScriptFixtureInfoProvider extends SkylarkClassObject + implements TransitiveInfoProvider { + + private static final String SKYLARK_NAME = "DeviceScriptFixtureInfo"; + public static final NativeClassObjectConstructor ANDROID_DEVICE_SCRIPT_FIXTURE_INFO = + new NativeClassObjectConstructor(SKYLARK_NAME) {}; + + private final Artifact fixtureScript; + private final NestedSet<Artifact> supportApks; + private final boolean daemon; + private final boolean strictExit; + + public AndroidDeviceScriptFixtureInfoProvider( + Artifact fixtureScript, NestedSet<Artifact> supportApks, boolean daemon, boolean strictExit) { + super(ANDROID_DEVICE_SCRIPT_FIXTURE_INFO, ImmutableMap.<String, Object>of()); + this.fixtureScript = fixtureScript; + this.supportApks = supportApks; + this.daemon = daemon; + this.strictExit = strictExit; + } + + public Artifact getFixtureScript() { + return fixtureScript; + } + + public NestedSet<Artifact> getSupportApks() { + return supportApks; + } + + public boolean getDaemon() { + return daemon; + } + + public boolean getStrictExit() { + return strictExit; + } +} diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixtureRule.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixtureRule.java new file mode 100644 index 0000000000..9904978c4c --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixtureRule.java @@ -0,0 +1,61 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// 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.google.devtools.build.lib.rules.android; + +import static com.google.devtools.build.lib.packages.Attribute.attr; +import static com.google.devtools.build.lib.packages.BuildType.LABEL; +import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; +import static com.google.devtools.build.lib.syntax.Type.BOOLEAN; +import static com.google.devtools.build.lib.syntax.Type.STRING; + +import com.google.devtools.build.lib.analysis.BaseRuleClasses; +import com.google.devtools.build.lib.analysis.RuleDefinition; +import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; +import com.google.devtools.build.lib.packages.RuleClass; +import com.google.devtools.build.lib.packages.RuleClass.Builder; +import com.google.devtools.build.lib.util.FileType; + +/** Rule definition for the {@code android_device_script_fixture} rule. */ +public class AndroidDeviceScriptFixtureRule implements RuleDefinition { + + static final FileType DEVICE_SCRIPT_FIXTURE = FileType.of(".sh"); + + @Override + public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) { + return builder + .setUndocumented() + .add( + attr("script", LABEL) + .exec() + .allowedFileTypes(DEVICE_SCRIPT_FIXTURE) + .allowedRuleClasses()) + .add(attr("cmd", STRING)) + .add( + attr("support_apks", LABEL_LIST) + .allowedFileTypes(AndroidRuleClasses.APK) + .allowedRuleClasses("android_binary")) + .add(attr("daemon", BOOLEAN).value(Boolean.FALSE)) + .add(attr("strict_exit", BOOLEAN).value(Boolean.TRUE)) + .build(); + } + + @Override + public Metadata getMetadata() { + return RuleDefinition.Metadata.builder() + .name("android_device_script_fixture") + .ancestors(BaseRuleClasses.RuleBase.class) + .factoryClass(AndroidDeviceScriptFixture.class) + .build(); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java index d352144810..d70894dabf 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java @@ -171,6 +171,7 @@ public final class AndroidRuleClasses { fromTemplates("%{name}_images/userdata_images.dat"); public static final SafeImplicitOutputsFunction ANDROID_DEVICE_EMULATOR_METADATA = fromTemplates("%{name}_images/emulator-meta-data.pb"); + static final FileType APK = FileType.of(".apk"); /** * The default label of android_sdk option diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBuildViewTestCase.java index 2811cb6a2a..3b2d2001ac 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBuildViewTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBuildViewTestCase.java @@ -27,6 +27,7 @@ import com.google.common.truth.Truth; import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.FileProvider; import com.google.devtools.build.lib.analysis.OutputFileConfiguredTarget; @@ -37,6 +38,7 @@ import com.google.devtools.build.lib.rules.android.deployinfo.AndroidDeployInfoO import com.google.devtools.build.lib.rules.java.JavaCompileAction; import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider; import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar; +import com.google.devtools.build.lib.testutil.TestRuleClassProvider; import com.google.devtools.build.lib.util.Preconditions; import java.io.IOException; import java.util.Arrays; @@ -45,6 +47,17 @@ import javax.annotation.Nullable; /** Common methods shared between Android related {@link BuildViewTestCase}s. */ public abstract class AndroidBuildViewTestCase extends BuildViewTestCase { + + @Override + protected ConfiguredRuleClassProvider getRuleClassProvider() { + ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder(); + TestRuleClassProvider.addStandardRules(builder); + return builder + // TODO(b/35097211): Remove this once the new testing rules are released. + .addRuleDefinition(new AndroidDeviceScriptFixtureRule()) + .build(); + } + protected Iterable<Artifact> getNativeLibrariesInApk(ConfiguredTarget target) { SpawnAction compressedUnsignedApkaction = getCompressedUnsignedApkAction(target); ImmutableList.Builder<Artifact> result = ImmutableList.builder(); diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixtureTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixtureTest.java new file mode 100644 index 0000000000..6149580254 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixtureTest.java @@ -0,0 +1,197 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// 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.google.devtools.build.lib.rules.android; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.devtools.build.lib.actions.util.ActionsTestUtil; +import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.analysis.actions.FileWriteAction; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link AndroidDeviceScriptFixture}. */ +@RunWith(JUnit4.class) +public class AndroidDeviceScriptFixtureTest extends AndroidBuildViewTestCase { + + @Before + public void setup() throws Exception { + scratch.file("scripts/BUILD", "exports_files(['my_script.sh'])"); + scratch.file( + "java/com/app/BUILD", + "android_binary(", + " name = 'app',", + " manifest = 'AndroidManifest.xml',", + ")"); + scratch.file( + "java/com/app/support/BUILD", + "android_binary(", + " name = 'support',", + " manifest = 'AndroidManifest.xml',", + ")", + "genrule(", + " name = 'genrule',", + " outs = ['generated.apk'],", + " cmd = 'touch $(OUTS)',", + ")"); + } + + @Test + public void testScriptFixture() throws Exception { + scratch.file( + "javatests/com/app/BUILD", + "android_device_script_fixture(", + " name = 'fixture',", + " script = '//scripts:my_script.sh',", + ")"); + ConfiguredTarget fixture = getConfiguredTarget("//javatests/com/app:fixture"); + assertThat(fixture).isNotNull(); + AndroidDeviceScriptFixtureInfoProvider deviceScriptFixtureInfoProvider = + (AndroidDeviceScriptFixtureInfoProvider) + fixture.get( + AndroidDeviceScriptFixtureInfoProvider.ANDROID_DEVICE_SCRIPT_FIXTURE_INFO.getKey()); + assertThat(deviceScriptFixtureInfoProvider).isNotNull(); + assertThat(deviceScriptFixtureInfoProvider.getFixtureScript()).isNotNull(); + assertThat(deviceScriptFixtureInfoProvider.getFixtureScript().prettyPrint()) + .isEqualTo("scripts/my_script.sh"); + } + + @Test + public void testCommandFixture() throws Exception { + scratch.file( + "javatests/com/app/BUILD", + "android_device_script_fixture(", + " name = 'fixture',", + " cmd = 'some literal command',", + ")"); + ConfiguredTarget fixture = getConfiguredTarget("//javatests/com/app:fixture"); + assertThat(fixture).isNotNull(); + AndroidDeviceScriptFixtureInfoProvider deviceScriptFixtureInfoProvider = + (AndroidDeviceScriptFixtureInfoProvider) + fixture.get( + AndroidDeviceScriptFixtureInfoProvider.ANDROID_DEVICE_SCRIPT_FIXTURE_INFO.getKey()); + assertThat(deviceScriptFixtureInfoProvider).isNotNull(); + assertThat(deviceScriptFixtureInfoProvider.getFixtureScript()).isNotNull(); + assertThat(deviceScriptFixtureInfoProvider.getFixtureScript().prettyPrint()) + .isEqualTo("javatests/com/app/cmd_device_fixtures/fixture/cmd.sh"); + FileWriteAction action = + (FileWriteAction) getGeneratingAction(deviceScriptFixtureInfoProvider.getFixtureScript()); + assertThat(action.getFileContents()).isEqualTo("some literal command"); + } + + @Test + public void testNoScriptOrCommand() throws Exception { + checkError( + "javatests/com/app", + "fixture", + "android_host_service_fixture requires that exactly one of the script and cmd attributes " + + "be specified", + "android_device_script_fixture(", + " name = 'fixture',", + ")"); + } + + @Test + public void testScriptAndCommand() throws Exception { + checkError( + "javatests/com/app", + "fixture", + "android_host_service_fixture requires that exactly one of the script and cmd attributes " + + "be specified", + "android_device_script_fixture(", + " name = 'fixture',", + " script = '//scripts:my_script.sh',", + " cmd = 'some literal command',", + ")"); + } + + @Test + public void testSupportApks() throws Exception { + scratch.file( + "javatests/com/app/BUILD", + "android_device_script_fixture(", + " name = 'fixture',", + " cmd = 'some literal command',", + " support_apks = [", + " '//java/com/app/support',", + " '//java/com/app/support:generated.apk',", + " ],", + ")"); + ConfiguredTarget fixture = getConfiguredTarget("//javatests/com/app:fixture"); + assertThat(fixture).isNotNull(); + AndroidDeviceScriptFixtureInfoProvider deviceScriptFixtureInfoProvider = + (AndroidDeviceScriptFixtureInfoProvider) + fixture.get( + AndroidDeviceScriptFixtureInfoProvider.ANDROID_DEVICE_SCRIPT_FIXTURE_INFO.getKey()); + assertThat(deviceScriptFixtureInfoProvider).isNotNull(); + + assertThat( + ActionsTestUtil.prettyArtifactNames(deviceScriptFixtureInfoProvider.getSupportApks())) + .containsExactly("java/com/app/support/support.apk", "java/com/app/support/generated.apk") + .inOrder(); + } + + @Test + public void testNonSupportedScriptExtension() throws Exception { + scratch.file("javatests/com/app/script.bat"); + checkError( + "javatests/com/app", + "fixture", + "file '//javatests/com/app:script.bat' is misplaced here (expected .sh)", + "android_device_script_fixture(", + " name = 'fixture',", + " script = 'script.bat',", + ")"); + } + + @Test + public void testDaemonIsProvided() throws Exception { + scratch.file( + "javatests/com/app/BUILD", + "android_device_script_fixture(", + " name = 'fixture',", + " cmd = 'some literal command',", + " daemon = 1,", + ")"); + ConfiguredTarget fixture = getConfiguredTarget("//javatests/com/app:fixture"); + assertThat(fixture).isNotNull(); + AndroidDeviceScriptFixtureInfoProvider deviceScriptFixtureInfoProvider = + (AndroidDeviceScriptFixtureInfoProvider) + fixture.get( + AndroidDeviceScriptFixtureInfoProvider.ANDROID_DEVICE_SCRIPT_FIXTURE_INFO.getKey()); + assertThat(deviceScriptFixtureInfoProvider).isNotNull(); + assertThat(deviceScriptFixtureInfoProvider.getDaemon()).isTrue(); + } + + @Test + public void testStrictExitIsProvided() throws Exception { + scratch.file( + "javatests/com/app/BUILD", + "android_device_script_fixture(", + " name = 'fixture',", + " cmd = 'some literal command',", + " strict_exit = 1,", + ")"); + ConfiguredTarget fixture = getConfiguredTarget("//javatests/com/app:fixture"); + assertThat(fixture).isNotNull(); + AndroidDeviceScriptFixtureInfoProvider deviceScriptFixtureInfoProvider = + (AndroidDeviceScriptFixtureInfoProvider) + fixture.get( + AndroidDeviceScriptFixtureInfoProvider.ANDROID_DEVICE_SCRIPT_FIXTURE_INFO.getKey()); + assertThat(deviceScriptFixtureInfoProvider).isNotNull(); + assertThat(deviceScriptFixtureInfoProvider.getStrictExit()).isTrue(); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/BUILD b/src/test/java/com/google/devtools/build/lib/rules/android/BUILD index 3d8368d1d7..c438825f59 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/android/BUILD +++ b/src/test/java/com/google/devtools/build/lib/rules/android/BUILD @@ -77,6 +77,24 @@ java_test( ) java_test( + name = "AndroidDeviceScriptFixtureTest", + srcs = ["AndroidDeviceScriptFixtureTest.java"], + deps = [ + ":AndroidBuildViewTestCase", + "//src/main/java/com/google/devtools/build/lib:android-rules", + "//src/main/java/com/google/devtools/build/lib:build-base", + "//src/main/java/com/google/devtools/build/lib:packages-internal", + "//src/main/java/com/google/devtools/build/lib/actions", + "//src/test/java/com/google/devtools/build/lib:actions_testutil", + "//src/test/java/com/google/devtools/build/lib:analysis_testutil", + "//src/test/java/com/google/devtools/build/lib:testutil", + "//third_party:guava", + "//third_party:junit4", + "//third_party:truth", + ], +) + +java_test( name = "AndroidLibraryTest", srcs = ["AndroidLibraryTest.java"], deps = [ @@ -110,6 +128,7 @@ java_library( "//src/main/protobuf:android_deploy_info_java_proto", "//src/test/java/com/google/devtools/build/lib:actions_testutil", "//src/test/java/com/google/devtools/build/lib:analysis_testutil", + "//src/test/java/com/google/devtools/build/lib:testutil", "//third_party:guava", "//third_party:junit4", "//third_party:truth", |