-
Notifications
You must be signed in to change notification settings - Fork 585
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
FIX: Race conditions in test_cli.py
when spawning test server processes
#4178
FIX: Race conditions in test_cli.py
when spawning test server processes
#4178
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice work!
The pylint failures in CI look relevant. If there is anything it's warning about that isn't sensible to change, feel free to locally disable the warning.
This uses Python's async process handling based on the asyncio module as a replacement for the low-level use of subprocess.Popen along with arbitrary (and inherently racey) time.sleep() calls.
3294602
to
934f3fe
Compare
In the first run macOS 14 (on Apple Silicon) failed obscurely:
.... looks like the interpreter crashed after the script had finished. 😨 I'd suggest to just merge and see whether that comes back. Perhaps we'll end up having to update the python interpreter in the build job setup or disable those tests on macOS 14 for some time. 😒 |
I think the macOS failure is #3991 so unrelated to this change. |
Let's hope so. In it goes! |
Couple of Windows builds in the merge are failing, maybe we need more than 15 seconds in practice on CI? |
Pull Request Dependencies
./botan tls_proxy
#4177Description
The
test_cli.py
script handles and orchestrates a few long-running processes (namely./botan tls_server
,./botan tls_client
,./botan tls_proxy
). For those tests to work properly, we have to ensure that the server processes are ready before trying to interact with them. Especially on the CI where runtime behavior is notoriously unpredictable. Until now, this was done by invokingtime.sleep(1)
after launching a server process. This worked most of the time, but introduced unnecessary waiting time while still being potentially racey.This now uses Python's
asyncio
module to handle such long-running processes and interact with them. Each CLI server now reports a "Listening for new connections..." string on stdout once its ready to receive connections. Theasyncio
-based wrapper can wait for this string and thus ensure that the server is ready before the test continues. Also, the wrapper makes sure to timeout on any of those waits (hard-coded 15 seconds) and kill the process if necessary.Result
Such tests can now rely on their server processes being in a defined state, without sleeping some arbitrary time and hoping for the best. As a side effect, running
./test_cli.py --threads=4
now takes 2.5 seconds on my laptop, instead of the more than 20 seconds it used to take due to thetime.sleep()
workarounds.Fixes #4112