Issue #1634 happened because GuestRRDPoint declared memused/memavailable
columns that real PVE guest rrddata responses never contain (they exist
only in node RRD), and every test mocked the fictional columns, so CI
validated the assumption instead of the API.
Add recorded fixtures for the guest and node rrddata endpoints in both
generations: PVE 9 responses captured live from a pve-manager 9.2.3
cluster via pvesh, and PVE 8 responses recovered from the host's
pre-migration pve2-vm/pve2-node RRD databases, serialized the way
PVE::RRD::create_rrd_data emits them. Decode tests in pkg/proxmox now
replay these recordings through the real client and fail whenever a
NodeRRDPoint or GuestRRDPoint field references a column absent from
every recorded response; the two known-dead guest fields are held in an
explicit allowlist that also fails if they are removed or ever start
appearing in recordings.
Companion to 7d7d2b6a3, which restored the LXC listing fallback.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Recorded Proxmox RRD API fixtures
Real rrddata responses recorded from Proxmox VE hosts, wrapped in the
{"data": [...]} envelope exactly as the HTTP API returns them. They exist so
that the decode tests in issue1634_rrd_fixture_test.go validate our parsing
structs against what PVE actually sends, not against hand-written mocks
(issue #1634 happened because every test mocked memused/memavailable
columns that real guest responses never contain).
PVE 9 fixtures (recorded live)
Captured 2026-07-27 from a live two-node cluster running pve-manager 9.2.3
via pvesh get ... --output-format json on node minipc, then trimmed to a
dozen rows while preserving the full column set of the original response.
pve9_lxc_rrddata.json—/nodes/minipc/lxc/108/rrddata --timeframe hour --cf AVERAGE(running container). Note memory is reported as cache-inclusivemem/maxmem; there is nomemused/memavailablein guest RRD.pve9_qemu_rrddata.json—/nodes/minipc/qemu/100/rrddata --timeframe year --cf AVERAGE. The only QEMU VM on the cluster was stopped, so the hour window carried no memory samples; the year window includes rows from when it last ran. The column schema (pve-vm-9.0) is identical across timeframes. Two sparse rows (stopped periods) are kept deliberately: PVE omits keys for absent samples rather than sending nulls.memhostis the PVE 9 QEMU host-side memory column; it also is notmemused/memavailable.pve9_node_rrddata.json—/nodes/minipc/rrddata --timeframe hour --cf AVERAGE. Node RRD is the only placememtotal/memused/memavailableexist.
PVE 8 fixtures (recovered from pre-migration RRD files)
The same host was upgraded from PVE 8; the upgrade renames the old RRD
databases (pve2-vm/<vmid>.old, pve2-node/<node>.old) instead of deleting
them. These fixtures were recovered 2026-07-27 from those files with
RRDs::fetch(..., "AVERAGE") and serialized the same way
PVE::RRD::create_rrd_data does (columns with NaN samples omitted), i.e. the
shape a PVE 8 API would have returned for the recorded data. The column sets
are the data-source names of the actual PVE 8 RRD schemas, not a guess.
pve8_guest_rrddata.json— frompve2-vm/100.old. PVE 8 serves both/lxc/{vmid}/rrddataand/qemu/{vmid}/rrddatafrom this samepve2-vmschema, so one guest fixture covers both endpoints. No pressure columns, nomemhost, and — as on PVE 9 — nomemused/memavailable.pve8_node_rrddata.json— frompve2-node/minipc.old. PVE 8 node RRD hasmemtotal/memusedbut nomemavailable(added in PVE 9), which is whyNodeRRDPoint.MemAvailablemust stay an optional pointer.