Skip to content

[android] Run tests for libdispatch in x64 emulator (wip) #78762

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

weliveindetail
Copy link
Member

Early preview for a ctest-based library that raises some questions:

  • If we need additional scripts, where should we put them? For example ctest_mock.sh (we might be able to avoid this one).
  • On my local machine I have to grant adb network access once. How to do that in CI?
  • How to track the emulator process and make sure: (1) it booted, (2) it shut down

@andrurogerz
Copy link
Contributor

Is the goal to make it easy to run these tests locally or to run them as part of CI? I think this change makes sense for local testing, but for CI we tend to put the bulk of the logic into a GitHub workflow. This way, you can leverage many well-tested, supported GitHub actions like nttld/setup-ndk and reactivecircus/android-emulator-runner to install NDK and run tests on Android emulators.

The ds2 github workflow is an example for running non-Swift tests on an Android emulator: https://github.com/compnerd/ds2/blob/main/.github/workflows/build.yml#L460

@weliveindetail
Copy link
Member Author

Thanks for the feedback and links @andrurogerz. I am sure a GitHub workflow would be a good solution, but I think we want to run this in Swift CI. Thus, we need to implement it in the build script.

@weliveindetail
Copy link
Member Author

If we need additional scripts, where should we put them?

libc++ has utils/ci for such scripts in upstream LLVM: https://github.com/llvm/llvm-project/tree/main/libcxx/utils/ci/vendor/android

How to track the emulator process and make sure: (1) it booted, (2) it shut down

We likely find an answer in the above scripts

On my local machine I have to grant adb network access once. How to do that in CI?

For the moment this question remains as it's Windows-specific. We will see with trial and error.

@weliveindetail
Copy link
Member Author

We should consider to cross-compile ctest for the targets we need and use it as a test driver instead of the script

@finagolfin
Copy link
Member

Interesting, I wanted to test this in the emulator once Android is added to the official CI, so we can probably reuse this script on a linux host then. You're probably aware that the compiler validation suite currently supports running its executable tests in the emulator through adb. You obviously don't use build-script on Windows, but maybe you can just use that through a Python script or it may simply give you ideas. I can't answer any of your questions about running the emulator on Windows, because I don't use Windows, but Andrew is right that you're better off using the existing github actions for that, if those are available in your Windows CI.

@weliveindetail
Copy link
Member Author

Thanks for your notes @finagolfin!

This is meant as a first test balloon to run something in the emulator at all in the Swift CI for Windows. I considered LIT-based tests more complicated and wanted to try something simple first. Happy to collaborate if there is overlap with Linux!

You're probably aware that the compiler validation suite currently supports running its executable tests in the emulator through adb.

Yes, I literally found them 2 days ago :) That will help a lot with tests for Swift itself and out-of-tree libs like xctest!

Andrew is right that you're better off using the existing github actions for that, if those are available in your Windows CI

I don't see how we would run these on ci.swift.org, is that possible?

@weliveindetail
Copy link
Member Author

@swift-ci Please test Windows

@weliveindetail weliveindetail force-pushed the android-ctest-libdispatch branch 3 times, most recently from 1b32852 to e01333a Compare January 22, 2025 12:39
@weliveindetail
Copy link
Member Author

Pushed a number of fixes and try to save some CI resources temporarily (only build Windows x64 + Android x86_64, only test dispatch).

@swift-ci Please test Windows

@finagolfin
Copy link
Member

I don't see how we would run these on ci.swift.org, is that possible?

I don't know how the official Windows CI works. If it doesn't allow running github action workflows, then no, it's not possible.

I think Andrew's point is that you'd be better off running these tests in your existing github-based CI first, before proposing them for non-github-based CI that requires more configuration work.

@weliveindetail
Copy link
Member Author

In order to test Android in Swift CI, we need the emulator and adb from Android cmdline-tools. We can download and install them pretty quickly.

However, my above attempt failed, because the machine's Java Runtime version is outdated (55 is from 2018). @shahmishal Is there a chance that the build machines get an update? (61 is from 2021)

T:\android-cmdline-tools.zip not found. Downloading ...
Extracting 'android-cmdline-tools.zip' ...
Error: LinkageError occurred while loading main class com.android.sdklib.tool.sdkmanager.SdkManagerCli
	java.lang.UnsupportedClassVersionError: com/android/sdklib/tool/sdkmanager/SdkManagerCli has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0
