proxmox: config block, IDs, marks, state mapping, classify, registration
Phase 2 of the proxmox provider plan. Adds the proxmox: config block with its validation, registers the type in the config allow-list and the constructor map, and starts internal/provider/proxmox: the api seam and its data types, providerIDs (vms/<vmid>/<name>) with the UID-derived VMID, the description mark, state mapping, and error classification. Tests read the responses captured from pv1-1 in Phase 0 rather than repeating Proxmox's wording, and every matcher is run against every captured error so none fires on the wrong message. The contract methods are Transient stubs until Phases 5 to 7. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
package proxmox
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestFormatDescription_keys(t *testing.T) {
|
||||
t.Parallel()
|
||||
created := time.Date(2026, 9, 23, 8, 0, 0, 0, time.FixedZone("CEST", 2*3600))
|
||||
got := formatDescription("3f1c2d7e-uid", created)
|
||||
want := "proxy-operator-managed=true\nproxy-operator-uid=3f1c2d7e-uid\nproxy-operator-created-at=2026-09-23T06:00:00Z"
|
||||
if got != want {
|
||||
t.Errorf("formatDescription() =\n%s\nwant\n%s", got, want)
|
||||
}
|
||||
m := parseDescription(got)
|
||||
if !m.Managed || m.UID != "3f1c2d7e-uid" || !m.CreatedAt.Equal(created) {
|
||||
t.Errorf("parseDescription(formatDescription()) = %+v, want managed, the UID and the time back", m)
|
||||
}
|
||||
}
|
||||
|
||||
// TestParseDescription_fromClone reads the mark back from the config of the
|
||||
// VM cloned in Phase 0, as Proxmox stored it.
|
||||
func TestParseDescription_fromClone(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := decodeData[map[string]any](t, "vm_config_clone")
|
||||
desc, _ := cfg["description"].(string)
|
||||
m := parseDescription(desc)
|
||||
want := time.Date(2026, 9, 23, 7, 0, 0, 0, time.UTC)
|
||||
if !m.Managed || m.UID != "00000000-0000-0000-0000-00000000recon" || !m.CreatedAt.Equal(want) {
|
||||
t.Errorf("parseDescription(captured) = %+v, want the recon mark", m)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseDescription_table(t *testing.T) {
|
||||
t.Parallel()
|
||||
ts := time.Date(2026, 9, 23, 7, 0, 0, 0, time.UTC)
|
||||
tests := []struct {
|
||||
name string
|
||||
desc string
|
||||
want instanceMark
|
||||
}{
|
||||
{name: "empty", desc: "", want: instanceMark{}},
|
||||
{name: "unmarked free text", desc: "Ubuntu VM for testing", want: instanceMark{}},
|
||||
{name: "managed with UID", desc: "proxy-operator-managed=true\nproxy-operator-uid=u1\nproxy-operator-created-at=2026-09-23T07:00:00Z", want: instanceMark{Managed: true, UID: "u1", CreatedAt: ts}},
|
||||
{name: "managed with empty UID", desc: "proxy-operator-managed=true\nproxy-operator-uid=", want: instanceMark{Managed: true}},
|
||||
{name: "managed without UID line", desc: "proxy-operator-managed=true", want: instanceMark{Managed: true}},
|
||||
{name: "managed value must be exactly true", desc: "proxy-operator-managed=yes\nproxy-operator-uid=u1", want: instanceMark{UID: "u1"}},
|
||||
{name: "unparsable created-at gives zero time", desc: "proxy-operator-managed=true\nproxy-operator-created-at=yesterday", want: instanceMark{Managed: true}},
|
||||
{name: "CRLF line endings", desc: "proxy-operator-managed=true\r\nproxy-operator-uid=u1\r\n", want: instanceMark{Managed: true, UID: "u1"}},
|
||||
{name: "admin lines kept around the mark", desc: "owner: team-crawl\n\nproxy-operator-managed=true\nnote=do not touch\nproxy-operator-uid=u1", want: instanceMark{Managed: true, UID: "u1"}},
|
||||
{name: "first occurrence of a key wins", desc: "proxy-operator-uid=u1\nproxy-operator-uid=u2\nproxy-operator-managed=true", want: instanceMark{Managed: true, UID: "u1"}},
|
||||
{name: "surrounding spaces trimmed", desc: " proxy-operator-managed=true \n proxy-operator-uid=u1", want: instanceMark{Managed: true, UID: "u1"}},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := parseDescription(tc.desc)
|
||||
if got.Managed != tc.want.Managed || got.UID != tc.want.UID || !got.CreatedAt.Equal(tc.want.CreatedAt) {
|
||||
t.Errorf("parseDescription(%q) = %+v, want %+v", tc.desc, got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user