fix: 修复环路检测失败 + 多项UX增强
修复: - 环路检测正则 \s+(Onu\S+)\s+ → \s+(Onu\S+) (splitlines移除换行后尾随\s无法匹配) - 权限中间件 Header(...) → Header(None) 避免缺失Auth头返回422而非401 - 环路检测请求超时30s→120s (SSH连接30+台OLT实测需58秒) 重构 (ssh_service.py): - 提取 _send_and_wait 为私有方法,消除3处重复内部函数 - 添加 __enter__/__exit__ 上下文管理器支持 - 加固 execute_command prompt检测 (按行匹配<DEVICE_NAME>) - 移除未使用的settings import - olt.py/devices.py 调用方改用 with 语法 新功能: - 侧边栏退出登录上方显示当前用户名和角色 - 版本号从VERSION文件自动读取 (后端/health返回,前端动态显示) - 基于广西南宁经纬度计算日落时间,自动切换深色/浅色主题 - /api/olt/loopback-detection 响应增加raw字段便于排查 基础设施: - CLAUDE.md 加入 .gitignore - 新增 .claude/rules/07-remote-operations.md (远程部署操作) - 新增 .claude/rules/08-frp-notes.md (frp隧道注意事项) - 新增 VERSION 文件 (版本号 0.10.0) - 新增环路检测解析测试用例 (5个) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
"""SSH 输出解析测试"""
|
||||
import re
|
||||
import pytest
|
||||
from app.services.ssh_service import SSHService
|
||||
|
||||
@@ -91,3 +92,71 @@ class TestCleanOutput:
|
||||
cleaned = svc._clean_output(output)
|
||||
assert "1484-778f-aa60" in cleaned
|
||||
assert "---- More ----" not in cleaned
|
||||
|
||||
|
||||
class TestDetectLoopback:
|
||||
"""环路检测输出解析测试"""
|
||||
|
||||
def _parse(self, output: str):
|
||||
"""模拟 detect_loopback 中的解析逻辑"""
|
||||
has_loop = "Loop is detected on following interfaces" in output
|
||||
interfaces = []
|
||||
if has_loop:
|
||||
for line in output.splitlines():
|
||||
m = re.match(r'\s+(Onu\S+)', line)
|
||||
if m:
|
||||
interfaces.append(m.group(1))
|
||||
return has_loop, interfaces
|
||||
|
||||
def test_no_loop(self):
|
||||
output = """
|
||||
Loopback detection is enabled.
|
||||
Loopback detection interval is 30 second(s).
|
||||
No loopback is detected.
|
||||
"""
|
||||
has_loop, interfaces = self._parse(output)
|
||||
assert not has_loop
|
||||
assert interfaces == []
|
||||
|
||||
def test_has_loop_single(self):
|
||||
output = """
|
||||
Loopback detection is enabled.
|
||||
Loopback detection interval is 30 second(s).
|
||||
Loop is detected on following interfaces:
|
||||
Onu1/0/1:1
|
||||
"""
|
||||
has_loop, interfaces = self._parse(output)
|
||||
assert has_loop
|
||||
assert interfaces == ["Onu1/0/1:1"]
|
||||
|
||||
def test_has_loop_multiple(self):
|
||||
output = """
|
||||
Loop is detected on following interfaces:
|
||||
Onu1/0/1:1
|
||||
Onu1/0/2:3
|
||||
Onu2/0/5:10
|
||||
"""
|
||||
has_loop, interfaces = self._parse(output)
|
||||
assert has_loop
|
||||
assert interfaces == ["Onu1/0/1:1", "Onu1/0/2:3", "Onu2/0/5:10"]
|
||||
|
||||
def test_has_loop_with_extra_whitespace(self):
|
||||
"""接口行有多余空白字符"""
|
||||
output = """
|
||||
Loop is detected on following interfaces:
|
||||
Onu1/0/1:1
|
||||
"""
|
||||
has_loop, interfaces = self._parse(output)
|
||||
assert has_loop
|
||||
assert interfaces == ["Onu1/0/1:1"]
|
||||
|
||||
def test_no_false_positive_on_prompt(self):
|
||||
"""确保设备提示符不被误识别为接口"""
|
||||
output = """
|
||||
Loop is detected on following interfaces:
|
||||
Onu1/0/1:1
|
||||
<H3C_Device>
|
||||
"""
|
||||
has_loop, interfaces = self._parse(output)
|
||||
assert has_loop
|
||||
assert interfaces == ["Onu1/0/1:1"]
|
||||
|
||||
Reference in New Issue
Block a user