235 lines
6.7 KiB
Python
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"
|