Files
yuanshuai c91a64fddb
CI / Python 3.12 (push) Waiting to run
CI / Python 3.9 (push) Waiting to run
chore(repo): initialize team collaboration repository
2026-07-27 20:40:12 +08:00

235 lines
6.7 KiB
Python

"""全部领域枚举。
放在包根、不依赖任何东西 —— models / engine / schemas / api 都从这里取,
保证"状态"这个概念在全仓库只有一份定义。
"""
from __future__ import annotations
from enum import Enum
class StrEnum(str, Enum):
"""Python 3.9 没有 enum.StrEnum,自己来一个。"""
def __str__(self) -> str: # pragma: no cover - 只影响日志可读性
return self.value
# ---------------------------------------------------------------- Run / Step
class RunState(StrEnum):
QUEUED = "QUEUED" # 等资源
PREFLIGHT = "PREFLIGHT" # 安全门禁 + 环境指纹冻结
RUNNING = "RUNNING"
RECOVERING = "RECOVERING" # 恢复阶梯进行中
PAUSED = "PAUSED" # 人工暂停
FROZEN = "FROZEN" # 冻结现场,停止一切覆盖性动作(终态)
COMPLETED = "COMPLETED" # 终态
ABORTED = "ABORTED" # 紧急停止(终态)
REJECTED = "REJECTED" # 安全门禁拒绝(终态)
class StepState(StrEnum):
PENDING = "PENDING"
DISPATCHED = "DISPATCHED" # 已租给 Agent,等确认接手
RUNNING = "RUNNING"
SUCCEEDED = "SUCCEEDED"
FAILED = "FAILED"
TIMED_OUT = "TIMED_OUT"
SKIPPED = "SKIPPED"
CANCELLED = "CANCELLED"
class Verdict(StrEnum):
PASS = "PASS"
FAIL = "FAIL"
INCONCLUSIVE = "INCONCLUSIVE" # 非幂等步骤中断后不自动重跑 → 需人工确认
# ------------------------------------------------------------------ 恢复阶梯
class RecoveryLevel(StrEnum):
"""方案 §7.2 的五级阶梯。顺序即升级顺序。"""
AGENT_SOFT = "L1_AGENT_SOFT" # Agent 优雅停止 / 软重启进程
OS_REBOOT = "L2_OS_REBOOT" # OS 远程通道重启
OOB_RESET = "L3_OOB_RESET" # 带外触发主板 Reset
OOB_ATX_POWER = "L4_OOB_ATX_POWER" # 带外模拟 ATX 长按关机再开机
OOB_AC_CYCLE = "L5_OOB_AC_CYCLE" # 整机 AC 断电 → 安全间隔 → 上电
FREEZE = "FREEZE" # 冻结现场,不再自动恢复
@property
def requires_oob(self) -> bool:
return self in (
RecoveryLevel.OOB_RESET,
RecoveryLevel.OOB_ATX_POWER,
RecoveryLevel.OOB_AC_CYCLE,
)
class RecoveryOutcome(StrEnum):
RECOVERED = "RECOVERED"
FAILED = "FAILED"
ESCALATED = "ESCALATED"
FROZEN = "FROZEN"
class RecoveryTrigger(StrEnum):
HEARTBEAT_LOST = "HEARTBEAT_LOST"
STEP_TIMEOUT = "STEP_TIMEOUT"
HOST_CRASH = "HOST_CRASH" # 蓝屏 / kernel panic
DUT_NOT_ENUMERATED = "DUT_NOT_ENUMERATED"
DATA_INTEGRITY = "DATA_INTEGRITY" # → 直接 FREEZE,不走阶梯
MANUAL = "MANUAL"
# -------------------------------------------------------------------- 资产
class HostStatus(StrEnum):
ONLINE = "ONLINE"
DEGRADED = "DEGRADED" # 心跳迟到但未判失联
OFFLINE = "OFFLINE"
UNKNOWN = "UNKNOWN"
class DutStatus(StrEnum):
IDLE = "IDLE"
IN_USE = "IN_USE"
QUARANTINED = "QUARANTINED" # 疑似坏盘,隔离待人工确认
MISSING = "MISSING" # 探针找不到
class PowerState(StrEnum):
ON = "ON"
OFF = "OFF"
UNKNOWN = "UNKNOWN"
class DangerLevel(StrEnum):
NONE = "none"
LOW = "low"
HIGH = "high" # 需要审批记录
# -------------------------------------------------------------------- 失败
class FailureClass(StrEnum):
"""INFRA_FAILURE 必须与 DUT_DEFECT 分开统计 —— 见 domain-model.md。
把网络断了算成 SSD 缺陷,客户第一周就不信任这套系统。
"""
DUT_DEFECT = "DUT_DEFECT"
INFRA_FAILURE = "INFRA_FAILURE"
SCRIPT_FAILURE = "SCRIPT_FAILURE"
DATA_INTEGRITY = "DATA_INTEGRITY"
UNKNOWN = "UNKNOWN"
class IntegrityState(StrEnum):
OK = "OK"
MISMATCH = "MISMATCH"
NOT_CHECKED = "NOT_CHECKED"
# ------------------------------------------------------------- 事件(时间线)
class EventSource(StrEnum):
CONTROL_PLANE = "control_plane"
AGENT = "agent"
OOB = "oob" # 带外通道 —— 主机死后唯一还在说话的
HUMAN = "human"
class Severity(StrEnum):
DEBUG = "DEBUG"
INFO = "INFO"
WARNING = "WARNING"
ERROR = "ERROR"
CRITICAL = "CRITICAL"
class EventKind(StrEnum):
"""统一时间线的事件种类。
新增事件种类是常事;删除/改名不是 —— 历史事件已经落库,改名会让旧 Run 的
时间线读不出来。只增不改。
"""
# Run 生命周期
RUN_CREATED = "RUN_CREATED"
RUN_QUEUED = "RUN_QUEUED"
RUN_PREFLIGHT_STARTED = "RUN_PREFLIGHT_STARTED"
RUN_PREFLIGHT_PASSED = "RUN_PREFLIGHT_PASSED"
RUN_REJECTED = "RUN_REJECTED"
RUN_STARTED = "RUN_STARTED"
RUN_PAUSED = "RUN_PAUSED"
RUN_RESUMED = "RUN_RESUMED"
RUN_COMPLETED = "RUN_COMPLETED"
RUN_ABORTED = "RUN_ABORTED"
RUN_FROZEN = "RUN_FROZEN"
# 循环与步骤
LOOP_STARTED = "LOOP_STARTED"
LOOP_COMPLETED = "LOOP_COMPLETED"
STEP_DISPATCHED = "STEP_DISPATCHED"
STEP_LEASE_RENEWED = "STEP_LEASE_RENEWED"
STEP_LEASE_EXPIRED = "STEP_LEASE_EXPIRED"
STEP_STARTED = "STEP_STARTED"
STEP_OUTPUT = "STEP_OUTPUT"
STEP_SUCCEEDED = "STEP_SUCCEEDED"
STEP_FAILED = "STEP_FAILED"
STEP_TIMED_OUT = "STEP_TIMED_OUT"
STEP_RETRYING = "STEP_RETRYING"
STEP_CANCELLED = "STEP_CANCELLED"
# 检查点
CHECKPOINT_SAVED = "CHECKPOINT_SAVED"
CHECKPOINT_RESUMED = "CHECKPOINT_RESUMED"
# 心跳与双通道观测
HEARTBEAT_DEGRADED = "HEARTBEAT_DEGRADED"
HEARTBEAT_LOST = "HEARTBEAT_LOST"
HEARTBEAT_RECOVERED = "HEARTBEAT_RECOVERED"
OOB_OBSERVATION = "OOB_OBSERVATION"
OOB_POWER_STATE = "OOB_POWER_STATE"
# 恢复
RECOVERY_STARTED = "RECOVERY_STARTED"
RECOVERY_ESCALATED = "RECOVERY_ESCALATED"
RECOVERY_SUCCEEDED = "RECOVERY_SUCCEEDED"
RECOVERY_FAILED = "RECOVERY_FAILED"
# 设备与数据
DUT_ENUMERATION_LOST = "DUT_ENUMERATION_LOST"
DUT_ENUMERATION_RESTORED = "DUT_ENUMERATION_RESTORED"
INTEGRITY_MISMATCH = "INTEGRITY_MISMATCH"
# 安全与资源
SAFETY_APPROVED = "SAFETY_APPROVED"
SAFETY_REJECTED = "SAFETY_REJECTED"
LOCK_ACQUIRED = "LOCK_ACQUIRED"
LOCK_RELEASED = "LOCK_RELEASED"
# 人与产物
HUMAN_TOUCH = "HUMAN_TOUCH" # 每一次人工介入都记 —— UCR 的分母来源
FAILURE_SIGNED = "FAILURE_SIGNED"
EVIDENCE_BUNDLED = "EVIDENCE_BUNDLED"
class StepType(StrEnum):
COMMAND = "command"
DEVICE_CHECK = "device_check"
WAIT = "wait"
LOOP = "loop"
PRECHECK = "precheck"
REPORT = "report"
class OnFail(StrEnum):
RETRY = "retry"
FAIL_RUN = "fail_run"
CONTINUE = "continue"
FREEZE = "freeze"
RECOVER = "recover"