argus-netconf-exporter/tests/test_h3c_live_netconf.py
2025-11-28 14:35:21 +08:00

107 lines
3.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
"""
与真实 H3C 设备联调的“活体”测试用例。
说明:
- 连接参数参考 exp/yangcli/run_yangcli.sh
- server=127.0.0.1
- ncport=8830
- user=netconf_user
- password='...'
- 为避免在仓库中硬编码明文密码,本测试通过环境变量注入密码:
- H3C_NETCONF_PASSWORD
- 可选H3C_NETCONF_HOST / H3C_NETCONF_PORT / H3C_NETCONF_USER
默认行为:
- 若未设置 H3C_NETCONF_PASSWORD或无法建立到指定 host:port 的 TCP 连接,
则使用 pytest.skip() 自动跳过,不影响普通单元测试/CI。
- 仅在本地联调时、显式设置上述环境变量后,此测试才会真正访问设备。
"""
import os
import re
import socket
from pathlib import Path
import pytest
from ncclient import manager
from exporter.netconf_client import build_transceiver_filter, parse_netconf_response
H3C_HOST = os.getenv("H3C_NETCONF_HOST", "127.0.0.1")
H3C_PORT = int(os.getenv("H3C_NETCONF_PORT", "8830"))
H3C_USER = os.getenv("H3C_NETCONF_USER", "netconf_user")
def _load_password_from_script() -> str:
"""
尝试从 exp/yangcli 下的脚本中解析 --password='...'.
这样可以重用你已经验证过的 yangcli 参数,而不在测试里硬编码密码。
若脚本不存在或未找到 password则返回空字符串。
"""
root = Path(__file__).resolve().parents[1]
candidates = [
root / "exp" / "yangcli" / "run_yangcli_h3c.sh",
root / "exp" / "yangcli" / "run_yangcli.sh",
]
pattern = re.compile(r"--password='([^']*)'")
for path in candidates:
if not path.exists():
continue
text = path.read_text(encoding="utf-8")
match = pattern.search(text)
if match:
return match.group(1)
return ""
H3C_PASSWORD = os.getenv("H3C_NETCONF_PASSWORD") or _load_password_from_script()
def _can_connect(host: str, port: int, timeout: float = 2.0) -> bool:
"""快速探测 host:port 是否可连,用于决定是否跳过 live 测试。"""
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.settimeout(timeout)
sock.connect((host, port))
return True
except OSError:
return False
finally:
sock.close()
@pytest.mark.h3c_live
def test_h3c_live_transceiver_rpc_and_parse() -> None:
"""
使用真实 H3C 设备验证:
- ncclient 能与设备建立 NETCONF 会话;
- build_transceiver_filter() 构造的 subtree filter 在设备上可用;
- parse_netconf_response() 能正确解析设备返回的 XML并得到非空结果。
"""
if not _can_connect(H3C_HOST, H3C_PORT):
pytest.skip(f"H3C NETCONF {H3C_HOST}:{H3C_PORT} 不可达,跳过 live 测试")
flt = build_transceiver_filter()
with manager.connect(
host=H3C_HOST,
port=H3C_PORT,
username=H3C_USER,
password=H3C_PASSWORD,
hostkey_verify=False,
timeout=30,
allow_agent=False,
look_for_keys=False,
) as m:
reply = m.get(filter=("subtree", flt))
xml_str = str(reply)
transceivers, channels = parse_netconf_response(xml_str, device_name=f"h3c-{H3C_HOST}")
# 只要返回非空结果,就说明“连接 + filter + 解析”在真实设备上可以工作
assert transceivers or channels, "H3C 设备未返回任何 transceiver/channel 数据"