Conversation
On macOS the qt style creates AppKit controls, and AppKit deadlocks on any thread but the process main thread. libtest runs every test on a worker thread, so the widgets-qt driver tests hung forever in NativeSlider's QMacStyle hit test. Give the widgets-qt target its own harness, following the pattern of the test-backends crate: libtest-mimic forks one subprocess per test, and each subprocess runs its single test on its own main thread with its own thread-local testing platform. CI's '--skip=qt::' filter and '--list' behave as before.
tilladam
force-pushed
the
fix/qt-widgets-test-hang
branch
from
September 13, 2026 09:57
7949e89 to
908769c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On macOS,
cargo test -p test-driver-rust --test widgets-qthangs forever with 0% CPU. The qt style calls QStyle from the thread running the test, and QMacStyle instantiates AppKit controls for hit testing. On current macOS, AppKit's control layout goes through SwiftUI and blocks until it can run on the process main thread. libtest runs every test on a worker thread while the main thread waits for results, so the firstNativeSliderhit test deadlocks:--test-threads=1doesn't help: libtest still spawns a worker thread per test. CI never sees the hang because it filters these tests with--skip=qt::.This complements #13370, which runs
tests/run_tests.shoffscreen for machines without a display. With a display, the offscreen platform is not in effect for plaincargo test, and this change also lets the tests exercise the real macOS Qt style.Design
The
widgets-qttarget getsharness = falseand abuild.rs-generated harness, following the pattern of thetest-backendscrate: libtest-mimic forks one subprocess per test (marked with--exact <name>, the same convention cargo nextest uses), and each subprocess runs its single test on its own main thread with its own thread-local testing platform. Parallelism is preserved because every subprocess has its own main thread.The libtest CLI surface stays compatible:
--skip=qt::filters all tests out as before,--listprints the same names, and an--exactfilter that names a test from another target reports zero matching tests instead of failing.Testing
Everything measured on macOS arm64 (macOS 26.6, Qt with QMacStyle):
widgets-qt: 25/25 pass in ~7s, on both the macro and thebuild-timegeneration paths. Both previously hung on the first slider hit test.test-driver-rustsuite: 35/35 test binaries, 855 passed, 0 failed. The suite could not complete on this machine before.-- --skip=qt::(the CI invocation),-- --list, and cross-target-- --exactselection verified against the built binary.Follow-up
tests/backends' own fork harness has the same latent panic on an unmatched--exactfilter (run_test'sunwrap_or_else(panic!)intests/backends/tests/cases/harness.rs); the same fallthrough fix would apply there. Left out to keep this change to one target.