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