* refactor(channels): own setup and instance contracts * refactor(channels): isolate management contracts * refactor(channels): normalize activation contracts * fix(channels): enforce management contracts * refactor(channels): finish setup ownership migration * fix(channels): harden management contracts * fix(channels): enforce lazy loading and runtime ownership * fix(feishu): make multi-instance startup idempotent * fix(webui): render channel setup contracts cleanly * fix(feishu): stop websocket clients cleanly * fix(channels): enforce persistence and activation gates * fix(channels): preserve global feature action scope * fix(channels): apply defaults for single plugins * fix(channels): enforce management contract boundaries * refactor(feishu): remove identity helper indirection * fix(channels): preserve management setup contracts * refactor(channels): generalize instance settings UI * refactor(channels): package channel plugins with web UI metadata * refactor(channels): make built-ins self-contained packages * test(channels): colocate tests with channel packages * fix(dingtalk): use official brand icon * feat(channels): colocate webui translations * docs(channels): clarify plugin ownership * test(exec): remove output wait race * refactor(channels): unify plugin descriptors * fix(channels): enforce descriptor-owned contracts * refactor(channels): finish package-owned plugin setup * refactor(channels): use repository-owned packages only * fix(channels): self-describe dependencies and runtime state * fix(channels): warn about legacy entry points
52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
"""Cross-suite test infrastructure."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import ssl
|
|
import sys
|
|
from collections.abc import Iterator
|
|
|
|
import certifi
|
|
import pytest
|
|
|
|
|
|
@pytest.fixture(scope="session", autouse=True)
|
|
def _use_windows_system_ca_for_default_http_clients() -> Iterator[None]:
|
|
"""Avoid reparsing certifi's CA bundle for every offline HTTP client.
|
|
|
|
Loading certifi takes roughly 0.7 seconds per client on Windows. The test
|
|
suite constructs hundreds of clients while mocking their I/O. System roots
|
|
preserve certificate verification for accidental local requests; explicit
|
|
``cafile``, ``capath``, and ``cadata`` arguments still use the real loader.
|
|
"""
|
|
if sys.platform != "win32":
|
|
yield
|
|
return
|
|
|
|
original = ssl.create_default_context
|
|
certifi_path = os.path.normcase(os.path.abspath(certifi.where()))
|
|
|
|
def create_default_context(
|
|
purpose: ssl.Purpose = ssl.Purpose.SERVER_AUTH,
|
|
*,
|
|
cafile: str | None = None,
|
|
capath: str | None = None,
|
|
cadata: str | bytes | None = None,
|
|
) -> ssl.SSLContext:
|
|
requested_path = os.path.normcase(os.path.abspath(cafile)) if cafile else None
|
|
if requested_path == certifi_path and capath is None and cadata is None:
|
|
return original(purpose)
|
|
return original(
|
|
purpose,
|
|
cafile=cafile,
|
|
capath=capath,
|
|
cadata=cadata,
|
|
)
|
|
|
|
ssl.create_default_context = create_default_context
|
|
try:
|
|
yield
|
|
finally:
|
|
ssl.create_default_context = original
|