Error: Error: sdkmanager.bat exited with code 1.
Invocation:
  T:\android-ndk-r26b\.temp\cmdline-tools\bin\sdkmanager.bat --sdk_root=T:\android-ndk-r26b cmdline-tools;latest --channel=3

@finagolfin
Copy link
Member

If you TBC devs don't control the Windows environment in that CI, it may be using one of the Windows Docker files, in which case you can submit a Java update change there yourself, @weliveindetail.

@weliveindetail
Copy link
Member Author

Thanks @finagolfin! Yes, I'd like to consider that once I double-checked it's the right image source.

@weliveindetail
Copy link
Member Author

Unfortunately, the Windows builders haven't been ported to docker. In order to unblock progress we're installing Java on the fly now. This is a terrible workaround though. It's a waste of time and resources.

@weliveindetail
Copy link
Member Author

@swift-ci Please test Windows

@weliveindetail
Copy link
Member Author

The installation failed with:

T:\android-ndk-r26b-windows.zip not found. Downloading ...
Extracting 'android-ndk-r26b-windows.zip' ...
T:\android-cmdline-tools.zip not found. Downloading ...
T:\microsoft-jdk.zip not found. Downloading ...
Extracting 'microsoft-jdk.zip' ...
'android-cmdline-tools.zip' is already extracted and up to date.
Error: The term 'T:\android-ndk-r26b\.temp\cmdline-tools\bin\sdkmanager.bat' is not recognized

Must be an issue with Extract-ZipFile

@weliveindetail
Copy link
Member Author

@swift-ci Please test Windows

@weliveindetail
Copy link
Member Author

AVD failed to create a virtual device:

Error: Package path is not valid. Valid system image paths are:
null
Error: Error: avdmanager.bat exited with code 1.
Invocation:
  T:\android-ndk-r26b\cmdline-tools\latest\bin\avdmanager.bat create avd --name swift-test-device --package system-images;android-29;default;x86_64

@weliveindetail
Copy link
Member Author

@swift-ci Please test Windows

@weliveindetail
Copy link
Member Author

The build failed before any of the changes in $WebClient.DownloadFile($URL, $Destination):

T:\android-ndk-r26b-windows.zip not found. Downloading ...
Error: Exception calling "DownloadFile" with "2" argument(s): "The operation has timed out."
    at DownloadAndVerify, C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\utils\build.ps1: line 645
    at Fetch-Dependencies, C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\utils\build.ps1: line 795

Let's try that again.
@swift-ci Please test Windows

@weliveindetail
Copy link
Member Author

We reach that step now that creates the virtual device and need to figure out how to avoid the interactive config:

Auto-selecting single ABI x86_64
Do you wish to create a custom hardware profile? [no] offset 0, count -1, length 256
Error: Error: avdmanager.bat exited with code 1.
Invocation:
  T:\android-sdk\cmdline-tools\latest\bin\avdmanager.bat create avd --name "swift-test-device" --package "system-images;android-29;default;x86_64"

@weliveindetail
Copy link
Member Author

@swift-ci Please test Windows

@weliveindetail
Copy link
Member Author

@swift-ci please test Windows

@weliveindetail
Copy link
Member Author

The build failed due to an unrelated issue in LLDB:

llvm-project\lldb\source\Plugins\LanguageRuntime\Swift\ReflectionContext.cpp(405): error C2039: 'ResumeAsyncContext': is not a member of 'swift::reflection::ReflectionContext<swift::External<swift::NoObjCInterop<swift::RuntimeTarget<8>>>>::AsyncTaskInfo'

@weliveindetail
Copy link
Member Author

swiftlang/swift-corelibs-libdispatch#855
@swift-ci please test Windows

@weliveindetail
Copy link
Member Author

Looks like we need the Java runtime for the emulator as well and not only for for cmdline-tools. This worked locally, because the Java Runtime on my host isn't outdated like the one on the CI machines. I will retry once the current run reached the timeout.

@weliveindetail
Copy link
Member Author

swiftlang/swift-corelibs-libdispatch#855
@swift-ci please test Windows

@weliveindetail
Copy link
Member Author

Still:

error: no devices/emulators found

@weliveindetail
Copy link
Member Author

I can reproduce this locally by deleting the virtual device before running the build script. It seems that we cannot run a virtual device if we just created it, in particular, in the same process tree. The emulator process crashes without further notice. We can even wait and attempt it again and it crashes the same way. My latest patch demonstrates that. Running the build script again, however, works perfectly. So, this isn't an issue with permissions or execution environment.

