From 99088ab081279329b8362e1c24533fa0be303e6f Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Tue, 25 Feb 2025 14:49:05 +0800 Subject: gh-130292: Allow for empty simulator list when running iOS testbed (#130388) Adds error handling when there are no pre-existing test simulators. --- .../2025-02-20-13-50-07.gh-issue-130292.RvK2Ou.rst | 2 ++ iOS/testbed/__main__.py | 36 ++++++++++++++-------- 2 files changed, 25 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2025-02-20-13-50-07.gh-issue-130292.RvK2Ou.rst diff --git a/Misc/NEWS.d/next/Tests/2025-02-20-13-50-07.gh-issue-130292.RvK2Ou.rst b/Misc/NEWS.d/next/Tests/2025-02-20-13-50-07.gh-issue-130292.RvK2Ou.rst new file mode 100644 index 0000000..0805058 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2025-02-20-13-50-07.gh-issue-130292.RvK2Ou.rst @@ -0,0 +1,2 @@ +The iOS testbed will now run successfully on a machine that has not +previously run Xcode tests (such as CI configurations). diff --git a/iOS/testbed/__main__.py b/iOS/testbed/__main__.py index 08fbe90..d12a5ab 100644 --- a/iOS/testbed/__main__.py +++ b/iOS/testbed/__main__.py @@ -82,19 +82,29 @@ async def async_check_output(*args, **kwargs): # Return a list of UDIDs associated with booted simulators async def list_devices(): - # List the testing simulators, in JSON format - raw_json = await async_check_output( - "xcrun", "simctl", "--set", "testing", "list", "-j" - ) - json_data = json.loads(raw_json) - - # Filter out the booted iOS simulators - return [ - simulator["udid"] - for runtime, simulators in json_data["devices"].items() - for simulator in simulators - if runtime.split(".")[-1].startswith("iOS") and simulator["state"] == "Booted" - ] + try: + # List the testing simulators, in JSON format + raw_json = await async_check_output( + "xcrun", "simctl", "--set", "testing", "list", "-j" + ) + json_data = json.loads(raw_json) + + # Filter out the booted iOS simulators + return [ + simulator["udid"] + for runtime, simulators in json_data["devices"].items() + for simulator in simulators + if runtime.split(".")[-1].startswith("iOS") and simulator["state"] == "Booted" + ] + except subprocess.CalledProcessError as e: + # If there's no ~/Library/Developer/XCTestDevices folder (which is the + # case on fresh installs, and in some CI environments), `simctl list` + # returns error code 1, rather than an empty list. Handle that case, + # but raise all other errors. + if e.returncode == 1: + return [] + else: + raise async def find_device(initial_devices): -- cgit v0.12