Skip to content

Commit 3842583

Browse files
fix test_closing_connection_closes_commands (#584)
* [init] working code for corrected test Signed-off-by: varun-edachali-dbx <[email protected]> * excess comments Signed-off-by: varun-edachali-dbx <[email protected]> * use pytest parametrize instead of unittest subtests, switch to pytest instead of unittest primitives Signed-off-by: varun-edachali-dbx <[email protected]> * initialisations, function calls, then assertions Signed-off-by: varun-edachali-dbx <[email protected]> * remove pytest parametrize, move back to unittest subTest to allow keeping the test inside ClientTestSuite Signed-off-by: varun-edachali-dbx <[email protected]> * clean up docstring Signed-off-by: varun-edachali-dbx <[email protected]> * remove pytest import Signed-off-by: varun-edachali-dbx <[email protected]> --------- Signed-off-by: varun-edachali-dbx <[email protected]>
1 parent 0947b9a commit 3842583

File tree

1 file changed

+68
-10
lines changed

1 file changed

+68
-10
lines changed

tests/unit/test_client.py

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
TExecuteStatementResp,
1414
TOperationHandle,
1515
THandleIdentifier,
16+
TOperationState,
1617
TOperationType,
1718
)
1819
from databricks.sql.thrift_backend import ThriftBackend
@@ -23,6 +24,7 @@
2324
from databricks.sql.exc import RequestError, CursorAlreadyClosedError
2425
from databricks.sql.types import Row
2526

27+
from databricks.sql.utils import ExecuteResponse
2628
from tests.unit.test_fetches import FetchTests
2729
from tests.unit.test_thrift_backend import ThriftBackendTestSuite
2830
from tests.unit.test_arrow_queue import ArrowQueueSuite
@@ -168,22 +170,78 @@ def test_useragent_header(self, mock_client_class):
168170
http_headers = mock_client_class.call_args[0][3]
169171
self.assertIn(user_agent_header_with_entry, http_headers)
170172

171-
@patch("%s.client.ThriftBackend" % PACKAGE_NAME, ThriftBackendMockFactory.new())
172-
@patch("%s.client.ResultSet" % PACKAGE_NAME)
173-
def test_closing_connection_closes_commands(self, mock_result_set_class):
174-
# Test once with has_been_closed_server side, once without
173+
@patch("databricks.sql.client.ThriftBackend")
174+
def test_closing_connection_closes_commands(self, mock_thrift_client_class):
175+
"""Test that closing a connection properly closes commands.
176+
177+
This test verifies that when a connection is closed:
178+
1. the active result set is marked as closed server-side
179+
2. The operation state is set to CLOSED
180+
3. backend.close_command is called only for commands that weren't already closed
181+
182+
Args:
183+
mock_thrift_client_class: Mock for ThriftBackend class
184+
"""
175185
for closed in (True, False):
176186
with self.subTest(closed=closed):
177-
mock_result_set_class.return_value = Mock()
178-
connection = databricks.sql.connect(**self.DUMMY_CONNECTION_ARGS)
187+
# Set initial state based on whether the command is already closed
188+
initial_state = (
189+
TOperationState.FINISHED_STATE
190+
if not closed
191+
else TOperationState.CLOSED_STATE
192+
)
193+
194+
# Mock the execute response with controlled state
195+
mock_execute_response = Mock(spec=ExecuteResponse)
196+
mock_execute_response.status = initial_state
197+
mock_execute_response.has_been_closed_server_side = closed
198+
mock_execute_response.is_staging_operation = False
199+
200+
# Mock the backend that will be used
201+
mock_backend = Mock(spec=ThriftBackend)
202+
mock_thrift_client_class.return_value = mock_backend
203+
204+
# Create connection and cursor
205+
connection = databricks.sql.connect(
206+
server_hostname="foo",
207+
http_path="dummy_path",
208+
access_token="tok",
209+
)
179210
cursor = connection.cursor()
180-
cursor.execute("SELECT 1;")
211+
212+
# Mock execute_command to return our execute response
213+
cursor.thrift_backend.execute_command = Mock(
214+
return_value=mock_execute_response
215+
)
216+
217+
# Execute a command
218+
cursor.execute("SELECT 1")
219+
220+
# Get the active result set for later assertions
221+
active_result_set = cursor.active_result_set
222+
223+
# Close the connection
181224
connection.close()
182225

183-
self.assertTrue(
184-
mock_result_set_class.return_value.has_been_closed_server_side
226+
# Verify the close logic worked:
227+
# 1. has_been_closed_server_side should always be True after close()
228+
assert active_result_set.has_been_closed_server_side is True
229+
230+
# 2. op_state should always be CLOSED after close()
231+
assert (
232+
active_result_set.op_state
233+
== connection.thrift_backend.CLOSED_OP_STATE
185234
)
186-
mock_result_set_class.return_value.close.assert_called_once_with()
235+
236+
# 3. Backend close_command should be called appropriately
237+
if not closed:
238+
# Should have called backend.close_command during the close chain
239+
mock_backend.close_command.assert_called_once_with(
240+
mock_execute_response.command_handle
241+
)
242+
else:
243+
# Should NOT have called backend.close_command (already closed)
244+
mock_backend.close_command.assert_not_called()
187245

188246
@patch("%s.client.ThriftBackend" % PACKAGE_NAME)
189247
def test_cant_open_cursor_on_closed_connection(self, mock_client_class):

0 commit comments

Comments
 (0)