bitrise-steplib / steps-xcode-test

Xcode Test step
https://www.bitrise.io/cli
MIT License
33 stars 37 forks source link

Xcode 14.3 run in rosetta simulator. Arch in destination gets ignored. #226

Open KunzManuel opened 1 year ago

KunzManuel commented 1 year ago

Troubleshooting

Useful information

Issue description

On migrating a project to the M1 setup our team ran into a problem with building our tests with the Xcode Test for iOS step. Running with Xcode 14.3 and the M1 large we got the error: could not find module 'Example' for target 'x86_64-apple-ios-simulator'; found: arm64-apple-ios-simulator

This problem seems to come with Xcode 14.3 which no longer runs in rosetta mode. Release notes

But Xcode 14.3 still allows to run a simulator in rosetta mode. To enable this the destination has to be extended by the arch param. -destination "platform=iOS Simulator,name=iPhone 14,arch=x86_64"

By having a quick look into the code you can see that this arch param is currently ignored. The destination is parsed and the identifier of the simulator is appended to the xcodebuild command.

godrei commented 1 year ago

Hi @KunzManuel , thanks for the detailed issue report!

I couldn't reproduce the issue with my sample projects. Do you have an example project, which I could use for reproducing the issue and to verify the suggested approach?

Is the module mentioned in the error a swift package dependency? I came across this writing: Some pits of using SPM and Build Configuration in Xcode, which suggests updating build settings for resolving a similar problem.

KunzManuel commented 1 year ago

Hello,

unfortunately I can not share the project. Yes the module mention is a Swift Package. In the main project the build settings are set to exclude the arm64 arch due to a framework in use which does not support arm64 simulators yet. So right now before we can get rid of the framework, or support is added, we have to run the tests in rosetta mode. Our current hotfix is to use a custom Script step and run: xcrun xcodebuild test -workspace example.xcworkspace -scheme Example -destination "platform=iOS Simulator,name=iPhone 14 #Pro,arch=x86_64"

godrei commented 1 year ago

@KunzManuel have you tried Apple's Resolving architecture build errors on Apple silicon guide?

KunzManuel commented 1 year ago

@godrei Yes unfortunately non of it worked for me.

alessandrodn commented 1 year ago

I'm also struggling to get our project run UT on the x86_64 simulator as well. I can confirm the same behavior; I was able to bypass the error by explicitly excluding the arm64 architecture in the Additional options for the xcodebuild command. This should fix your error; though my build still doesn't pass 😞

Screenshot 2023-06-11 at 9 50 31
StrAbZ commented 1 year ago

Hi!

I have the exact same issue.

My project already have the arm64 as excluded arch as explained by Apple in Resolving architecture build errors on Apple silicon guide.

However this means we need to run Rosetta Simulators for Xcode 14.3, which normally should be done by adding the arch=x86_64 to the destination. But it looks like this is not passed to the Xcode build command.

robinkunde commented 1 year ago

I'm also dealing with this issue and my Bitrise project has now been marked "abandoned" because I cannot get it to build on CI. I skimmed over the code, and it looks like what this step does is use the destination identifier to retrieve the UUID of the simulator. That works but discards the arch info which is how Apple expects you to target Rosetta simulator destinations from the command line. The EXCLUDED_ARCH solution that is suggested in Bitrise's docs may work for some apps, but it's extremely cumbersome and I have personally not been able to make it work. Allowing the arch parameter would make things much easier.

That said, I think the arch parameter may not work before Xcode 14.3 or 14.2.

lpusok commented 1 year ago

Suggestion released in https://github.com/bitrise-steplib/steps-xcode-test/releases/tag/4.7.3. However Xcode's destination selector is very buggy if when using arch flag, it disregards any device name and OS version. It seems to select a destination with runtime OS 13.7 or 14.5, these can only be run under Rosetta. So manually selecting a device under these runtimes would be a workaround also.

robinkunde commented 1 year ago

4.7.3 solved my problem. Thanks

lpusok commented 1 year ago

@robinkunde @StrAbZ @KunzManuel

In addition of passing the arch flag through found a better way to override Xcode Simulator selector buginess using the start-xcode-simulator Step:

- xcode-start-simulator:
    inputs:
    - destination: platform=iOS Simulator,name=Bitrise iOS default,OS=latest,arch=x86_64 #Additional arch flag added here
