Skip to content

Support running x86_64 logic tests on Apple silicon#40

Closed
bogo wants to merge 3 commits intogoogle:masterfrom
bogo:bogo/xctest-m1
Closed

Support running x86_64 logic tests on Apple silicon#40
bogo wants to merge 3 commits intogoogle:masterfrom
bogo:bogo/xctest-m1

Conversation

@bogo
Copy link
Copy Markdown
Contributor

@bogo bogo commented Nov 7, 2021

This PR adds support for running x86_64 logic tests on Apple silicon by following the patterns introduced in 7f8fc8. This is most helpful in the current Bazel/rules_apple context, where the only Simulator binaries produced are x86. This approach to running logic tests on Apple silicon is discussed in MobileNativeFoundation/discussions#141.

Since xctest is stripped down to x86 only if the x86 slice is present, this should not affect existing Intel Macs, and should be automatically skipped once rules_apple and Bazel correctly support Apple silicon Simulator.

test_archs = bundle_util.GetFileArchTypes(test_executable)

# if a logic bundle is built w/ x86 on Apple silicon, it won't be able to launch on the ARM64 sim; rework the xctest to fix this
if ios_constants.ARCH.X86_64 in test_archs:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be an exclusive check? Because you could be testing a fat binary in which case you still wouldn't want to do this I think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. Do you think parametrizing the test runner with something like --force-run-x86 would be sufficient here? Then it could be passed as a test parameter from Bazel invocation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like host arch == arm64 && test_archs == x86_64 && no test host is a find conditional for now to make things "just work" for folks, but up to the google folks

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keith, why testing with a fat binary is not expected? I don't have a local M1 machine to test it out. My understanding is the current implementation can work for both x86_64 only test bundle and fat test bundle.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you have a fat binary, this conditional will be true, but you should probably not do this and test the native arm64 slice instead if you have it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense.

Bogo, could you help change the condition to be ios_constants.ARCH.X86_64 in test_archs and len(test_archs) == 1? Doing the host arch check seems not necessary. No matter if the host is M1 or intel, we can use x86_64 only xctest tool to execute x86_64 test bundle.

I will also need to change

bundle_util.RemoveArchType(uitest_runner_exec, ios_constants.ARCH.ARM64)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my conditional mentioned above also makes sure this wouldn't happen in cases where it's unnecessary, but it's not required

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@keith I thought about testing the host architecture, but figured it might be better to have the code paths as close as possible on Apple silicon and x86. Can add the necessary helpers if you feel it'd be worth it though.

@ivan-golub
Copy link
Copy Markdown

Hey @bogo! This PR seems to be stale for quite some time. Is it abandoned? Do you need any help to finalize it? My team would like to be able to run x86 sim tests via bazel which mean we need to teach xctestrunner first

@thii
Copy link
Copy Markdown
Contributor

thii commented Feb 3, 2022

@albertdai Can you take a look at this too?

