Files
napalm-proxmox/tests/conftest.py
2026-05-29 09:24:39 +02:00

218 lines
5.7 KiB
Python

"""Shared fixtures and mock helpers for napalm-proxmox tests."""
from __future__ import annotations
import pytest
from unittest.mock import MagicMock, patch
from napalm_proxmox.driver import ProxmoxDriver
# ---------------------------------------------------------------------------
# Sample API payloads
# ---------------------------------------------------------------------------
NODE_STATUS = {
"uptime": 123456,
"model": "PowerEdge R640",
"cpu": 0.12,
"memory": {"total": 137438953472, "used": 68719476736},
}
VERSION_INFO = {"version": "8.2.4", "release": "8", "repoid": "abc123"}
NODE_NETWORK = [
{
"iface": "eth0",
"type": "eth",
"active": 1,
"autostart": 1,
"hwaddr": "aa:bb:cc:dd:ee:01",
"speed": 1000,
"mtu": 1500,
"address": "10.0.0.1",
"netmask": "255.255.255.0",
"comments": "Management",
},
{
"iface": "eth1",
"type": "eth",
"active": 1,
"autostart": 1,
"hwaddr": "aa:bb:cc:dd:ee:02",
"speed": 10000,
"mtu": 9000,
"comments": "",
},
{
"iface": "vmbr0",
"type": "bridge",
"active": 1,
"autostart": 1,
"hwaddr": "aa:bb:cc:dd:ee:03",
"speed": None,
"mtu": 1500,
"address": "192.168.1.1",
"netmask": "255.255.255.0",
"comments": "Linux bridge",
},
{
"iface": "vmbr1",
"type": "OVSBridge",
"active": 0,
"autostart": 1,
"hwaddr": "",
"speed": None,
"mtu": 1500,
"comments": "OVS bridge",
},
]
SDN_ZONES = [
{"zone": "zone-vlan", "type": "vlan", "nodes": "pve1"},
{"zone": "zone-vxlan", "type": "vxlan", "nodes": "pve1,pve2", "vrf-vxlan": 10000},
{"zone": "zone-evpn", "type": "evpn", "nodes": "pve1,pve2", "vrf-vxlan": 10001},
]
SDN_VNETS = [
{"vnet": "vnet0", "zone": "zone-vlan", "tag": 10},
{"vnet": "vnet1", "zone": "zone-vlan", "tag": 20},
{"vnet": "vnet2", "zone": "zone-vxlan", "tag": 100000},
]
SDN_SUBNETS_VNET0 = [
{"cidr": "10.10.0.0/24", "gateway": "10.10.0.1", "vnet": "vnet0"},
]
SDN_SUBNETS_VNET1 = [
{"cidr": "10.20.0.0/24", "gateway": "10.20.0.1", "vnet": "vnet1"},
{"cidr": "2001:db8:20::/64", "gateway": "2001:db8:20::1", "vnet": "vnet1"},
]
SDN_SUBNETS_VNET2: list = []
DNS_INFO = {"search": "pve1.example.com", "dns1": "8.8.8.8"}
NTP_INFO = {"server": "pool.ntp.org,time.cloudflare.com"}
NODE_NETSTAT = [
{
"dev": "eth0",
"rx_bytes": 1000000,
"tx_bytes": 500000,
"rx_packets": 1000,
"tx_packets": 900,
"rx_errs": 0,
"tx_errs": 0,
"rx_drop": 0,
"tx_drop": 1,
}
]
NODES_LIST = [{"node": "pve1", "status": "online"}]
PVE_USERS = [
{"userid": "root@pam", "groups": ""},
{"userid": "napalm@pam", "groups": ""},
]
# ---------------------------------------------------------------------------
# Driver fixture
# ---------------------------------------------------------------------------
def _build_mock_api(
nodes=None,
node_status=None,
version=None,
network=None,
sdn_zones=None,
sdn_vnets=None,
sdn_subnets=None,
dns=None,
ntp=None,
netstat=None,
pve_users=None,
exec_return="",
sensors=None,
):
"""Build a MagicMock ProxmoxAPI with pre-configured return values."""
api = MagicMock()
# Nodes list
api.nodes.get.return_value = nodes or NODES_LIST
# Version
api.version.get.return_value = version or VERSION_INFO
# Node sub-resource
node_res = MagicMock()
api.nodes.return_value = node_res
node_res.status.get.return_value = node_status or NODE_STATUS
node_res.network.get.return_value = network if network is not None else NODE_NETWORK
node_res.dns.get.return_value = dns or DNS_INFO
node_res.ntp.get.return_value = ntp or NTP_INFO
node_res.netstat.get.return_value = netstat or NODE_NETSTAT
node_res.execute.post.return_value = {"data": exec_return}
node_res.hardware.sensors.get.return_value = sensors or []
node_res.time.get.return_value = {}
node_res.subscription.get.return_value = {}
# SDN
cluster = MagicMock()
api.cluster = cluster
cluster.sdn.zones.get.return_value = sdn_zones or SDN_ZONES
cluster.sdn.vnets.get.return_value = sdn_vnets or SDN_VNETS
# SDN subnets per vnet
subnets_map = sdn_subnets or {
"vnet0": SDN_SUBNETS_VNET0,
"vnet1": SDN_SUBNETS_VNET1,
"vnet2": SDN_SUBNETS_VNET2,
}
def _vnet_resource(vnet_id):
vnet_res = MagicMock()
vnet_res.subnets.get.return_value = subnets_map.get(vnet_id, [])
return vnet_res
cluster.sdn.vnets.side_effect = _vnet_resource
# Access / users
api.access.users.get.return_value = pve_users or PVE_USERS
api.access.users.return_value.get.return_value = {}
return api
@pytest.fixture
def driver():
"""Return an open ProxmoxDriver with a mocked API."""
drv = ProxmoxDriver(
hostname="pve1.example.com",
username="root",
password="secret",
optional_args={"verify_ssl": False, "realm": "pam"},
)
mock_api = _build_mock_api()
with patch("napalm_proxmox.driver.ProxmoxAPI", return_value=mock_api):
drv.open()
return drv
@pytest.fixture
def driver_with_exec(request):
"""Return a driver whose exec endpoint returns a parametrised string."""
exec_output = getattr(request, "param", "")
drv = ProxmoxDriver(
hostname="pve1.example.com",
username="root",
password="secret",
optional_args={"verify_ssl": False},
)
mock_api = _build_mock_api(exec_return=exec_output)
with patch("napalm_proxmox.driver.ProxmoxAPI", return_value=mock_api):
drv.open()
return drv