- xcode-test:
    inputs:
    - destination: $BITRISE_XCODE_DESTINATION # Use the same destination as the xcode-start-simulator Step
    - project_path: ./ios-sample/ios-sample.xcodeproj
    - scheme: ios-sample
    # Disabling parallel testing ensures that prebooted device is used. ARCHS=x86_64 is optional, to enable project compilation
    - xcodebuild_options: -verbose -parallel-testing-enabled NO  ARCHS=x86_64
    - collect_simulator_diagnostics: never # This is the default
sleivysarnas commented 1 year ago

We are still having issues even after 4.7.4 update and @lpusok suggested changes (to start simulator before test step). Locally and on local Bitrise CLI build everything works as expected, but when running through Bitrise (non-local) we are experiencing this error:

Failed to install or launch the test runner. (Underlying Error: Process spawn via launchd failed. Bad file descriptor. (Underlying Error: The operation couldn’t be completed. (Mach error 9 - (os/kern) memory failure)))

lpusok commented 1 year ago

@sleivysarnas What happens if you set the destination directly in the xcode-test Step (- destination: platform=iOS Simulator,name=Bitrise iOS default,OS=latest,arch=x86_64), not using the start-simulator one?

sleivysarnas commented 1 year ago

@lpusok exactly the same error

daliad007 commented 1 year ago

@sleivysarnas What happens if you set the destination directly in the xcode-test Step (- destination: platform=iOS Simulator,name=Bitrise iOS default,OS=latest,arch=x86_64), not using the start-simulator one?

Hello, we had the same issue and this fixed it for us. We also updated to the latest version at this point (5.0.1) thank you!

kkizlaitis commented 1 year ago

@lpusok, I'm getting the same error no matter how I'm launching the x86_64 simulator. Doesn't matter if I use Start Simulator step, or put arch=x86_64 in the Xcode Test step directly.

I've logged into Bitrise with remote access (no build step, just with steps containing project setup and a script with sleep so that I would have enough time to try stuff) and tried running the tests via Screen Sharing.