xctest_tool = shutil.copy(
xcode_info_util.GetXctestToolPath(ios_constants.SDK.IPHONESIMULATOR),
os.path.join(tempfile.mkdtemp(), "xctest")
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can change LeaveOnlyArchType to LeaveOnlyArchType(input_file_path, output_file_path, arch_type). So we don't need to do this copy

@bogo
Copy link
Copy Markdown
Contributor Author

bogo commented Feb 8, 2022

Thanks for the help, @keith and @albertdai! Applied the changes you suggested.

@thii
Copy link
Copy Markdown
Contributor

thii commented Mar 15, 2022

Seems like this patch needs tweaks for Xcode 13.3. Getting the following error when using it with Xcode 13.3:

2022-03-16 06:03:33.959 xctest[76139:18007203] The bundle “ATest.xctest” couldn’t be loaded. Try reinstalling the bundle.
2022-03-16 06:03:33.962 xctest[76139:18007203] (dlopen(/tmp/test_runner_work_dir.fetEaf/ATest/ATest.xctest/ATest, 0x0109): Library not loaded: @rpath/libXCTestSwiftSupport.dylib
  Referenced from: /private/tmp/test_runner_work_dir.fetEaf/ATest/ATest.xctest/ATest

  Reason: tried: '/Applications/Xcode-13.3.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/swift/libXCTestSwiftSupport.dylib' (no such file), '/usr/lib/swift/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/tmp3710xrhn/Frameworks/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/test_runner_work_dir.fetEaf/ATest/ATest.xctest/Frameworks/libXCTestSwiftSupport.dylib' (no such file), '/Applications/Xcode-13.3.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/swift/libXCTestSwiftSupport.dylib' (no such file), '/usr/lib/swift/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/tmp3710xrhn/Frameworks/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/test_runner_work_dir.fetEaf/ATest/ATest.xctest/Frameworks/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/tmp3710xrhn/../../Frameworks/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/tmp3710xrhn/../../PrivateFrameworks/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/tmp3710xrhn/../../../usr/lib/libXCTestSwiftSupport.dylib' (no such file))

@ivan-golub
Copy link
Copy Markdown

Hey @bogo @keith @albertdai ! We have been using custom xctestrunner from this commit with great success but would love to get this in main branch to get other fixes like #41 in too. Do you need any help with this PR to move it forward? Also looks like @thii caught some issues on 13.3 which means some more adjustments are needed

@keith
Copy link
Copy Markdown
Contributor

keith commented Mar 16, 2022

Seems like we'd need to fix the new issues before doing anything, but note that on this repo @albertdai is the decider on this stuff as the only person with commit access

@albertdai
Copy link
Copy Markdown
Contributor

Seems like this patch needs tweaks for Xcode 13.3. Getting the following error when using it with Xcode 13.3:

2022-03-16 06:03:33.959 xctest[76139:18007203] The bundle “ATest.xctest” couldn’t be loaded. Try reinstalling the bundle.
2022-03-16 06:03:33.962 xctest[76139:18007203] (dlopen(/tmp/test_runner_work_dir.fetEaf/ATest/ATest.xctest/ATest, 0x0109): Library not loaded: @rpath/libXCTestSwiftSupport.dylib
  Referenced from: /private/tmp/test_runner_work_dir.fetEaf/ATest/ATest.xctest/ATest

  Reason: tried: '/Applications/Xcode-13.3.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/swift/libXCTestSwiftSupport.dylib' (no such file), '/usr/lib/swift/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/tmp3710xrhn/Frameworks/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/test_runner_work_dir.fetEaf/ATest/ATest.xctest/Frameworks/libXCTestSwiftSupport.dylib' (no such file), '/Applications/Xcode-13.3.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/swift/libXCTestSwiftSupport.dylib' (no such file), '/usr/lib/swift/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/tmp3710xrhn/Frameworks/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/test_runner_work_dir.fetEaf/ATest/ATest.xctest/Frameworks/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/tmp3710xrhn/../../Frameworks/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/tmp3710xrhn/../../PrivateFrameworks/libXCTestSwiftSupport.dylib' (no such file), '/private/tmp/tmp3710xrhn/../../../usr/lib/libXCTestSwiftSupport.dylib' (no such file))

I don't have a local Apple silicon machine to test out this issue on Xcode 13.3. @bogo Could you help double check with that from your side?

@albertdai
Copy link
Copy Markdown
Contributor

I tested out locally with my intel macbook pro and confirmed the test runner with the commits can not work with Swift logic test on Xcode 13.3.

So we need to fix the issues before merging the commits into master.

@ivan-golub
Copy link
Copy Markdown

@bogo do you need help with this PR? This is really valuable change

@bogo
Copy link
Copy Markdown
Contributor Author

bogo commented Apr 18, 2022

@ivan-golub @albertdai will take a look at whether I can make it work again either later this week or early next week!

@albertdai
Copy link
Copy Markdown
Contributor

Thanks Bogo.

I feel the xctest tool may have some dependencies with relative path under the new Xcode version. You can consider creating the temp xctest tool under the same directory of xctest. I have not tested it out yet.

@ivan-golub
Copy link
Copy Markdown

ivan-golub commented Apr 22, 2022

FYI: failure for swift logic tests seem to be present only for iOS 15.4 simulator, ie this will fail

ios_test_runner(
    name = "iphone_test_runner",
    device_type = "iPhone 8",
    os_version = "15.4",
    visibility = ["//visibility:public"],
)

but this will not

ios_test_runner(
    name = "iphone_test_runner",
    device_type = "iPhone 8",
    os_version = "15.2", # or 15.0
    visibility = ["//visibility:public"],
)


# if a logic bundle is built w/ x86 on Apple silicon, it won't be able to launch on the ARM64 sim; rework the xctest to fix this
if ios_constants.ARCH.X86_64 in test_archs and len(test_archs) == 1:
replacement_xctest_tool = os.path.join(tempfile.mkdtemp(), "xctest")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
replacement_xctest_tool = os.path.join(tempfile.mkdtemp(), "xctest")
replacement_xctest_tool = os.path.join(os.path.dirname(xctest_tool), "xctest_x86_64")

this fixes swift logic test issue with xcode 13.3 and ios 15.4 as @albertdai suspected here #40 (comment)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could fail depending on how the user installed xcode, as it won't have permissions in some cases

@keith
Copy link
Copy Markdown
Contributor

keith commented May 17, 2022

FYI this broke with Xcode 13.4.0, the issue appears to be a change in iOS, I'm debugging a bit

)
xctest_tool = replacement_xctest_tool
platform_developer_dir = os.path.join(xcode_info_util.GetSdkPlatformPath(ios_constants.SDK.IPHONESIMULATOR), "Developer")
simctl_env_vars[_SIMCTL_ENV_VAR_PREFIX + "DYLD_FALLBACK_LIBRARY_PATH"] = "{0}/usr/lib".format(platform_developer_dir)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
simctl_env_vars[_SIMCTL_ENV_VAR_PREFIX + "DYLD_FALLBACK_LIBRARY_PATH"] = "{0}/usr/lib".format(platform_developer_dir)
simctl_env_vars[_SIMCTL_ENV_VAR_PREFIX + "DYLD_LIBRARY_PATH"] = "{0}/usr/lib".format(platform_developer_dir)

this fixes Xcode 13.4 support, and still works for earlier versions. I'm not sure why yet but something about the semantics of this changed.

@bogo bogo closed this Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants