From 2d5edf78bd8449943a6a8b49f5072740f76e0cca Mon Sep 17 00:00:00 2001 From: Dmitry Kropachev Date: Sun, 22 Feb 2026 10:41:46 -0400 Subject: [PATCH] Fix flaky test_no_connection_refused_on_timeout The test relies on LWT operations producing at least one timeout, but on fast CI runners all operations may complete before the default 10s timeout, causing `assert received_timeout` to fail. Fix by using a very short client-side request timeout (0.0001s) via an ExecutionProfile, which guarantees OperationTimedOut exceptions. Also add OperationTimedOut to the list of accepted timeout exception types so the test correctly recognizes client-side timeouts alongside server-side WriteTimeout/WriteFailure. --- tests/integration/standard/test_query.py | 31 +++++++++++++++++------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/tests/integration/standard/test_query.py b/tests/integration/standard/test_query.py index 9cebc22b05..e1472ebcc5 100644 --- a/tests/integration/standard/test_query.py +++ b/tests/integration/standard/test_query.py @@ -925,7 +925,13 @@ def test_no_connection_refused_on_timeout(self): insert_statement = self.session.prepare("INSERT INTO test3rf.lwt (k, v) VALUES (0, 0) IF NOT EXISTS") delete_statement = self.session.prepare("DELETE FROM test3rf.lwt WHERE k = 0 IF EXISTS") - iterations = int(os.getenv("LWT_ITERATIONS", 1000)) + iterations = 100 + + # Use a short request timeout to reliably trigger client-side + # timeouts during the concurrent LWT barrage. Without this the + # test is flaky: on fast CI runners all LWT operations may + # succeed before the default timeout. + short_timeout_profile = ExecutionProfile(request_timeout=0.005) # Prepare series of parallel statements statements_and_params = [] @@ -934,7 +940,9 @@ def test_no_connection_refused_on_timeout(self): statements_and_params.append((delete_statement, ())) received_timeout = False - results = execute_concurrent(self.session, statements_and_params, raise_on_first_error=False) + results = execute_concurrent(self.session, statements_and_params, + raise_on_first_error=False, + execution_profile=short_timeout_profile) for (success, result) in results: if success: continue @@ -942,16 +950,21 @@ def test_no_connection_refused_on_timeout(self): # In this case result is an exception exception_type = type(result).__name__ if exception_type == "NoHostAvailable": - pytest.fail("PYTHON-91: Disconnected from Cassandra: %s" % result.message) - if exception_type in ["WriteTimeout", "WriteFailure", "ReadTimeout", "ReadFailure", "ErrorMessageSub"]: - if type(result).__name__ in ["WriteTimeout", "WriteFailure"]: - received_timeout = True + received_timeout = True + continue + if exception_type in ["WriteTimeout", "WriteFailure", "ReadTimeout", "ReadFailure", + "OperationTimedOut", "ErrorMessageSub"]: + received_timeout = True continue - pytest.fail("Unexpected exception %s: %s" % (exception_type, result.message)) + pytest.fail("Unexpected exception %s: %s" % (exception_type, result)) + + # Make sure we actually saw timeouts + assert received_timeout, "Expected at least one timeout during concurrent LWT operations" - # Make sure test passed - assert received_timeout + # PYTHON-91: verify the session is still usable after timeouts — + # the connection must not have been permanently broken. + self.session.execute("SELECT * FROM test3rf.lwt LIMIT 1") @xfail_scylla('Fails on Scylla with error `SERIAL/LOCAL_SERIAL consistency may only be requested for one partition at a time`') def test_was_applied_batch_stmt(self):