Firstly, I tried opening up Xcode, selecting any Rosetta-enabled iOS simulator and then tried running the tests (from Xcode's interface). The Rosetta simulator launched successfully and the tests succeeded successfully.

I then tried to retest everything with CLI.

I tried using command:

xcodebuild "-workspace" "/Users/vagrant/git/<redacted>.xcworkspace" "-scheme" "<redacted>" "test" -destination "platform=iOS Simulator,name=iPad (10th generation),arch=x86_64"

but the test failed due to Process spawn via launchd failed. It doesn't matter actually what name I give to the destination because xcodebuild doesn't care about it.

In another attempt, I checked which simulators were running using xcrun simctl list. There was only one simulator (the one that Xcode launched when tests were run). I figure it still is a Rosetta simulator.

I extracted its id and tried to run the xcodebuild directly on this Rosetta-enabled device (while still specifying x86_64 architecture for xcodebuild):

xcodebuild "-workspace" "/Users/vagrant/git/<redacted>.xcworkspace" "-scheme" "<redacted>" "test" -destination "id=B386AAB3-B36E-4E19-B0F3-15F99DDE1DB5" "ARCHS=x86_64"

The build still failed in a similar manner, however, when analysing the logs, I've encountered that immediately after the start of the process, xcodebuild printed these lines:

--- xcodebuild: WARNING: Using the first of multiple matching destinations:
{ platform:iOS Simulator, id:B386AAB3-B36E-4E19-B0F3-15F99DDE1DB5, OS:16.4, name:iPad (10th generation) }
{ platform:iOS Simulator, id:B386AAB3-B36E-4E19-B0F3-15F99DDE1DB5, OS:16.4, name:iPad (10th generation) }

How can it be that there are now multiple instances of the same simulator? Could it be that one of them is Rosetta enabled and the other one is standard? I assume that the first destination is the standard one, because if it was Rosetta simulator, the tests would have succeeded?

For the record, we are using "Xcode 14.3.x, on macOS 13.2 (Ventura)" stack and "Xcode Test for iOS" of version 5.0.1 (although it should not matter because I was logged in directly to Bitrise and ran the commands myself).

Please help us, because we haven't been able to run any tests after Bitrise switched to M1 😕

hanishassim commented 1 year ago

I am having the same issue with unit tests failing after move to M1. This is due to the workflow is using a pre-warmed device, which means it's not using the specified simulator we defined. If you take a look here

The Device destination specifier (destination) Input now uses the device called Bitrise iOS default by default. Where already created, this device is:

iPhone 8 with iOS Simulator runtime 16 and earlier (Xcode 14 and earlier) iPhone 11 with iOS Simulator runtime 17.0 and later (shipped in Xcode 15 beta) If a device with this name is not found (e.g. in a local dev environment), the first matching (platform and OS specifiers are considered) device will be selected.

I reached out to their support team, and they suggested to raise our project's minimum deployment target instead, which is not acceptable! We are the customers and they should cater us not the other way around.

I am so disappointed with the response they provided.

kkizlaitis commented 1 year ago

For the record, when we updated to "Xcode 15.0.x" stack, the issue was resolved.

hanishassim commented 8 months ago

you're right @kkizlaitis I am able to get successful test execution using Xcode 15.2 stack.

Screenshot 2024-03-21 at 11 01 08 AM
kkizlaitis commented 3 weeks ago

The issue reappeared on Stack Xcode 16.1.x 😞

This worked previously:

destination: platform=iOS Simulator,name=Bitrise iOS default,OS=latest,arch=x86_64

But now, it's throwing this error:

❌ xcodebuild: error: Unable to find a device matching the provided destination specifier:
Exit code:  -1
Last lines of the build log:
        { platform:iOS Simulator, id:C1E4F34C-82B0-4804-970D-7EC652ED683A, OS:18.0, name:iPhone 16 Plus }
        { platform:iOS Simulator, id:C1E4F34C-82B0-4804-970D-7EC652ED683A, OS:18.0, name:iPhone 16 Plus }
        { platform:iOS Simulator, id:72AE2054-4A91-4041-8789-D1BC7B1F8B32, OS:18.1, name:iPhone 16 Plus }
        { platform:iOS Simulator, id:72AE2054-4A91-4041-8789-D1BC7B1F8B32, OS:18.1, name:iPhone 16 Plus }
        { platform:iOS Simulator, id:4B4AF5DA-55D2-48A7-B35E-C2330C89FF9A, OS:18.0, name:iPhone 16 Pro }
        { platform:iOS Simulator, id:4B4AF5DA-55D2-48A7-B35E-C2330C89FF9A, OS:18.0, name:iPhone 16 Pro }
        { platform:iOS Simulator, id:4BFA2282-04B8-4196-A479-6434F9804747, OS:18.1, name:iPhone 16 Pro }
        { platform:iOS Simulator, id:4BFA2282-04B8-4196-A479-6434F9804747, OS:18.1, name:iPhone 16 Pro }
        { platform:iOS Simulator, id:B9401E9E-0F88-488E-BF8D-B097B04888A9, OS:18.0, name:iPhone 16 Pro Max }
        { platform:iOS Simulator, id:B9401E9E-0F88-488E-BF8D-B097B04888A9, OS:18.0, name:iPhone 16 Pro Max }
        { platform:iOS Simulator, id:F30C0F6E-7075-48C8-91CF-1B7406529E1D, OS:18.1, name:iPhone 16 Pro Max }
        { platform:iOS Simulator, id:F30C0F6E-7075-48C8-91CF-1B7406529E1D, OS:18.1, name:iPhone 16 Pro Max }
        { platform:iOS Simulator, id:2AED54EE-B159-41DD-924E-FCAE48F4087A, OS:16.4, name:iPhone SE (3rd generation) }
        { platform:iOS Simulator, id:2AED54EE-B159-41DD-924E-FCAE48F4087A, OS:16.4, name:iPhone SE (3rd generation) }
        { platform:iOS Simulator, id:D270A8EC-BFF6-4D13-B87E-8830DF4B2E7C, OS:17.5, name:iPhone SE (3rd generation) }
        { platform:iOS Simulator, id:D270A8EC-BFF6-4D13-B87E-8830DF4B2E7C, OS:17.5, name:iPhone SE (3rd generation) }
        { platform:iOS Simulator, id:B880E11F-8AC6-4F07-81B2-514A8FFCD1EE, OS:18.0, name:iPhone SE (3rd generation) }
        { platform:iOS Simulator, id:B880E11F-8AC6-4F07-81B2-514A8FFCD1EE, OS:18.0, name:iPhone SE (3rd generation) }
        { platform:iOS Simulator, id:E9B79867-AB8C-4FE0-BC50-5206367C2D51, OS:18.1, name:iPhone SE (3rd generation) }
        { platform:iOS Simulator, id:E9B79867-AB8C-4FE0-BC50-5206367C2D51, OS:18.1, name:iPhone SE (3rd generation) }