Instead, I assume that the avdmanager keeps a file handle open and the emulator fails to lock it. Once we close the build script process, the handle is released and next time the emulator can lock it, because we don't need to recreate the virtual devices. I will double-check and see how to close them.

Anyway, let's run through the current state one more time.

swiftlang/swift-corelibs-libdispatch#855
@swift-ci please test Windows

@weliveindetail
Copy link
Member Author

Build bot failed as expected:

ANDROID_SDK_HOME = T:\android-sdk
T:\android-sdk\cmdline-tools\latest\bin\avdmanager.bat list avd reports:
Available Android Virtual Devices:
Create Android virtual device for arch x86_64
T:\android-sdk\cmdline-tools\latest\bin\avdmanager.bat list avd reports:
Available Android Virtual Devices:
    Name: swift-test-device-x86_64
    Path: T:\android-sdk\.android\avd\swift-test-device-x86_64.avd
  Target: Default Android System Image
          Based on: Android 10.0 ("Q") Tag/ABI: default/x86_64
  Sdcard: 512 MB
T:\android-sdk\emulator\emulator.exe -list-avds reports:
swift-test-device-x86_64
Start Android emulator for arch x86_64
Waiting for process 4584 to start
Process 4584 failed to start, trying again...
Waiting for process 9360 to start
Process 9360 failed to start, trying again...
Waiting for process 9668 to start
Process 9668 failed to start, trying again...
Waiting for process 5356 to start
Process 5356 failed to start, trying again...
Waiting for process 7624 to start
Error: Android emulator process 7624 failed to start.

@weliveindetail
Copy link
Member Author

Trial and error found a fix locally. Let's see if CI reproduces that 🤞
@swift-ci please test Windows

Copy link
Member Author

@weliveindetail weliveindetail left a comment

Choose a reason for hiding this comment

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

We got past the emulator startup 🙌

utils/build.ps1 Outdated

Write-Host "Waiting while Android emulator boots in process $AndroidEmulatorPid"
$adb = "$BinaryCache\android-sdk\platform-tools\adb.exe"
Invoke-Program $adb "wait-for-device"
Copy link
Member Author

@weliveindetail weliveindetail Feb 4, 2025

Choose a reason for hiding this comment

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

Now the build bot hangs here in adb wait-for-device

@weliveindetail
Copy link
Member Author

@swift-ci please test Windows

@weliveindetail
Copy link
Member Author

No luck with that

T:\android-sdk\emulator\emulator.exe -list-avds reports:
swift-test-device-x86_64
Start Android emulator for arch x86_64
Waiting for process 6632 to start
Waiting while Android emulator boots in process 6632
adb wait-for-device running in process 7648
* daemon not running; starting now at tcp:5037
* daemon started successfully
adb failed to connect. Shutting it down.
adb wait-for-device running in process 3928
adb failed to connect. Shutting it down.
adb wait-for-device running in process 6132
adb failed to connect. Shutting it down.
adb wait-for-device running in process 10728
adb failed to connect. Shutting it down.
adb wait-for-device running in process 6324
Error: Android Debug Bridge process 6324 failed to connect.
    at <ScriptBlock>, C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\utils\build.ps1: line 1047
    at Isolate-EnvVars, C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\utils\build.ps1: line 610
    at AndroidEmulator-Run, C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\utils\build.ps1: line 993
    at <ScriptBlock>, C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\utils\build.ps1: line 3214
  From System.Management.Automation.RuntimeException: Android Debug Bridge process 6324 failed to connect.
error: no emulator detected

@finagolfin
Copy link
Member

Are you familiar with the popular ReactiveCircus github workflow to start an Android emulator on macOS/linux? They have it create some kind of polling loop in Typescript that waits to make sure the emulator starts up. Maybe you could look at their OSS code and find something useful for your Windows emulator startup here.

@weliveindetail
Copy link
Member Author

No I wasn't aware of it. I am afraid the issues here are very Windows specific, but it's still a good source for common things to try. Like emulator flags -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none for example. Thanks

@weliveindetail
Copy link
Member Author

@swift-ci please test Windows

@weliveindetail
Copy link
Member Author

@swift-ci please test Windows

@weliveindetail
Copy link
Member Author

@swift-ci please test Windows

@weliveindetail
Copy link
Member Author

weliveindetail commented Feb 21, 2025

Android emulator requires Hyper-V support in Windows, but the CI machines don't seem to have it.

T:\android-sdk\emulator\emulator.exe -accel-check reports:
accel:
3
Android Emulator requires an Intel/AMD processor with virtualization extension support.  (Virtualization extension is not supported)
accel

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.

4 participants