Skip to content

Increasing code coverage

91e67e5
Select commit
Loading
Failed to load commit list.
Merged

FIX: Setinputsizes() SQL_DECIMAL crash #519

Increasing code coverage
91e67e5
Select commit
Loading
Failed to load commit list.
Azure Pipelines / MSSQL-Python-PR-Validation succeeded Apr 14, 2026 in 18m 4s

Build #pr-validation-pipeline had test failures

Details

Tests

  • Failed: 1 (0.00%)
  • Passed: 28,423 (97.26%)
  • Other: 799 (2.73%)
  • Total: 29,223
Code coverage

  • 6648 of 8391 lines covered (79.23%)

Annotations

Check failure on line 1 in test_mixed_handle_cleanup_at_shutdown

See this annotation in the file changed.

@azure-pipelines azure-pipelines / MSSQL-Python-PR-Validation

test_mixed_handle_cleanup_at_shutdown

AssertionError: Process crashed. stderr: 
assert -11 == 0
 +  where -11 = CompletedProcess(args=['/opt/venv/bin/python', '-c', '\nimport sys\nfrom mssql_python import connect\n\nconnections = []\n\n# Connection 1: Everything left open\nconn1 = connect("Server=172.17.0.4;Database=TestDB;Uid=SA;Pwd=Azure@123!;TrustServerCertificate=yes")\ncursor1a = conn1.cursor()\ncursor1a.execute("SELECT 1 AS test")\ncursor1a.fetchall()\ncursor1b = conn1.cursor()\ncursor1b.execute("SELECT 2 AS test")\ncursor1b.fetchall()\nconnections.append((conn1, [cursor1a, cursor1b]))\nprint("Connection 1: cursors left open")\n\n# Connection 2: Cursors closed, connection left open\nconn2 = connect("Server=172.17.0.4;Database=TestDB;Uid=SA;Pwd=Azure@123!;TrustServerCertificate=yes")\ncursor2a = conn2.cursor()\ncursor2a.execute("SELECT 3 AS test")\ncursor2a.fetchall()\ncursor2a.close()\ncursor2b = conn2.cursor()\ncursor2b.execute("SELECT 4 AS test")\ncursor2b.fetchall()\ncursor2b.close()\nconnections.append((conn2, []))\nprint("Connection 2: cursors closed, connection left open")\n\n# Connection 3: Everything properly closed\nconn3 = connect("Server=172.17.0.4;Database=TestDB;Uid=SA;Pwd=Azure@123!;TrustServerCertificate=yes")\ncursor3a = conn3.cursor()\ncursor3a.execute("SELECT 5 AS test")\ncursor3a.fetchall()\ncursor3a.close()\nconn3.close()\nprint("Connection 3: everything properly closed")\n\n# Let Python shutdown with mixed cleanup state\n# - Type 3 (STMT) handles from conn1 cursors: skipped during shutdown\n# - Type 2 (DBC) handles from conn1, conn2: skipped during shutdown\n# - Type 1 (ENV) handle: normal C++ static destruction\nprint("Mixed handle cleanup test: Exiting with partial cleanup")\nsys.exit(0)\n'], returncode=-11, stdout='', stderr='').returncode
Raw output
self = <test_013_SqlHandle_free_shutdown.TestHandleFreeShutdown object at 0x5507e94610>
conn_str = 'Server=172.17.0.4;Database=TestDB;Uid=SA;Pwd=Azure@123!;TrustServerCertificate=yes'

    def test_mixed_handle_cleanup_at_shutdown(self, conn_str):
        """
        Test mixed scenario with all handle types during shutdown.
    
        Scenario:
        1. Create multiple connections (DBC handles)
        2. Create multiple cursors per connection (STMT handles)
        3. Some cursors closed, some left open
        4. Some connections closed, some left open
        5. Let Python shutdown handle the rest
    
        Expected: No segfault, clean exit
        This tests the real-world scenario where cleanup is partial
        """
        script = textwrap.dedent(f"""
            import sys
            from mssql_python import connect
    
            connections = []
    
            # Connection 1: Everything left open
            conn1 = connect("{conn_str}")
            cursor1a = conn1.cursor()
            cursor1a.execute("SELECT 1 AS test")
            cursor1a.fetchall()
            cursor1b = conn1.cursor()
            cursor1b.execute("SELECT 2 AS test")
            cursor1b.fetchall()
            connections.append((conn1, [cursor1a, cursor1b]))
            print("Connection 1: cursors left open")
    
            # Connection 2: Cursors closed, connection left open
            conn2 = connect("{conn_str}")
            cursor2a = conn2.cursor()
            cursor2a.execute("SELECT 3 AS test")
            cursor2a.fetchall()
            cursor2a.close()
            cursor2b = conn2.cursor()
            cursor2b.execute("SELECT 4 AS test")
            cursor2b.fetchall()
            cursor2b.close()
            connections.append((conn2, []))
            print("Connection 2: cursors closed, connection left open")
    
            # Connection 3: Everything properly closed
            conn3 = connect("{conn_str}")
            cursor3a = conn3.cursor()
            cursor3a.execute("SELECT 5 AS test")
            cursor3a.fetchall()
            cursor3a.close()
            conn3.close()
            print("Connection 3: everything properly closed")
    
            # Let Python shutdown with mixed cleanup state
            # - Type 3 (STMT) handles from conn1 cursors: skipped during shutdown
            # - Type 2 (DBC) handles from conn1, conn2: skipped during shutdown
            # - Type 1 (ENV) handle: normal C++ static destruction
            print("Mixed handle cleanup test: Exiting with partial cleanup")
            sys.exit(0)
        """)
    
        result = subprocess.run(
            [sys.executable, "-c", script], capture_output=True, text=True, timeout=5
        )
    
>       assert result.returncode == 0, f"Process crashed. stderr: {result.stderr}"
E       AssertionError: Process crashed. stderr: 
E       assert -11 == 0
E        +  where -11 = CompletedProcess(args=['/opt/venv/bin/python', '-c', '\nimport sys\nfrom mssql_python import connect\n\nconnections = []\n\n# Connection 1: Everything left open\nconn1 = connect("Server=172.17.0.4;Database=TestDB;Uid=SA;Pwd=Azure@123!;TrustServerCertificate=yes")\ncursor1a = conn1.cursor()\ncursor1a.execute("SELECT 1 AS test")\ncursor1a.fetchall()\ncursor1b = conn1.cursor()\ncursor1b.execute("SELECT 2 AS test")\ncursor1b.fetchall()\nconnections.append((conn1, [cursor1a, cursor1b]))\nprint("Connection 1: cursors left open")\n\n# Connection 2: Cursors closed, connection left open\nconn2 = connect("Server=172.17.0.4;Database=TestDB;Uid=SA;Pwd=Azure@123!;TrustServerCertificate=yes")\ncursor2a = conn2.cursor()\ncursor2a.execute("SELECT 3 AS test")\ncursor2a.fetchall()\ncursor2a.close()\ncursor2b = conn2.cursor()\ncursor2b.execute("SELECT 4 AS test")\ncursor2b.fetchall()\ncursor2b.close()\nconnections.append((conn2, []))\nprint("Connection 2: cursors closed, connection left open")\n\n# Connection 3: Everything properly closed\nconn3 = connect("Server=172.17.0.4;Database=T