Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015a8P6WMRPeqdpd5VCh6jAy
93 lines
3.3 KiB
Go
93 lines
3.3 KiB
Go
package engine
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"pve-confsync/internal/model"
|
|
)
|
|
|
|
func keys(p Plan) []string {
|
|
var out []string
|
|
for _, c := range p.Changes {
|
|
out = append(out, c.Key())
|
|
}
|
|
return out
|
|
}
|
|
|
|
func TestFilterDependencies(t *testing.T) {
|
|
p := Plan{Client: "c", Changes: []Change{
|
|
{Kind: model.KindZone, ID: "z1", Op: OpCreate, Set: map[string]any{"type": "vlan"}},
|
|
{Kind: model.KindZone, ID: "z2", Op: OpUpdate, Set: map[string]any{"mtu": 1500}},
|
|
{Kind: model.KindVNet, ID: "v1", Op: OpCreate, Set: map[string]any{"zone": "z1"}},
|
|
{Kind: model.KindVNet, ID: "v2", Op: OpCreate, Set: map[string]any{"zone": "z2"}},
|
|
{Kind: model.KindSubnet, ID: "z1-10.0.0.0-24", Op: OpCreate, Set: map[string]any{"vnet": "v1"}},
|
|
}}
|
|
got := keys(Filter(p, []string{"sdn-subnet/z1-10.0.0.0-24"}))
|
|
want := []string{"sdn-zone/z1", "sdn-vnet/v1", "sdn-subnet/z1-10.0.0.0-24"}
|
|
if len(got) != len(want) {
|
|
t.Fatalf("got %v, want %v", got, want)
|
|
}
|
|
for i := range want {
|
|
if got[i] != want[i] {
|
|
t.Fatalf("got %v, want %v (plan order kept)", got, want)
|
|
}
|
|
}
|
|
// an update of the parent zone is not pulled in
|
|
if got := keys(Filter(p, []string{"sdn-vnet/v2"})); len(got) != 1 {
|
|
t.Fatalf("got %v, want only the vnet", got)
|
|
}
|
|
// unknown keys select nothing; no keys select everything
|
|
if got := Filter(p, []string{"sdn-vnet/nope"}); len(got.Changes) != 0 {
|
|
t.Fatalf("unknown key selected %v", keys(got))
|
|
}
|
|
if got := Filter(p, nil); len(got.Changes) != len(p.Changes) {
|
|
t.Fatal("empty selection must keep the whole plan")
|
|
}
|
|
}
|
|
|
|
func TestFilterDeleteChildrenFirst(t *testing.T) {
|
|
p := Plan{Changes: []Change{
|
|
{Kind: model.KindSubnet, ID: "z-10.0.0.0-24", Op: OpDelete, Old: map[string]any{"vnet": "v"}},
|
|
{Kind: model.KindVNet, ID: "v", Op: OpDelete, Old: map[string]any{"zone": "z"}},
|
|
{Kind: model.KindVNet, ID: "other", Op: OpDelete, Old: map[string]any{"zone": "y"}},
|
|
{Kind: model.KindZone, ID: "z", Op: OpDelete},
|
|
}}
|
|
got := keys(Filter(p, []string{"sdn-zone/z"}))
|
|
if len(got) != 3 || got[2] != "sdn-zone/z" {
|
|
t.Fatalf("got %v", got)
|
|
}
|
|
}
|
|
|
|
func TestFilterErrors(t *testing.T) {
|
|
p := Plan{
|
|
Changes: []Change{
|
|
{Kind: model.KindVNet, ID: "ceph", Op: OpCreate, Set: map[string]any{"zone": "stor"}},
|
|
{Kind: model.KindVNet, ID: "vx1", Op: OpCreate, Set: map[string]any{"zone": "vxz"}},
|
|
},
|
|
Errors: []string{`sdn-zone/stor: field "bridge" required`, "sdn-subnet/z-fd00::-64: bad", "global problem"},
|
|
}
|
|
if got := Filter(p, []string{"sdn-vnet/vx1"}); len(got.Errors) != 1 || got.Errors[0] != "global problem" {
|
|
t.Fatalf("vx1: errors %v", got.Errors)
|
|
}
|
|
// the zone of ceph cannot be created: its error blocks ceph
|
|
if got := Filter(p, []string{"sdn-vnet/ceph"}); len(got.Errors) != 2 {
|
|
t.Fatalf("ceph: errors %v", got.Errors)
|
|
}
|
|
if k, ok := ErrorKey("sdn-subnet/z-fd00::-64: bad"); !ok || k != "sdn-subnet/z-fd00::-64" {
|
|
t.Fatalf("ErrorKey IPv6: %q %v", k, ok)
|
|
}
|
|
}
|
|
|
|
func TestDigest(t *testing.T) {
|
|
a := Plan{Client: "c", Changes: []Change{{Kind: model.KindZone, ID: "z", Op: OpUpdate, Set: map[string]any{"mtu": 1500}}}}
|
|
b := Plan{Client: "c", Changes: []Change{{Kind: model.KindZone, ID: "z", Op: OpUpdate, Set: map[string]any{"mtu": 9000}}}}
|
|
if a.Digest() == b.Digest() {
|
|
t.Fatal("different plans, same digest")
|
|
}
|
|
a2 := a
|
|
a2.Warnings = []string{"w"}
|
|
if a.Digest() != a2.Digest() {
|
|
t.Fatal("warnings must not change the digest")
|
|
}
|
|
}
|