aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/objc
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/objc')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalIosTest.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalIosTestRule.java46
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/LabDeviceTemplateProvider.java49
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java96
4 files changed, 166 insertions, 34 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalIosTest.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalIosTest.java
index 069963c298..5bbd81f126 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalIosTest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalIosTest.java
@@ -43,10 +43,11 @@ public final class ExperimentalIosTest extends IosTest {
NestedSetBuilder<Artifact> filesToBuildBuilder = NestedSetBuilder.<Artifact>stableOrder();
filesToBuildBuilder.addTransitive(filesToBuild);
- TestSupport testSupport = new TestSupport(ruleContext)
- .registerTestRunnerActionsForSimulator()
- .addRunfiles(runfilesBuilder)
- .addFilesToBuild(filesToBuildBuilder);
+ TestSupport testSupport =
+ new TestSupport(ruleContext)
+ .registerTestRunnerActions()
+ .addRunfiles(runfilesBuilder)
+ .addFilesToBuild(filesToBuildBuilder);
Artifact executable = testSupport.generatedTestScript();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalIosTestRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalIosTestRule.java
index f6cb640f98..2a866b720c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalIosTestRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalIosTestRule.java
@@ -17,6 +17,7 @@ package com.google.devtools.build.lib.rules.objc;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.Type.LABEL;
import static com.google.devtools.build.lib.packages.Type.LABEL_LIST;
+import static com.google.devtools.build.lib.packages.Type.STRING_LIST;
import com.google.devtools.build.lib.Constants;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
@@ -39,23 +40,40 @@ public final class ExperimentalIosTestRule implements RuleDefinition {
public RuleClass build(RuleClass.Builder builder, final RuleDefinitionEnvironment env) {
return builder
/*<!-- #BLAZE_RULE(experimental_ios_test).IMPLICIT_OUTPUTS -->
- <ul>
- <li><code><var>name</var>.ipa</code>: the test bundle as an
- <code>.ipa</code> file
- <li><code><var>name</var>.xcodeproj/project.pbxproj: An Xcode project file which can be
- used to develop or build on a Mac.</li>
- </ul>
- <!-- #END_BLAZE_RULE.IMPLICIT_OUTPUTS -->*/
+ <ul>
+ <li><code><var>name</var>.ipa</code>: the test bundle as an
+ <code>.ipa</code> file
+ <li><code><var>name</var>.xcodeproj/project.pbxproj: An Xcode project file which can be
+ used to develop or build on a Mac.</li>
+ </ul>
+ <!-- #END_BLAZE_RULE.IMPLICIT_OUTPUTS -->*/
.setImplicitOutputsFunction(
ImplicitOutputsFunction.fromFunctions(ReleaseBundlingSupport.IPA, XcodeSupport.PBXPROJ))
- .override(attr(IosTest.TARGET_DEVICE, LABEL)
- .allowedFileTypes()
- .allowedRuleClasses(Constants.IOS_DEVICE_RULE_CLASSES)
- .value(env.getLabel("//tools/objc/sim_devices:default")))
+ .override(
+ attr(IosTest.TARGET_DEVICE, LABEL)
+ .allowedFileTypes()
+ .allowedRuleClasses(Constants.IOS_DEVICE_RULE_CLASSES)
+ .value(env.getLabel("//tools/objc/sim_devices:default")))
+ /* <!-- #BLAZE_RULE(experimental_ios_test).ATTRIBUTE(ios_test_target_device) -->
+ The device against how to run the test. If this attribute is defined, the test will run on
+ the lab device. Otherwise, the test will run on simulator.
+ ${SYNOPSIS}
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(
+ attr("ios_test_target_device", LABEL)
+ .allowedFileTypes()
+ .allowedRuleClasses("ios_lab_device"))
+ /* <!-- #BLAZE_RULE(experimental_ios_test).ATTRIBUTE(ios_device_arg) -->
+ Extra arguments to pass to the <code>ios_test_target_device</code>'s binary. They should be
+ in the form KEY=VALUE or simply KEY (check your device's documentation for allowed
+ parameters).
+ ${SYNOPSIS}
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(attr("ios_device_arg", STRING_LIST))
/* <!-- #BLAZE_RULE(experimental_ios_test).ATTRIBUTE(plugins) -->
- Plugins to pass to the test runner.
- ${SYNOPSIS}
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ Plugins to pass to the test runner.
+ ${SYNOPSIS}
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
.add(attr("plugins", LABEL_LIST).allowedFileTypes(FileType.of("_deploy.jar")))
.add(attr("$test_template", LABEL)
.value(env.getLabel("//tools/objc:ios_test.sh.bazel_template")))
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/LabDeviceTemplateProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/LabDeviceTemplateProvider.java
new file mode 100644
index 0000000000..29b6dd3bdc
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/LabDeviceTemplateProvider.java
@@ -0,0 +1,49 @@
+// Copyright 2015 Google Inc. 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.objc;
+
+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.concurrent.ThreadSafety.Immutable;
+
+/**
+ * Provides template which can be run by the test runner script of {@code experimental_ios_test}
+ * targets for lab devices.
+ *
+ * <p> The template contained in a {@code ios_lab_device} target.
+ */
+@Immutable
+public final class LabDeviceTemplateProvider implements TransitiveInfoProvider {
+ private final Artifact template;
+
+ public LabDeviceTemplateProvider(Artifact template) {
+ this.template = Preconditions.checkNotNull(template);
+ }
+
+ /**
+ * Returns the template for lab devices.
+ *
+ * <p>The template contains the following substitution variables:
+ * <ul>
+ * <li> the %launcher and %launcher_arg (whose values must separately be provided through
+ * an {@link IosTestSubstitutionProvider})
+ * <li> %test_app_ipa, %test_app_name, %xctest_app_ipa, %xctest_app_name, %ios_device_arg
+ * (whose values are expected to be provided by the substituting rule)
+ * </ul>
+ */
+ public Artifact getLabDeviceTemplate() {
+ return template;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
index ebc6820a0b..f1774e4bb0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.rules.objc;
+import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -29,10 +30,13 @@ import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction;
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.util.FileType;
import java.util.List;
+import javax.annotation.Nullable;
+
/**
* Support for running XcTests.
*/
@@ -46,7 +50,7 @@ class TestSupport {
/**
* Registers actions to create all files needed in order to actually run the test.
*/
- TestSupport registerTestRunnerActionsForSimulator() {
+ TestSupport registerTestRunnerActions() {
registerTestScriptSubstitutionAction();
return this;
}
@@ -62,14 +66,11 @@ class TestSupport {
// testIpa is the app actually containing the tests
Artifact testIpa = testIpa();
+ // The substitutions below are common for simulator and lab device.
ImmutableList.Builder<Substitution> substitutions = new ImmutableList.Builder<Substitution>()
.add(Substitution.of("%(test_app_ipa)s", testIpa.getRootRelativePathString()))
.add(Substitution.of("%(test_app_name)s", baseNameWithoutIpa(testIpa)))
-
- .add(Substitution.of("%(iossim_path)s", iossim().getRootRelativePath().getPathString()))
- .add(Substitution.of("%(plugin_jars)s", Artifact.joinRootRelativePaths(":", plugins())))
-
- .addAll(deviceSubstitutions().getSubstitutionsForTestRunnerScript());
+ .add(Substitution.of("%(plugin_jars)s", Artifact.joinRootRelativePaths(":", plugins())));
// xctestIpa is the app bundle being tested
Optional<Artifact> xctestIpa = xctestIpa();
@@ -82,17 +83,38 @@ class TestSupport {
.add(Substitution.of("%(xctest_app_ipa)s", ""))
.add(Substitution.of("%(xctest_app_name)s", ""));
}
-
+
+ Artifact template;
+ if (!runWithLabDevice()) {
+ substitutions.addAll(substitutionsForSimulator());
+ template = ruleContext.getPrerequisiteArtifact("$test_template", Mode.TARGET);
+ } else {
+ substitutions.addAll(substitutionsForLabDevice());
+ template = testTemplateForLabDevice();
+ }
+
+ ruleContext.registerAction(new TemplateExpansionAction(ruleContext.getActionOwner(),
+ template, generatedTestScript(), substitutions.build(), /*executable=*/true));
+ }
+
+ private boolean runWithLabDevice() {
+ return iosLabDeviceSubstitutions() != null;
+ }
+
+ /**
+ * Gets the substitutions for simulator.
+ */
+ private ImmutableList<Substitution> substitutionsForSimulator() {
+ ImmutableList.Builder<Substitution> substitutions = new ImmutableList.Builder<Substitution>()
+ .add(Substitution.of("%(iossim_path)s", iossim().getRootRelativePath().getPathString()))
+ .addAll(deviceSubstitutions().getSubstitutionsForTestRunnerScript());
+
Optional<Artifact> testRunner = testRunner();
if (testRunner.isPresent()) {
substitutions.add(
Substitution.of("%(testrunner_binary)s", testRunner.get().getRootRelativePathString()));
}
-
- Artifact template = ruleContext.getPrerequisiteArtifact("$test_template", Mode.TARGET);
-
- ruleContext.registerAction(new TemplateExpansionAction(ruleContext.getActionOwner(),
- template, generatedTestScript(), substitutions.build(), /*executable=*/true));
+ return substitutions.build();
}
private IosTestSubstitutionProvider deviceSubstitutions() {
@@ -133,6 +155,34 @@ class TestSupport {
}
/**
+ * Gets the substitutions for lab device.
+ */
+ private ImmutableList<Substitution> substitutionsForLabDevice() {
+ return new ImmutableList.Builder<Substitution>()
+ .addAll(iosLabDeviceSubstitutions().getSubstitutionsForTestRunnerScript())
+ .add(Substitution.of("%(ios_device_arg)s", Joiner.on(" ").join(iosDeviceArgs()))).build();
+ }
+
+ /**
+ * Gets the test template for lab devices.
+ */
+ private Artifact testTemplateForLabDevice() {
+ return ruleContext
+ .getPrerequisite("ios_test_target_device", Mode.TARGET, LabDeviceTemplateProvider.class)
+ .getLabDeviceTemplate();
+ }
+
+ @Nullable
+ private IosTestSubstitutionProvider iosLabDeviceSubstitutions() {
+ return ruleContext.getPrerequisite(
+ "ios_test_target_device", Mode.TARGET, IosTestSubstitutionProvider.class);
+ }
+
+ private List<String> iosDeviceArgs() {
+ return ruleContext.attributes().get("ios_device_arg", Type.STRING_LIST);
+ }
+
+ /**
* Adds all files needed to run this test to the passed Runfiles builder.
*/
TestSupport addRunfiles(Runfiles.Builder runfilesBuilder) {
@@ -140,10 +190,15 @@ class TestSupport {
.addArtifact(testIpa())
.addArtifacts(xctestIpa().asSet())
.addArtifact(generatedTestScript())
- .addArtifact(iossim())
- .addTransitiveArtifacts(deviceRunfiles())
- .addTransitiveArtifacts(plugins())
- .addArtifacts(testRunner().asSet());
+ .addTransitiveArtifacts(plugins());
+ if (!runWithLabDevice()) {
+ runfilesBuilder
+ .addArtifact(iossim())
+ .addTransitiveArtifacts(deviceRunfiles())
+ .addArtifacts(testRunner().asSet());
+ } else {
+ runfilesBuilder.addTransitiveArtifacts(labDeviceRunfiles());
+ }
return this;
}
@@ -163,6 +218,15 @@ class TestSupport {
}
/**
+ * Runfiles required in order to use the specified target device.
+ */
+ private NestedSet<Artifact> labDeviceRunfiles() {
+ return ruleContext
+ .getPrerequisite("ios_test_target_device", Mode.TARGET, RunfilesProvider.class)
+ .getDefaultRunfiles().getAllArtifacts();
+ }
+
+ /**
* Adds files which must be built in order to run this test to builder.
*/
TestSupport addFilesToBuild(NestedSetBuilder<Artifact> builder) {