|
50 | 50 |
|
51 | 51 | from tests.e2e.common.uc_volume_tests import PySQLUCVolumeTestSuiteMixin |
52 | 52 |
|
53 | | -from databricks.sql.exc import SessionAlreadyClosedError, CursorAlreadyClosedError |
| 53 | +from databricks.sql.exc import SessionAlreadyClosedError |
54 | 54 |
|
55 | 55 | log = logging.getLogger(__name__) |
56 | 56 |
|
@@ -808,146 +808,6 @@ def test_catalogs_returns_arrow_table(self): |
808 | 808 | results = cursor.fetchall_arrow() |
809 | 809 | assert isinstance(results, pyarrow.Table) |
810 | 810 |
|
811 | | - def test_close_connection_closes_cursors(self): |
812 | | - |
813 | | - from databricks.sql.thrift_api.TCLIService import ttypes |
814 | | - |
815 | | - with self.connection() as conn: |
816 | | - cursor = conn.cursor() |
817 | | - cursor.execute( |
818 | | - "SELECT id, id `id2`, id `id3` FROM RANGE(1000000) order by RANDOM()" |
819 | | - ) |
820 | | - ars = cursor.active_result_set |
821 | | - |
822 | | - # We must manually run this check because thrift_backend always forces `has_been_closed_server_side` to True |
823 | | - # Cursor op state should be open before connection is closed |
824 | | - status_request = ttypes.TGetOperationStatusReq( |
825 | | - operationHandle=ars.command_id, getProgressUpdate=False |
826 | | - ) |
827 | | - op_status_at_server = ars.thrift_backend._client.GetOperationStatus( |
828 | | - status_request |
829 | | - ) |
830 | | - assert ( |
831 | | - op_status_at_server.operationState |
832 | | - != ttypes.TOperationState.CLOSED_STATE |
833 | | - ) |
834 | | - |
835 | | - conn.close() |
836 | | - |
837 | | - # When connection closes, any cursor operations should no longer exist at the server |
838 | | - with pytest.raises(SessionAlreadyClosedError) as cm: |
839 | | - op_status_at_server = ars.thrift_backend._client.GetOperationStatus( |
840 | | - status_request |
841 | | - ) |
842 | | - |
843 | | - def test_closing_a_closed_connection_doesnt_fail(self, caplog): |
844 | | - caplog.set_level(logging.DEBUG) |
845 | | - # Second .close() call is when this context manager exits |
846 | | - with self.connection() as conn: |
847 | | - # First .close() call is explicit here |
848 | | - conn.close() |
849 | | - assert "Session appears to have been closed already" in caplog.text |
850 | | - |
851 | | - conn = None |
852 | | - try: |
853 | | - with pytest.raises(KeyboardInterrupt): |
854 | | - with self.connection() as c: |
855 | | - conn = c |
856 | | - raise KeyboardInterrupt("Simulated interrupt") |
857 | | - finally: |
858 | | - if conn is not None: |
859 | | - assert ( |
860 | | - not conn.open |
861 | | - ), "Connection should be closed after KeyboardInterrupt" |
862 | | - |
863 | | - def test_cursor_close_properly_closes_operation(self): |
864 | | - """Test that Cursor.close() properly closes the active operation handle on the server.""" |
865 | | - with self.connection() as conn: |
866 | | - cursor = conn.cursor() |
867 | | - try: |
868 | | - cursor.execute("SELECT 1 AS test") |
869 | | - assert cursor.active_op_handle is not None |
870 | | - cursor.close() |
871 | | - assert cursor.active_op_handle is None |
872 | | - assert not cursor.open |
873 | | - finally: |
874 | | - if cursor.open: |
875 | | - cursor.close() |
876 | | - |
877 | | - conn = None |
878 | | - cursor = None |
879 | | - try: |
880 | | - with self.connection() as c: |
881 | | - conn = c |
882 | | - with pytest.raises(KeyboardInterrupt): |
883 | | - with conn.cursor() as cur: |
884 | | - cursor = cur |
885 | | - raise KeyboardInterrupt("Simulated interrupt") |
886 | | - finally: |
887 | | - if cursor is not None: |
888 | | - assert ( |
889 | | - not cursor.open |
890 | | - ), "Cursor should be closed after KeyboardInterrupt" |
891 | | - |
892 | | - def test_nested_cursor_context_managers(self): |
893 | | - """Test that nested cursor context managers properly close operations on the server.""" |
894 | | - with self.connection() as conn: |
895 | | - with conn.cursor() as cursor1: |
896 | | - cursor1.execute("SELECT 1 AS test1") |
897 | | - assert cursor1.active_op_handle is not None |
898 | | - |
899 | | - with conn.cursor() as cursor2: |
900 | | - cursor2.execute("SELECT 2 AS test2") |
901 | | - assert cursor2.active_op_handle is not None |
902 | | - |
903 | | - # After inner context manager exit, cursor2 should be not open |
904 | | - assert not cursor2.open |
905 | | - assert cursor2.active_op_handle is None |
906 | | - |
907 | | - # After outer context manager exit, cursor1 should be not open |
908 | | - assert not cursor1.open |
909 | | - assert cursor1.active_op_handle is None |
910 | | - |
911 | | - def test_cursor_error_handling(self): |
912 | | - """Test that cursor close handles errors properly to prevent orphaned operations.""" |
913 | | - with self.connection() as conn: |
914 | | - cursor = conn.cursor() |
915 | | - |
916 | | - cursor.execute("SELECT 1 AS test") |
917 | | - |
918 | | - op_handle = cursor.active_op_handle |
919 | | - |
920 | | - assert op_handle is not None |
921 | | - |
922 | | - # Manually close the operation to simulate server-side closure |
923 | | - conn.thrift_backend.close_command(op_handle) |
924 | | - |
925 | | - cursor.close() |
926 | | - |
927 | | - assert not cursor.open |
928 | | - |
929 | | - def test_result_set_close(self): |
930 | | - """Test that ResultSet.close() properly closes operations on the server and handles state correctly.""" |
931 | | - with self.connection() as conn: |
932 | | - cursor = conn.cursor() |
933 | | - try: |
934 | | - cursor.execute("SELECT * FROM RANGE(10)") |
935 | | - |
936 | | - result_set = cursor.active_result_set |
937 | | - assert result_set is not None |
938 | | - |
939 | | - initial_op_state = result_set.op_state |
940 | | - |
941 | | - result_set.close() |
942 | | - |
943 | | - assert result_set.op_state == result_set.thrift_backend.CLOSED_OP_STATE |
944 | | - assert result_set.op_state != initial_op_state |
945 | | - |
946 | | - # Closing the result set again should be a no-op and not raise exceptions |
947 | | - result_set.close() |
948 | | - finally: |
949 | | - cursor.close() |
950 | | - |
951 | 811 |
|
952 | 812 | # use a RetrySuite to encapsulate these tests which we'll typically want to run together; however keep |
953 | 813 | # the 429/503 subsuites separate since they execute under different circumstances. |
|
0 commit comments