Files
hurui200320 317d015260
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 16s
CI / build (pull_request) Successful in 17s
CI / quality (pull_request) Successful in 18s
CI / e2e_tests (pull_request) Successful in 27s
CI / security (pull_request) Successful in 38s
CI / typecheck (pull_request) Successful in 39s
CI / unit_tests (pull_request) Successful in 3m0s
CI / docker (pull_request) Successful in 10s
CI / integration_tests (pull_request) Successful in 3m29s
CI / coverage (pull_request) Successful in 5m54s
CI / lint (push) Successful in 13s
CI / build (push) Successful in 14s
CI / quality (push) Successful in 17s
CI / security (push) Successful in 38s
CI / e2e_tests (push) Successful in 36s
CI / typecheck (push) Successful in 39s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 2m59s
CI / integration_tests (push) Successful in 3m24s
CI / docker (push) Successful in 38s
CI / coverage (push) Successful in 5m54s
CI / benchmark-publish (push) Successful in 19m34s
CI / benchmark-regression (pull_request) Successful in 36m21s
test(e2e): validate M4 acceptance criteria for v3.3.0 milestone closure
Strengthen M4 E2E CLI acceptance tests and address all review findings
from the self-review on PR #681 (3 blocking, 7 non-blocking issues).

Blocking fixes:
- Remove tautological domain assertions from cli_plan_execute() that
  verified values the test itself constructed via _mock_parent_plan and
  could never fail.  Replace with a comment documenting that subplan
  info cannot be verified from CLI output alone.
- Fix unguarded positional arg access in plan_diff() that would raise
  IndexError if the production CLI passes plan_id as a keyword argument.
  Now uses kwargs-with-positional-fallback pattern.
- Split the 1074-line helper_m4_e2e_verification.py into four focused
  modules under the CONTRIBUTING.md 500-line limit:
    helper_m4_e2e_common.py (237 lines) — constants, helpers, factories
    helper_m4_e2e_domain.py (495 lines) — domain model tests
    helper_m4_e2e_cli.py    (426 lines) — CLI integration tests
    helper_m4_e2e_verification.py (81 lines) — thin dispatcher

Non-blocking improvements:
- Add ProjectLink isinstance type guard before iterating project_links.
- Wrap all assert_called_once*() calls in try/except with _fail()
  pattern to produce standardised FAIL: diagnostics instead of raw
  AssertionError.
- Make project_links extraction symmetric with action_name (kwargs +
  positional fallback at index 1).
- Replace broad "execute" substring match with word-boundary regex
  r"\bexecute\b" to avoid false positives from incidental substrings.
- Extract _make_subplan_status() factory, _assert_exit_code() and
  _assert_mock_called_once*() wrappers to eliminate DRY violations
  (SubplanStatus construction repeated 3x, exit-code checks 4x).
- Replace non-deterministic datetime.now() calls with frozen constant
  _FROZEN_NOW = datetime(2026, 3, 1, 12, 0, 0) for deterministic
  fixtures.
- Rename generic _DECISION_ULID_N constants to descriptive names
  (_DECISION_PROMPT_DEF, _DECISION_STRATEGY, _DECISION_PARALLEL_SPAWN,
  _DECISION_SPAWN_API, _DECISION_SPAWN_UI).

Quality gates:
- lint: PASS
- format: PASS (1404 files unchanged)
- typecheck: PASS (0 errors)
- unit_tests: 10,431 scenarios, 0 failures
- integration_tests: 1,452 tests, 0 failures
- coverage_report: PASS (98%, threshold 97%)
- security_scan: PASS
- dead_code: PASS
- docs: PASS
- build: PASS

ISSUES CLOSED: #495
2026-03-13 14:03:37 +08:00

65 lines
2.2 KiB
Python

"""Shared utilities for Robot Framework helper scripts.
This module centralises the ``reset_global_state()`` function used by
``helper_m4_e2e_verification.py`` (and its sub-modules
``helper_m4_e2e_common.py``, ``helper_m4_e2e_domain.py``,
``helper_m4_e2e_cli.py``),
``helper_m4_correction_subplan_smoke.py``, and
``helper_m3_decision_validation_smoke.py``.
Any helper script invoked via ``Run Process`` from a ``.robot`` suite
can import this module to reset process-wide singletons between
chained CLI invocations.
"""
import contextlib
import sys
def reset_global_state() -> None:
"""Reset process-wide singletons between CLI invocations.
Clears the Settings singleton, DI container, provider registry,
and in-memory SQLAlchemy engine cache so that chained CLI
invocations within the same helper process do not carry stale
state.
Each import is guarded by ``contextlib.suppress(ImportError)``
because this module lives in ``robot/`` and may be loaded in
contexts where not all application modules are on the path
(e.g. a minimal helper that only exercises domain models).
This is an intentional exception to the top-of-file import rule
per CONTRIBUTING.md §Import Guidelines.
"""
# Settings singleton
with contextlib.suppress(ImportError):
from cleveragents.config.settings import Settings
Settings._instance = None
# DI container singleton
with contextlib.suppress(ImportError):
from cleveragents.application.container import reset_container
reset_container()
# Provider registry singleton
with contextlib.suppress(ImportError):
from cleveragents.providers.registry import reset_provider_registry
reset_provider_registry()
# In-memory SQLAlchemy engine cache
with contextlib.suppress(ImportError):
from cleveragents.infrastructure.database.engine_cache import MEMORY_ENGINES
for _url, engine in list(MEMORY_ENGINES.items()):
try:
engine.dispose()
except Exception as exc:
print(
f"[helpers_common] engine.dispose() suppressed: {exc}",
file=sys.stderr,
)
MEMORY_ENGINES.clear()