package kvm
import (
"encoding/xml"
"strings"
"testing"
"time"
)
func TestInstanceMetadata_roundTrip(t *testing.T) {
t.Parallel()
created := time.Date(2026, 9, 4, 12, 30, 0, 0, time.FixedZone("CEST", 2*3600))
raw, err := xml.Marshal(newInstanceMetadata("uid-1", created))
if err != nil {
t.Fatalf("Marshal() error = %v", err)
}
if !strings.Contains(string(raw), `xmlns="`+metadataURI+`"`) {
t.Errorf("marshalled metadata lacks the namespace declaration: %s", raw)
}
m, err := parseInstanceMetadata(string(raw))
if err != nil {
t.Fatalf("parseInstanceMetadata() error = %v", err)
}
if !m.managed() || m.UID != "uid-1" {
t.Errorf("parsed = %+v, want managed with uid-1", m)
}
if got := m.createdAt(); !got.Equal(created) || got.Location() != time.UTC {
t.Errorf("createdAt() = %v, want %v in UTC", got, created)
}
}
func TestParseInstanceMetadata_libvirtPrefixedForm(t *testing.T) {
t.Parallel()
// libvirt re-serialises the stored element with whatever prefix it
// chooses; only the namespace URI is contractual.
in := `` +
`trueuid-2` +
`2026-09-04T10:00:00Z`
m, err := parseInstanceMetadata(in)
if err != nil {
t.Fatalf("parseInstanceMetadata() error = %v", err)
}
if !m.managed() || m.UID != "uid-2" || m.createdAt().Hour() != 10 {
t.Errorf("parsed = %+v", m)
}
}
func TestParseInstanceMetadata_libvirtBareForm(t *testing.T) {
t.Parallel()
// What libvirt 11.6 actually returns from DomainGetMetadata: the element
// selected by our URI, serialised without any namespace declaration.
in := `trueuid-3` +
`2026-09-10T07:30:00Z`
m, err := parseInstanceMetadata(in)
if err != nil {
t.Fatalf("parseInstanceMetadata() error = %v", err)
}
if !m.managed() || m.UID != "uid-3" || m.createdAt().Minute() != 30 {
t.Errorf("parsed = %+v", m)
}
}
func TestParseInstanceMetadata_notManaged(t *testing.T) {
t.Parallel()
tests := []struct {
name string
in string
wantErr bool
}{
{"managed false", `falseu`, false},
{"foreign element", `true`, true},
{"garbage", `not xml`, true},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
m, err := parseInstanceMetadata(tc.in)
if (err != nil) != tc.wantErr {
t.Fatalf("error = %v, wantErr %v", err, tc.wantErr)
}
if m.managed() {
t.Errorf("managed() = true for %q", tc.in)
}
})
}
}
func TestInstanceMetadata_createdAtMalformedIsZero(t *testing.T) {
t.Parallel()
m := instanceMetadata{CreatedAt: "yesterday"}
if !m.createdAt().IsZero() {
t.Errorf("createdAt() = %v, want zero time", m.createdAt())
}
}