Skip to content

[Bug]: Python Client reports connected after an unsuccessful connection probe #30060

Description

@dengn

Existing issue check

  • Checked relevant Python SDK issues; this report concerns the SDK client path.

Environment

Repository main 3e50e1b32d8da61bbbf70c89989fb08b671809de, Python 3.12, SQLAlchemy 1.4/2.x. Initial findings were reproduced offline with synthetic inputs; real-service validation will be linked from the implementation PR.

Priority: P0.

Actual behavior and reproduction

Mock the lazy engine factory and make version-query execution raise an unreachable-endpoint error. Call connect(database='test', on_connect=[]). The probe error is swallowed and connected() returns True because it only checks engine existence; success is logged before an authenticated query succeeds.

Expected behavior

A successful connect must include an authenticated query. Unreachable host, rejected authentication and failed initialization must leave no usable engine/pool and must not log success. Dispose old engines on reconnect and reclaim failed new engines. connected() describes successful initialization; live health checks remain distinct.

Design and acceptance tests

Perform a required SELECT 1 before manager/version initialization and success reporting. Dispose and clear a failed engine while preserving the primary error and cancellation. Tests must verify successful handshake, failure/disposal, no success log on failure, reconnect cleanup, real unreachable port, invalid credentials and pool reuse.

Implementation tracking

#30074 — draft implementation with regression cases and recorded local validation. Pending review/merge; the issue closes on merge.

Activity

  1. XuPeng-SH commented on Oct 20, 2026

    @XuPeng-SH
    Contributor

    Validation follow-up for merged PR #30074: I found one remaining sync-client observability gap in clients/python/matrixone/client.py. Client.connect() logs success=True immediately after the SELECT 1 probe, before _initialize_vector_managers() and _execute_connection_hook_immediately(). If either post-probe initialization step raises, the exception path clears/disposes the engine and logs failure, but the success event has already been emitted. That contradicts this issue's acceptance condition that failed initialization must not log success.

    A focused regression can let the probe succeed, make _initialize_vector_managers() raise, and assert connect() raises, the engine is disposed/cleared, and no log_connection(success=True) call occurs. The merged tests cover probe failure, but I did not find this post-probe initialization failure case in test_connection_contracts.py. I left this issue open for that gap.

    Local validation update (2026-10-20)

    Reproduced against MatrixOne HEAD 21966565287edf9f7d7f519af60d269711608945 using the actual Python SDK implementation: the mocked SELECT 1 probe succeeds, then _initialize_managers raises an injected initialization error. connect() raises ConnectionError and connected() is false after cleanup, but the captured connection-success flags are [True, False]. This confirms the false success event is emitted before initialization completes.

    Also reran pytest -q clients/python/tests/offline at that HEAD: passed (warnings only).

  2. Ariznawlll commented on Oct 23, 2026

    @Ariznawlll
    Collaborator

    测试版本

    原问题验证

    使用真实 SQLAlchemy/PyMySQL 连接到本机 MatrixOne,而非仅构造 mock engine。Client.connect(..., on_connect=[]) 成功时实际完成认证及 SELECT 1,connected() 为 true、连接成功日志标记为 [True];错误密码、不可达端口以及认证探测成功后注入 manager 初始化异常时,connect() 均抛出连接异常,connected() 为 false、_engine 已清空,成功日志均未出现,标记实际为 [False]。实库探测连续 3/3 轮通过;特别覆盖了此前评论指出的“探测通过但后续初始化失败仍先记录成功”的残留点。

    Happy Path 覆盖

    1. 有效账户连接并查询通过;同一个 SDK Client 再次连接,前一 Engine 的 dispose() 实际调用 1 次,新的连接仍可用。3/3 轮一致。

    Unhappy Path 覆盖

    1. 错误密码:连接抛错、无可用 Engine/连接状态、没有虚假成功日志,失败 Engine 的 dispose() 恰好调用 1 次,3/3。
    2. 本机不可达端口:连接抛错、无可用 Engine/连接状态、没有虚假成功日志,失败 Engine 的 dispose() 恰好调用 1 次,3/3。
    3. 在真实认证/SELECT 1 成功后注入 manager 初始化失败:连接抛错并释放/清空 Engine,dispose() 恰好调用 1 次,仅记录失败,不会先记录成功,3/3。
    4. 每轮临时测试库在 finally 中删除;未写入共享环境。

    白盒验证

    • 对 clients/python/tests/offline/test_connection_contracts.py 独立执行 3 次,每次 23 个测试均通过,覆盖探测失败清理、认证后成功门槛、初始化失败日志、异步与超时等已有 SDK 契约。
    • 本轮未跑完整 Python SDK offline suite;未将单项契约测试冒充完整 suite。

    回归测试

    测试证据

    • SDK 后续修复 PR #30678;其 Python SDK offline CI。
    • 本机独立实库探针 3/3 次均输出 initial_connect=PASS、reconnect_disposes_old_pool=PASS、invalid_auth_no_false_success=PASS、unreachable_no_false_success=PASS、post_probe_init_no_false_success=PASS、failed_pool_disposal=PASS;对应 SDK 契约测试每轮均为 23/23 通过。

    测试结论

    测试通过。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

kind/bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions