Skip to content

Commit b506b43

Browse files
authored
Expose simulator_creator as public API for improved extensibility (#2881)
Adds a `create_simulator_action` to both iOS test runners, as well as a `clean_up_simulator_action` to `ios_xctestrun_runner`, to provide a way to customize how a simulator is provisioned for a test execution. This should make it easier to support simulator pooling scenarios without requiring users to make changes to test runner internals in a fork.
1 parent 6c04d27 commit b506b43

File tree

8 files changed

+254
-168
lines changed

8 files changed

+254
-168
lines changed

apple/testing/default_runner/BUILD

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
22
load("@rules_python//python:py_binary.bzl", "py_binary")
3+
load("@rules_shell//shell:sh_binary.bzl", "sh_binary")
34
load(
45
"//apple/testing/default_runner:ios_test_runner.bzl",
56
"ios_test_runner",
@@ -101,6 +102,12 @@ py_binary(
101102
visibility = ["//visibility:public"],
102103
)
103104

105+
sh_binary(
106+
name = "simulator_cleanup",
107+
srcs = ["simulator_cleanup.sh"],
108+
visibility = ["//visibility:public"],
109+
)
110+
104111
ios_test_runner(
105112
name = "ios_default_runner",
106113
# Used by the rule implementations, so it needs to be public; but

apple/testing/default_runner/ios_test_runner.bzl

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,22 @@ load(
2222

2323
def _get_template_substitutions(
2424
*,
25+
create_simulator_action_binary,
2526
device_type,
2627
os_version,
27-
simulator_creator,
28-
testrunner,
29-
pre_action_binary,
3028
post_action_binary,
31-
post_action_determines_exit_code):
29+
post_action_determines_exit_code,
30+
pre_action_binary,
31+
testrunner):
3232
"""Returns the template substitutions for this runner."""
3333
subs = {
34+
"create_simulator_action_binary": create_simulator_action_binary,
3435
"device_type": device_type,
3536
"os_version": os_version,
36-
"simulator_creator": simulator_creator,
37-
"testrunner_binary": testrunner,
38-
"pre_action_binary": pre_action_binary,
3937
"post_action_binary": post_action_binary,
4038
"post_action_determines_exit_code": post_action_determines_exit_code,
39+
"pre_action_binary": pre_action_binary,
40+
"testrunner_binary": testrunner,
4141
}
4242
return {"%(" + k + ")s": subs[k] for k in subs}
4343

@@ -56,7 +56,7 @@ def _ios_test_runner_impl(ctx):
5656
os_version = str(ctx.attr.os_version or ctx.fragments.objc.ios_simulator_version or "")
5757
device_type = ctx.attr.device_type or ctx.fragments.objc.ios_simulator_device or ""
5858

59-
runfiles = ctx.attr._simulator_creator[DefaultInfo].default_runfiles
59+
runfiles = ctx.attr.create_simulator_action[DefaultInfo].default_runfiles
6060
runfiles = runfiles.merge(ctx.attr._testrunner[DefaultInfo].default_runfiles)
6161

6262
default_action_binary = "/usr/bin/true"
@@ -78,13 +78,13 @@ def _ios_test_runner_impl(ctx):
7878
template = ctx.file._test_template,
7979
output = ctx.outputs.test_runner_template,
8080
substitutions = _get_template_substitutions(
81+
create_simulator_action_binary = ctx.executable.create_simulator_action.short_path,
8182
device_type = device_type,
8283
os_version = os_version,
83-
simulator_creator = ctx.executable._simulator_creator.short_path,
84-
testrunner = ctx.executable._testrunner.short_path,
85-
pre_action_binary = pre_action_binary,
8684
post_action_binary = post_action_binary,
8785
post_action_determines_exit_code = "true" if post_action_determines_exit_code else "false",
86+
pre_action_binary = pre_action_binary,
87+
testrunner = ctx.executable._testrunner.short_path,
8888
),
8989
)
9090
return [
@@ -106,6 +106,21 @@ def _ios_test_runner_impl(ctx):
106106
ios_test_runner = rule(
107107
_ios_test_runner_impl,
108108
attrs = {
109+
"create_simulator_action": attr.label(
110+
cfg = "exec",
111+
executable = True,
112+
default = Label("//apple/testing/default_runner:simulator_creator"),
113+
doc = """
114+
A binary that produces a UDID for a simulator that matches the given device type and OS version. The UDID will be used to run the tests on the correct simulator. The binary must print only the UDID to stdout. This is only invoked when the `$REUSE_GLOBAL_SIMULATOR` environment variable is set.
115+
116+
When executed, the binary will have the following environment variables available to it:
117+
118+
<ul>
119+
<li>`SIMULATOR_DEVICE_TYPE`: The device type of the simulator to create. The supported types correspond to the output of `xcrun simctl list devicetypes`. E.g., iPhone 6, iPad Air. The value will either be the value of the `device_type` attribute, the `--ios_simulator_device` command-line flag, or an empty string that should imply a default device.</li>
120+
<li>`SIMULATOR_OS_VERSION`: The os version of the simulator to create. The supported os versions correspond to the output of `xcrun simctl list runtimes`. ' 'E.g., 11.2, 9.3. The value will either be the value of the `os_version` attribute, the `--ios_simulator_version` command-line flag, or an empty string that should imply a default OS version for the selected simulator runtime.</li>
121+
</ul>
122+
""",
123+
),
109124
"device_type": attr.string(
110125
default = "",
111126
doc = """
@@ -130,56 +145,45 @@ correspond to the output of `xcrun simctl list runtimes`. ' 'E.g., 11.2, 9.3.
130145
By default, it is the latest supported version of the device type.'
131146
""",
132147
),
133-
"test_environment": attr.string_dict(
148+
"post_action": attr.label(
149+
cfg = "exec",
150+
executable = True,
134151
doc = """
135-
Optional dictionary with the environment variables that are to be propagated
136-
into the XCTest invocation.
152+
A binary to run following test execution. Runs after testing but before test result handling and coverage processing. Sets the `$TEST_EXIT_CODE` environment variable, in addition to any other variables available to the test runner.
137153
""",
138154
),
139-
"pre_action": attr.label(
140-
executable = True,
141-
cfg = "exec",
155+
"post_action_determines_exit_code": attr.bool(
156+
default = False,
142157
doc = """
143-
A binary to run prior to test execution. Runs after simulator creation. Sets any environment variables available to the test runner.
158+
When true, the exit code of the test run will be set to the exit code of the `post_action`. This is useful for tests that need to fail the test run based on their own criteria.
144159
""",
145160
),
146-
"post_action": attr.label(
147-
executable = True,
161+
"pre_action": attr.label(
148162
cfg = "exec",
163+
executable = True,
149164
doc = """
150-
A binary to run following test execution. Runs after testing but before test result handling and coverage processing. Sets the `$TEST_EXIT_CODE` environment variable, in addition to any other variables available to the test runner.
165+
A binary to run prior to test execution. Runs after simulator creation. Sets any environment variables available to the test runner.
151166
""",
152167
),
153-
"post_action_determines_exit_code": attr.bool(
154-
default = False,
168+
"test_environment": attr.string_dict(
155169
doc = """
156-
When true, the exit code of the test run will be set to the exit code of the post action. This is useful for tests that need to fail the test run based on their own criteria.
170+
Optional dictionary with the environment variables that are to be propagated
171+
into the XCTest invocation.
157172
""",
158173
),
159174
"_test_template": attr.label(
160-
default = Label(
161-
"//apple/testing/default_runner:ios_test_runner.template.sh",
162-
),
175+
default = Label("//apple/testing/default_runner:ios_test_runner.template.sh"),
163176
allow_single_file = True,
164177
),
165178
"_testrunner": attr.label(
166-
default = Label(
167-
"@xctestrunner//:ios_test_runner",
168-
),
169-
executable = True,
170179
cfg = "exec",
180+
executable = True,
181+
default = Label("@xctestrunner//:ios_test_runner"),
171182
doc = """
172183
It is the rule that needs to provide the AppleTestRunnerInfo provider. This
173184
dependency is the test runner binary.
174185
""",
175186
),
176-
"_simulator_creator": attr.label(
177-
default = Label(
178-
"//apple/testing/default_runner:simulator_creator",
179-
),
180-
executable = True,
181-
cfg = "exec",
182-
),
183187
"_xcode_config": attr.label(
184188
default = configuration_field(
185189
fragment = "apple",

apple/testing/default_runner/ios_test_runner.template.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ if [[ -n "${REUSE_GLOBAL_SIMULATOR:-}" ]]; then
253253
exit 1
254254
fi
255255

256-
id="$("./%(simulator_creator)s" "%(os_version)s" "%(device_type)s")"
256+
id="$(SIMULATOR_DEVICE_TYPE="%(device_type)s" SIMULATOR_OS_VERSION="%(os_version)s" "%(create_simulator_action_binary)s")"
257257
target_flags=(
258258
"test"
259259
"--platform=ios_simulator"

0 commit comments

Comments
 (0)