Skip to content

Commit

Permalink
Add xctrunner and xctrunnertool
Browse files Browse the repository at this point in the history
  • Loading branch information
kapoorlakshya committed Sep 13, 2024
1 parent 421d428 commit 86139ab
Show file tree
Hide file tree
Showing 18 changed files with 740 additions and 0 deletions.
6 changes: 6 additions & 0 deletions apple/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ bzl_library(
deps = ["//apple/internal:xcarchive"],
)

bzl_library(
name = "xctrunner",
srcs = ["xctrunner.bzl"],
deps = ["//apple/internal:xctrunner"],
)

bzl_library(
name = "docc",
srcs = ["docc.bzl"],
Expand Down
12 changes: 12 additions & 0 deletions apple/internal/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,18 @@ bzl_library(
],
)

bzl_library(
name = "xctrunner",
srcs = ["xctrunner.bzl"],
visibility = [
"//apple:__subpackages__",
],
deps = [
"//apple:providers",
"//apple/internal/providers:apple_debug_info",
],
)

bzl_library(
name = "docc",
srcs = ["docc.bzl"],
Expand Down
98 changes: 98 additions & 0 deletions apple/internal/xctrunner.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"""
Rule for merging multiple test targets into a single XCTRunner.app bundle.
"""

load("@build_bazel_rules_apple//apple:providers.bzl", "AppleBundleInfo")

def _xctrunner_impl(ctx):
# Get test target info
bundle_info = [target[AppleBundleInfo] for target in ctx.attr.test_targets]
xctests = [info.archive for info in bundle_info] # xctest bundles
infoplist = [info.infoplist for info in bundle_info] # Info.plist files
output = ctx.actions.declare_directory(ctx.label.name + ".app")

# Args for _make_xctrunner
arguments = ctx.actions.args()
arguments.add("--name", ctx.label.name)
arguments.add("--platform", ctx.attr.platform)

# absolute paths to xctest bundles
xctest_paths = [xctest.path for xctest in xctests]
arguments.add_all(
xctest_paths,
before_each = "--xctest",
expand_directories = False,
)

# app bundle output path
arguments.add("--output", output.path)

ctx.actions.run(
inputs = depset(xctests + infoplist),
outputs = [output],
executable = ctx.executable._make_xctrunner,
arguments = [arguments],
mnemonic = "MakeXCTRunner",
)

return DefaultInfo(files = depset([output]))

xctrunner = rule(
implementation = _xctrunner_impl,
attrs = {
"test_targets": attr.label_list(
mandatory = True,
providers = [
AppleBundleInfo,
],
doc = "List of test targets to include.",
),
"platform": attr.string(
default = "iPhoneOS.platform",
mandatory = False,
doc = "Platform to bundle for. Default: iPhoneOS.platform",
),
"arch": attr.string(
default = "arm64",
mandatory = False,
doc = "List of architectures to bundle for. Default: arm64",
),
"zip": attr.bool(
default = False,
mandatory = False,
doc = "Whether to zip the resulting bundle.",
),
"_make_xctrunner": attr.label(
default = Label("//tools/xctrunnertool:run"),
executable = True,
cfg = "exec",
doc = "An executable binary that can merge separate xctest into a single XCTestRunner bundle.",
),
},
doc = """\
Packages one or more .xctest bundles into a XCTRunner.app.
Note: Tests inside must be qualified with the test target
name as `testTargetName/testClass/testCase` for device farm builds.
Example:
````starlark
load("//apple:xctrunner.bzl", "xctrunner")
ios_ui_test(
name = "HelloWorldSwiftUITests",
minimum_os_version = "15.0",
runner = "@build_bazel_rules_apple//apple/testing/default_runner:ios_xctestrun_ordered_runner",
test_host = ":HelloWorldSwift",
deps = [":UITests"],
)
xctrunner(
name = "HelloWorldSwiftXCTRunner",
test_targets = [":HelloWorldSwiftUITests"],
testonly = True,
)
````
""",
)
24 changes: 24 additions & 0 deletions apple/xctrunner.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2024 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.

"""
Rule for creating a XCTRunner.app with one or more .xctest bundles.
"""

load(
"@build_bazel_rules_apple//apple/internal:xctrunner.bzl",
_xctrunner = "xctrunner",
)

xctrunner = _xctrunner
1 change: 1 addition & 0 deletions doc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ _RULES_DOC_SRCS = [
"visionos.doc",
"watchos.doc",
"xcarchive",
"xctrunner",
]

_DOC_SRCS = _PLAIN_DOC_SRCS + _RULES_DOC_SRCS
Expand Down
4 changes: 4 additions & 0 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ below.
<td valign="top"><code>@build_bazel_rules_apple//apple:versioning.bzl</code></td>
<td valign="top"><code><a href="rules-versioning.md#apple_bundle_version">apple_bundle_version</a></code><br/></td>
</tr>
<tr>
<td valign="top"><code>@build_bazel_rules_apple//apple:xctrunner.bzl</code></td>
<td valign="top"><code><a href="rules-xctrunner.md#xctrunner">xctrunner</a></code></td>
</tr>
</tr>
<tr>
<th align="left" valign="top" rowspan="1">Resources</th>
Expand Down
49 changes: 49 additions & 0 deletions doc/rules-xctrunner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!-- Generated with Stardoc: http://skydoc.bazel.build -->

Rule for creating a XCTRunner.app with one or more .xctest bundles.

<a id="xctrunner"></a>

## xctrunner

<pre>
xctrunner(<a href="#xctrunner-name">name</a>, <a href="#xctrunner-arch">arch</a>, <a href="#xctrunner-platform">platform</a>, <a href="#xctrunner-test_targets">test_targets</a>, <a href="#xctrunner-zip">zip</a>)
</pre>

Packages one or more .xctest bundles into a XCTRunner.app.

Note: Tests inside must be qualified with the test target
name as `testTargetName/testClass/testCase` for device farm builds.

Example:

````starlark
load("//apple:xctrunner.bzl", "xctrunner")

ios_ui_test(
name = "HelloWorldSwiftUITests",
minimum_os_version = "15.0",
runner = "@build_bazel_rules_apple//apple/testing/default_runner:ios_xctestrun_ordered_runner",
test_host = ":HelloWorldSwift",
deps = [":UITests"],
)

xctrunner(
name = "HelloWorldSwiftXCTRunner",
test_targets = [":HelloWorldSwiftUITests"],
testonly = True,
)
````

**ATTRIBUTES**


| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="xctrunner-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
| <a id="xctrunner-arch"></a>arch | List of architectures to bundle for. Default: arm64 | String | optional | `"arm64"` |
| <a id="xctrunner-platform"></a>platform | Platform to bundle for. Default: iPhoneOS.platform | String | optional | `"iPhoneOS.platform"` |
| <a id="xctrunner-test_targets"></a>test_targets | List of test targets to include. | <a href="https://bazel.build/concepts/labels">List of labels</a> | required | |
| <a id="xctrunner-zip"></a>zip | Whether to zip the resulting bundle. | Boolean | optional | `False` |


7 changes: 7 additions & 0 deletions examples/ios/HelloWorldSwift/BUILD
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
load("@bazel_skylib//rules:build_test.bzl", "build_test")
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
load("//apple:docc.bzl", "docc_archive")
load("//apple:xctrunner.bzl", "xctrunner")
load("//apple:ios.bzl", "ios_application", "ios_ui_test", "ios_unit_test")

licenses(["notice"])
Expand Down Expand Up @@ -103,3 +104,9 @@ docc_archive(
fallback_display_name = "HelloWorldSwift",
minimum_access_level = "internal",
)

xctrunner(
name = "HelloWorldSwiftXCTRunner",
test_targets = [":HelloWorldSwiftUITests"],
testonly = True,
)
148 changes: 148 additions & 0 deletions test/starlark_tests/xctrunner_tests.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Copyright 2024 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.

"""xctrunner Starlark tests."""

load(
"//test/starlark_tests/rules:common_verification_tests.bzl",
"archive_contents_test",
)

def xctrunner_test_suite(name):


def xcarchive_test_suite(name):
"""Test suite for xcarchive rule.
Args:
name: the base name to be used in things created by this macro
"""

# Verify xcarchive bundles required files and app for simulator and device.
archive_contents_test(
name = "{}_contains_xcarchive_files_simulator".format(name),
build_type = "simulator",
target_under_test = "//test/starlark_tests/targets_under_test/ios:app_minimal.xcarchive",
contains = [
"$BUNDLE_ROOT/Info.plist",
"$BUNDLE_ROOT/Products/Applications/app_minimal.app",
],
plist_test_file = "$BUNDLE_ROOT/Info.plist",
plist_test_values = {
"ApplicationProperties:ApplicationPath": "Applications/app_minimal.app",
"ApplicationProperties:ArchiveVersion": "2",
"ApplicationProperties:CFBundleIdentifier": "com.google.example",
"ApplicationProperties:CFBundleShortVersionString": "1.0",
"ApplicationProperties:CFBundleVersion": "1.0",
"Name": "app_minimal",
"SchemeName": "app_minimal",
},
tags = [name],
)
archive_contents_test(
name = "{}_contains_xcarchive_files_simulator_dsyms".format(name),
build_type = "simulator",
target_under_test = "//test/starlark_tests/targets_under_test/ios:app_minimal.xcarchive",
contains = [
"$BUNDLE_ROOT/dSYMs/app_minimal.app.dSYM",
"$BUNDLE_ROOT/dSYMs/app_minimal.app.dSYM/Contents/Resources/DWARF/app_minimal",
"$BUNDLE_ROOT/dSYMs/app_minimal.app.dSYM/Contents/Info.plist",
"$BUNDLE_ROOT/Info.plist",
"$BUNDLE_ROOT/Products/Applications/app_minimal.app",
],
plist_test_file = "$BUNDLE_ROOT/Info.plist",
plist_test_values = {
"ApplicationProperties:ApplicationPath": "Applications/app_minimal.app",
"ApplicationProperties:ArchiveVersion": "2",
"ApplicationProperties:CFBundleIdentifier": "com.google.example",
"ApplicationProperties:CFBundleShortVersionString": "1.0",
"ApplicationProperties:CFBundleVersion": "1.0",
"Name": "app_minimal",
"SchemeName": "app_minimal",
},
apple_generate_dsym = True,
tags = [name],
)
archive_contents_test(
name = "{}_contains_xcarchive_files_simulator_dsyms_extensions".format(name),
build_type = "simulator",
target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_ext_space_in_path.xcarchive",
contains = [
"$BUNDLE_ROOT/dSYMs/app_with_ext_space_in_path.app.dSYM",
"$BUNDLE_ROOT/dSYMs/ext with space.appex.dSYM",
"$BUNDLE_ROOT/dSYMs/ext with space.appex.dSYM/Contents/Resources/DWARF/ext with space",
"$BUNDLE_ROOT/dSYMs/ext with space.appex.dSYM/Contents/Info.plist",
"$BUNDLE_ROOT/Info.plist",
"$BUNDLE_ROOT/Products/Applications/app_with_ext_space_in_path.app",
],
plist_test_file = "$BUNDLE_ROOT/Info.plist",
plist_test_values = {
"ApplicationProperties:ApplicationPath": "Applications/app_with_ext_space_in_path.app",
"ApplicationProperties:ArchiveVersion": "2",
"ApplicationProperties:CFBundleIdentifier": "com.google.example",
"ApplicationProperties:CFBundleShortVersionString": "1.0",
"ApplicationProperties:CFBundleVersion": "1.0",
"Name": "app_with_ext_space_in_path",
"SchemeName": "app_with_ext_space_in_path",
},
apple_generate_dsym = True,
tags = [name],
)
archive_contents_test(
name = "{}_contains_xcarchive_files_simulator_linkmaps".format(name),
build_type = "simulator",
target_under_test = "//test/starlark_tests/targets_under_test/ios:app_minimal.xcarchive",
contains = [
"$BUNDLE_ROOT/Info.plist",
"$BUNDLE_ROOT/Linkmaps/app_minimal_x86_64.linkmap",
"$BUNDLE_ROOT/Products/Applications/app_minimal.app",
],
plist_test_file = "$BUNDLE_ROOT/Info.plist",
plist_test_values = {
"ApplicationProperties:ApplicationPath": "Applications/app_minimal.app",
"ApplicationProperties:ArchiveVersion": "2",
"ApplicationProperties:CFBundleIdentifier": "com.google.example",
"ApplicationProperties:CFBundleShortVersionString": "1.0",
"ApplicationProperties:CFBundleVersion": "1.0",
"Name": "app_minimal",
"SchemeName": "app_minimal",
},
objc_generate_linkmap = True,
tags = [name],
)
archive_contents_test(
name = "{}_contains_xcarchive_files_device".format(name),
build_type = "device",
target_under_test = "//test/starlark_tests/targets_under_test/ios:app_minimal.xcarchive",
contains = [
"$BUNDLE_ROOT/Info.plist",
"$BUNDLE_ROOT/Products/Applications/app_minimal.app",
],
plist_test_file = "$BUNDLE_ROOT/Info.plist",
plist_test_values = {
"ApplicationProperties:ApplicationPath": "Applications/app_minimal.app",
"ApplicationProperties:ArchiveVersion": "2",
"ApplicationProperties:CFBundleIdentifier": "com.google.example",
"ApplicationProperties:CFBundleShortVersionString": "1.0",
"ApplicationProperties:CFBundleVersion": "1.0",
"Name": "app_minimal",
"SchemeName": "app_minimal",
},
tags = [name],
)

native.test_suite(
name = name,
tags = [name],
)
Loading

0 comments on commit 86139ab

Please sign in to comment.