Use procspawn crate to run replay test on macOS #100
Merged
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.
This PR turns
test_replay
from a standalone, non-harness test into a normal unit test, that is part of the main binary target.The reason this test was split out into a separate binary was that it calls into GTK, and on macOS, GTK can only be used from the main thread of a program. When
cargo test
is run, it runs tests in worker threads. Even if--test-threads=1
is passed, it spawns a single worker thread, rather than running the tests on its main thread. So the replay test had to be written as a separate binary to ensure it executed on a main thread on macOS.Making this test into a separate binary has caused other problems, though: we had to define a library crate, and a public API for it, just so that the main binary target and the test could share code. That wasn't an architecture we wanted, and we'd like to undo that change before we publish the package.
So to allow the replay test to run as a normal unit test, this PR uses the procspawn crate to
spawn
a new process, much like one would spawn a thread. The child process runs from the same test binary, but branches at the point whereprocspawn::init()
is called. In the parent process, that function just returns, but in the child, it runs the closure provided in thespawn
call, and then sends the result to the parent over IPC.In order for a test using GTK to work correctly, that branch needs to happen before the test binary loads lots of libraries and starts executing its own code. So we use the ctor crate to register a function as a global constructor, which calls
procspawn::init()
right at the start of execution, beforemain
has even started.