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) } }) } }