package proxmox import ( "testing" "gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator/internal/provider" ) func TestMapState_table(t *testing.T) { t.Parallel() tests := []struct { status, qmp, ip string want provider.InstanceState }{ {"running", "running", "192.168.4.147", provider.StateRunning}, {"running", "running", "", provider.StateProvisioning}, {"running", "", "192.168.4.147", provider.StateRunning}, {"running", "", "", provider.StateProvisioning}, {"running", "prelaunch", "", provider.StateProvisioning}, {"running", "paused", "192.168.4.147", provider.StateStopped}, {"running", "suspended", "", provider.StateStopped}, {"running", "io-error", "", provider.StateStopped}, {"running", "something-new", "", provider.StateStopped}, {"stopped", "stopped", "", provider.StateStopped}, {"stopped", "", "", provider.StateStopped}, {"unknown", "", "", provider.StateStopped}, {"", "", "", provider.StateStopped}, } for _, tc := range tests { t.Run(tc.status+"/"+tc.qmp+"/"+tc.ip, func(t *testing.T) { t.Parallel() if got := mapState(tc.status, tc.qmp, tc.ip); got != tc.want { t.Errorf("mapState(%q, %q, %q) = %q, want %q", tc.status, tc.qmp, tc.ip, got, tc.want) } }) } } // TestMapState_fromCaptures feeds status/current as Proxmox reported it for // a running, a stopped and a paused VM. func TestMapState_fromCaptures(t *testing.T) { t.Parallel() tests := []struct { capture string ip string want provider.InstanceState }{ {"status_current_running", "192.168.0.150", provider.StateRunning}, {"status_current_running", "", provider.StateProvisioning}, {"status_current_stopped", "", provider.StateStopped}, {"status_current_paused", "192.168.0.150", provider.StateStopped}, } for _, tc := range tests { t.Run(tc.capture+"/"+tc.ip, func(t *testing.T) { t.Parallel() s := decodeData[vmStatus](t, tc.capture) if got := mapState(s.Status, s.QMPStatus, tc.ip); got != tc.want { t.Errorf("mapState(%q, %q, %q) = %q, want %q", s.Status, s.QMPStatus, tc.ip, got, tc.want) } }) } } func TestFirstIPv4_filters(t *testing.T) { t.Parallel() ip := func(addr, typ string) agentIP { return agentIP{Address: addr, Type: typ} } tests := []struct { name string ifaces []agentInterface want string }{ {name: "none", want: ""}, {name: "loopback interface only", ifaces: []agentInterface{{Name: "lo", IPAddresses: []agentIP{ip("127.0.0.1", "ipv4")}}}, want: ""}, {name: "ipv6 only", ifaces: []agentInterface{{Name: "ens18", IPAddresses: []agentIP{ip("fe80::1", "ipv6"), ip("2001:db8::5", "ipv6")}}}, want: ""}, {name: "link-local skipped", ifaces: []agentInterface{{Name: "ens18", IPAddresses: []agentIP{ip("169.254.3.4", "ipv4"), ip("192.168.4.20", "ipv4")}}}, want: "192.168.4.20"}, {name: "unspecified skipped", ifaces: []agentInterface{{Name: "ens18", IPAddresses: []agentIP{ip("0.0.0.0", "ipv4")}}}, want: ""}, {name: "loopback address on another interface skipped", ifaces: []agentInterface{{Name: "dummy0", IPAddresses: []agentIP{ip("127.0.0.2", "ipv4")}}}, want: ""}, {name: "type and literal disagree", ifaces: []agentInterface{{Name: "ens18", IPAddresses: []agentIP{ip("fe80::1", "ipv4"), ip("10.0.0.9", "ipv6")}}}, want: ""}, {name: "unparsable skipped", ifaces: []agentInterface{{Name: "ens18", IPAddresses: []agentIP{ip("not-an-ip", "ipv4"), ip("10.0.0.9", "ipv4")}}}, want: "10.0.0.9"}, {name: "agent order decides", ifaces: []agentInterface{ {Name: "ens18", IPAddresses: []agentIP{ip("192.168.4.20", "ipv4")}}, {Name: "ens19", IPAddresses: []agentIP{ip("10.0.0.9", "ipv4")}}, }, want: "192.168.4.20"}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { t.Parallel() if got := firstIPv4(tc.ifaces); got != tc.want { t.Errorf("firstIPv4() = %q, want %q", got, tc.want) } }) } } // TestFirstIPv4_fromCaptures reads the guest agent's answer from the two // Phase 0 runs, untagged and on VLAN 4. func TestFirstIPv4_fromCaptures(t *testing.T) { t.Parallel() tests := map[string]string{ "agent_network_get_interfaces": "192.168.0.150", "agent_network_get_interfaces_vlan": "192.168.4.147", } for capture, want := range tests { t.Run(capture, func(t *testing.T) { t.Parallel() res := decodeData[struct { Result []agentInterface `json:"result"` }](t, capture) if got := firstIPv4(res.Result); got != want { t.Errorf("firstIPv4(%s) = %q, want %q", capture, got, want) } }) } }