163 lines
4.4 KiB
Go
163 lines
4.4 KiB
Go
package kvm2
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator/internal/provider"
|
|
)
|
|
|
|
func TestMarshalInstanceMetadata_namespacedElement(t *testing.T) {
|
|
t.Parallel()
|
|
created := time.Date(2026, 9, 16, 10, 30, 0, 0, time.FixedZone("CEST", 2*3600))
|
|
got, err := marshalInstanceMetadata(newInstanceMetadata("uid-1", created))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, want := range []string{
|
|
`<instance xmlns="` + metadataURI + `">`,
|
|
"<managed>true</managed>",
|
|
"<uid>uid-1</uid>",
|
|
"<createdAt>2026-09-16T08:30:00Z</createdAt>",
|
|
"</instance>",
|
|
} {
|
|
if !strings.Contains(got, want) {
|
|
t.Errorf("marshalled metadata %q lacks %q", got, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseMetadata_withNamespace(t *testing.T) {
|
|
t.Parallel()
|
|
in := `<instance xmlns="` + metadataURI + `"><managed>true</managed><uid>abc</uid><createdAt>2026-09-16T08:30:00Z</createdAt></instance>`
|
|
m, err := parseInstanceMetadata(in)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !m.managed() {
|
|
t.Error("managed() = false, want true")
|
|
}
|
|
if m.UID != "abc" {
|
|
t.Errorf("UID = %q, want abc", m.UID)
|
|
}
|
|
if want := time.Date(2026, 9, 16, 8, 30, 0, 0, time.UTC); !m.createdAt().Equal(want) {
|
|
t.Errorf("createdAt() = %v, want %v", m.createdAt(), want)
|
|
}
|
|
}
|
|
|
|
func TestParseMetadata_withoutNamespaceDeclaration(t *testing.T) {
|
|
t.Parallel()
|
|
in := "<instance>\n <managed>true</managed>\n <uid>abc</uid>\n <createdAt>2026-09-16T08:30:00Z</createdAt>\n</instance>"
|
|
m, err := parseInstanceMetadata(in)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !m.managed() || m.UID != "abc" {
|
|
t.Errorf("got managed=%v uid=%q, want true/abc", m.managed(), m.UID)
|
|
}
|
|
if m.createdAt().IsZero() {
|
|
t.Error("createdAt() is zero, want parsed timestamp")
|
|
}
|
|
}
|
|
|
|
func TestParseMetadata_absentGivesEmptyUID(t *testing.T) {
|
|
t.Parallel()
|
|
tests := []struct {
|
|
name string
|
|
in string
|
|
}{
|
|
{name: "empty element", in: "<instance/>"},
|
|
{name: "empty element with namespace", in: `<instance xmlns="` + metadataURI + `"></instance>`},
|
|
{name: "empty children", in: "<instance><managed></managed><uid></uid><createdAt></createdAt></instance>"},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
m, err := parseInstanceMetadata(tc.in)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if m.managed() {
|
|
t.Error("managed() = true, want false")
|
|
}
|
|
if m.UID != "" {
|
|
t.Errorf("UID = %q, want empty", m.UID)
|
|
}
|
|
if !m.createdAt().IsZero() {
|
|
t.Errorf("createdAt() = %v, want zero", m.createdAt())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParseMetadata_badCreatedAtIsZeroTime(t *testing.T) {
|
|
t.Parallel()
|
|
tests := []struct {
|
|
name string
|
|
in string
|
|
}{
|
|
{name: "garbage", in: "<instance><managed>true</managed><uid>u</uid><createdAt>yesterday</createdAt></instance>"},
|
|
{name: "date only", in: "<instance><managed>true</managed><uid>u</uid><createdAt>2026-09-16</createdAt></instance>"},
|
|
{name: "missing", in: "<instance><managed>true</managed><uid>u</uid></instance>"},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
m, err := parseInstanceMetadata(tc.in)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !m.createdAt().IsZero() {
|
|
t.Errorf("createdAt() = %v, want zero", m.createdAt())
|
|
}
|
|
if !m.managed() || m.UID != "u" {
|
|
t.Errorf("other fields lost: managed=%v uid=%q", m.managed(), m.UID)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParseMetadata_notXMLIsPermanent(t *testing.T) {
|
|
t.Parallel()
|
|
tests := []struct {
|
|
name string
|
|
in string
|
|
}{
|
|
{name: "empty string", in: ""},
|
|
{name: "whitespace", in: " \n"},
|
|
{name: "plain text", in: "managed: true"},
|
|
{name: "unclosed element", in: "<instance><managed>true"},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := parseInstanceMetadata(tc.in)
|
|
if !errors.Is(err, provider.ErrPermanent) {
|
|
t.Errorf("err = %v, want ErrPermanent", err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParseMetadata_wrongRootIsPermanent(t *testing.T) {
|
|
t.Parallel()
|
|
tests := []struct {
|
|
name string
|
|
in string
|
|
}{
|
|
{name: "other local name", in: "<proxy><managed>true</managed></proxy>"},
|
|
{name: "other local name with our namespace", in: `<vm xmlns="` + metadataURI + `"><uid>x</uid></vm>`},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := parseInstanceMetadata(tc.in)
|
|
if !errors.Is(err, provider.ErrPermanent) {
|
|
t.Errorf("err = %v, want ErrPermanent", err)
|
|
}
|
|
})
|
|
}
|
|
}
|