diff options
-rw-r--r-- | libvirt/libvirt_domain_mock_test.go | 9 | ||||
-rw-r--r-- | libvirt/libvirt_interfaces.go | 7 | ||||
-rw-r--r-- | libvirt/qemu_agent.go | 25 | ||||
-rw-r--r-- | libvirt/qemu_agent_test.go | 196 |
4 files changed, 226 insertions, 11 deletions
diff --git a/libvirt/libvirt_domain_mock_test.go b/libvirt/libvirt_domain_mock_test.go new file mode 100644 index 00000000..9a4c0290 --- /dev/null +++ b/libvirt/libvirt_domain_mock_test.go @@ -0,0 +1,9 @@ +package libvirt + +type LibVirtDomainMock struct { + QemuAgentCommandResponse string +} + +func (d LibVirtDomainMock) QemuAgentCommand(cmd string, timeout int, flags uint32) string { + return d.QemuAgentCommandResponse +} diff --git a/libvirt/libvirt_interfaces.go b/libvirt/libvirt_interfaces.go new file mode 100644 index 00000000..f9d2f11a --- /dev/null +++ b/libvirt/libvirt_interfaces.go @@ -0,0 +1,7 @@ +package libvirt + +// Interface used to expose a libvirt.VirDomain +// Used to allow testing +type LibVirtDomain interface { + QemuAgentCommand(cmd string, timeout int, flags uint32) string +} diff --git a/libvirt/qemu_agent.go b/libvirt/qemu_agent.go index 5b87dbd5..946aa39f 100644 --- a/libvirt/qemu_agent.go +++ b/libvirt/qemu_agent.go @@ -13,13 +13,15 @@ type QemuAgentInterfacesResponse struct { } type QemuAgentInterface struct { - Name string `json:"name"` - Hwaddr string `json:"hardware-address"` - IpAddresses []struct { - Type string `json:"ip-address-type"` - Address string `json:"ip-address"` - Prefix uint `json:"prefix"` - } `json:"ip-addresses"` + Name string `json:"name"` + Hwaddr string `json:"hardware-address"` + IpAddresses []QemuAgentInterfaceIpAddress `json:"ip-addresses"` +} + +type QemuAgentInterfaceIpAddress struct { + Type string `json:"ip-address-type"` + Address string `json:"ip-address"` + Prefix uint `json:"prefix"` } // Retrieve all the interfaces attached to a domain and their addresses. Only @@ -27,7 +29,7 @@ type QemuAgentInterface struct { // When wait4ipv4 is turned on the code will not report interfaces that don't // have a ipv4 address set. This is useful when a domain gets the ipv6 address // before the ipv4 one. -func getDomainInterfacesViaQemuAgent(domain *libvirt.VirDomain, wait4ipv4 bool) []libvirt.VirDomainInterface { +func getDomainInterfacesViaQemuAgent(domain LibVirtDomain, wait4ipv4 bool) []libvirt.VirDomainInterface { log.Print("[DEBUG] get network interfaces using qemu agent") var interfaces []libvirt.VirDomainInterface @@ -54,9 +56,9 @@ func getDomainInterfacesViaQemuAgent(domain *libvirt.VirDomain, wait4ipv4 bool) continue } - libVirtIface := libvirt.VirDomainInterface{} - libVirtIface.Name = iface.Name - libVirtIface.Hwaddr = iface.Hwaddr + libVirtIface := libvirt.VirDomainInterface{ + Name: iface.Name, + Hwaddr: iface.Hwaddr} ipv4Assigned := false for _, addr := range iface.IpAddresses { @@ -78,6 +80,7 @@ func getDomainInterfacesViaQemuAgent(domain *libvirt.VirDomain, wait4ipv4 bool) libVirtAddr.Type = libvirt.VIR_IP_ADDR_TYPE_IPV6 default: log.Printf("[ERROR] Cannot handle unknown address type %s", addr.Type) + continue } libVirtIface.Addrs = append(libVirtIface.Addrs, libVirtAddr) } diff --git a/libvirt/qemu_agent_test.go b/libvirt/qemu_agent_test.go new file mode 100644 index 00000000..095af723 --- /dev/null +++ b/libvirt/qemu_agent_test.go @@ -0,0 +1,196 @@ +package libvirt + +import ( + "encoding/json" + "testing" + + libvirt "github.com/dmacvicar/libvirt-go" +) + +func TestGetDomainInterfacesViaQemuAgentInvalidResponse(t *testing.T) { + domain := LibVirtDomainMock{} + + interfaces := getDomainInterfacesViaQemuAgent(domain, false) + + if len(interfaces) != 0 { + t.Errorf("wrong number of interfaces: %d instead of 0", len(interfaces)) + } +} + +func TestGetDomainInterfacesViaQemuAgentNoInterfaces(t *testing.T) { + + response := QemuAgentInterfacesResponse{ + Interfaces: []QemuAgentInterface{}} + data, err := json.Marshal(response) + if err != nil { + t.Errorf("error: %v", err) + } + domain := LibVirtDomainMock{ + QemuAgentCommandResponse: string(data), + } + + interfaces := getDomainInterfacesViaQemuAgent(domain, false) + if len(interfaces) != 0 { + t.Errorf("wrong number of interfaces: %d instead of 0", len(interfaces)) + } +} + +func TestGetDomainInterfacesViaQemuAgentIgnoreLoopbackDevice(t *testing.T) { + response := QemuAgentInterfacesResponse{ + Interfaces: []QemuAgentInterface{ + QemuAgentInterface{ + Name: "lo", + Hwaddr: "ho:me", + IpAddresses: []QemuAgentInterfaceIpAddress{ + QemuAgentInterfaceIpAddress{ + Type: "ipv4", + Address: "127.0.0.1", + Prefix: 1, + }, + }, + }, + }, + } + data, err := json.Marshal(response) + if err != nil { + t.Errorf("error: %v", err) + } + domain := LibVirtDomainMock{ + QemuAgentCommandResponse: string(data), + } + + interfaces := getDomainInterfacesViaQemuAgent(domain, false) + + if len(interfaces) != 0 { + t.Errorf("wrong number of interfaces)") + } +} + +func TestGetDomainInterfacesViaQemuAgentIgnoreDevicesWithoutAddress(t *testing.T) { + response := QemuAgentInterfacesResponse{ + Interfaces: []QemuAgentInterface{ + QemuAgentInterface{ + Name: "eth1", + Hwaddr: "xy:yy:zz", + IpAddresses: []QemuAgentInterfaceIpAddress{ + QemuAgentInterfaceIpAddress{ + Type: "ipv4", + Address: "", + Prefix: 1, + }, + }, + }, + }, + } + data, err := json.Marshal(response) + if err != nil { + t.Errorf("error: %v", err) + } + domain := LibVirtDomainMock{ + QemuAgentCommandResponse: string(data), + } + + interfaces := getDomainInterfacesViaQemuAgent(domain, false) + + if len(interfaces) != 0 { + t.Errorf("wrong number of interfaces") + } +} + +func TestGetDomainInterfacesViaQemuAgentUnknownIpAddressType(t *testing.T) { + response := QemuAgentInterfacesResponse{ + Interfaces: []QemuAgentInterface{ + QemuAgentInterface{ + Name: "eth2", + Hwaddr: "zy:yy:zz", + IpAddresses: []QemuAgentInterfaceIpAddress{ + QemuAgentInterfaceIpAddress{ + Type: "ipv8", + Address: "i don't exist", + Prefix: 1, + }, + }, + }, + }, + } + data, err := json.Marshal(response) + if err != nil { + t.Errorf("error: %v", err) + } + domain := LibVirtDomainMock{ + QemuAgentCommandResponse: string(data), + } + + interfaces := getDomainInterfacesViaQemuAgent(domain, false) + + if len(interfaces) != 0 { + t.Errorf("wrong number of interfaces: %d instead of 1", len(interfaces)) + } +} + +func TestGetDomainInterfacesViaQemuAgent(t *testing.T) { + device := "eth0" + mac := "xx:yy:zz" + ipv4Addr := "192.168.1.1" + ipv6Addr := "2001:0db8:0000:0000:0000:ff00:0042:8329" + + response := QemuAgentInterfacesResponse{ + Interfaces: []QemuAgentInterface{ + QemuAgentInterface{ + Name: device, + Hwaddr: mac, + IpAddresses: []QemuAgentInterfaceIpAddress{ + QemuAgentInterfaceIpAddress{ + Type: "ipv4", + Address: ipv4Addr, + Prefix: 1, + }, + QemuAgentInterfaceIpAddress{ + Type: "ipv6", + Address: ipv6Addr, + Prefix: 1, + }, + }, + }, + }, + } + data, err := json.Marshal(response) + if err != nil { + t.Errorf("error: %v", err) + } + domain := LibVirtDomainMock{ + QemuAgentCommandResponse: string(data), + } + + interfaces := getDomainInterfacesViaQemuAgent(domain, false) + + if len(interfaces) != 1 { + t.Errorf("wrong number of interfaces: %d instead of 1", len(interfaces)) + } + + if interfaces[0].Name != device { + t.Errorf("wrong interface name: %s", interfaces[0].Name) + } + + if interfaces[0].Hwaddr != mac { + t.Errorf("wrong interface name: %s", interfaces[0].Hwaddr) + } + + if len(interfaces[0].Addrs) != 2 { + t.Errorf("wrong number of addresses: %d", len(interfaces[0].Addrs)) + } + + for _, addr := range interfaces[0].Addrs { + var expected string + + if addr.Type == libvirt.VIR_IP_ADDR_TYPE_IPV4 { + expected = ipv4Addr + } else { + expected = ipv6Addr + } + + if expected != addr.Addr { + t.Errorf("Expected %s, got %s", expected, addr.Addr) + } + } +} |