Skip to content

Commit 35b2b04

Browse files
committed
Merge pull request docker-archive-public#2374 from dgageot/more-vb-tests
Add more tests to the VirtualBox driver
2 parents 076bbf8 + 308f9d0 commit 35b2b04

File tree

7 files changed

+239
-79
lines changed

7 files changed

+239
-79
lines changed

drivers/virtualbox/disk.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package virtualbox
22

33
import (
44
"bufio"
5-
"io"
65
"strings"
76
)
87

@@ -11,28 +10,31 @@ type VirtualDisk struct {
1110
Path string
1211
}
1312

14-
func (d *Driver) getVMDiskInfo(name string) (*VirtualDisk, error) {
15-
out, err := d.vbmOut("showvminfo", name, "--machinereadable")
13+
func getVMDiskInfo(name string, vbox VBoxManager) (*VirtualDisk, error) {
14+
out, err := vbox.vbmOut("showvminfo", name, "--machinereadable")
1615
if err != nil {
1716
return nil, err
1817
}
1918

20-
r := strings.NewReader(out)
21-
return parseDiskInfo(r)
19+
return parseDiskInfo(out)
2220
}
2321

24-
func parseDiskInfo(r io.Reader) (*VirtualDisk, error) {
25-
s := bufio.NewScanner(r)
22+
func parseDiskInfo(out string) (*VirtualDisk, error) {
2623
disk := &VirtualDisk{}
24+
25+
r := strings.NewReader(out)
26+
s := bufio.NewScanner(r)
2727
for s.Scan() {
2828
line := s.Text()
2929
if line == "" {
3030
continue
3131
}
32+
3233
res := reEqualQuoteLine.FindStringSubmatch(line)
3334
if res == nil {
3435
continue
3536
}
37+
3638
key, val := res[1], res[2]
3739
switch key {
3840
case "SATA-1-0":
@@ -44,5 +46,6 @@ func parseDiskInfo(r io.Reader) (*VirtualDisk, error) {
4446
if err := s.Err(); err != nil {
4547
return nil, err
4648
}
49+
4750
return disk, nil
4851
}

drivers/virtualbox/disk_test.go

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package virtualbox
22

33
import (
4-
"strings"
54
"testing"
5+
6+
"github.com/docker/machine/drivers/vmwarevsphere/errors"
7+
"github.com/stretchr/testify/assert"
68
)
79

8-
var (
9-
testDiskInfoText = `
10+
const (
11+
validDiskInfoText = `
1012
storagecontrollerbootable0="on"
1113
"SATA-0-0"="/home/ehazlett/.boot2docker/boot2docker.iso"
1214
"SATA-IsEjected"="off"
@@ -18,19 +20,39 @@ nic1="nat"
1820
)
1921

2022
func TestVMDiskInfo(t *testing.T) {
21-
r := strings.NewReader(testDiskInfoText)
22-
disk, err := parseDiskInfo(r)
23-
if err != nil {
24-
t.Fatal(err)
23+
vbox := &VBoxManagerMock{
24+
args: "showvminfo default --machinereadable",
25+
stdOut: validDiskInfoText,
2526
}
2627

27-
diskPath := "/home/ehazlett/vm/test/disk.vmdk"
28-
diskUUID := "12345-abcdefg"
29-
if disk.Path != diskPath {
30-
t.Fatalf("expected disk path %s", diskPath)
28+
disk, err := getVMDiskInfo("default", vbox)
29+
30+
assert.Equal(t, "/home/ehazlett/vm/test/disk.vmdk", disk.Path)
31+
assert.Equal(t, "12345-abcdefg", disk.UUID)
32+
assert.NoError(t, err)
33+
}
34+
35+
func TestVMDiskInfoError(t *testing.T) {
36+
vbox := &VBoxManagerMock{
37+
args: "showvminfo default --machinereadable",
38+
err: errors.New("BUG"),
3139
}
3240

33-
if disk.UUID != diskUUID {
34-
t.Fatalf("expected disk uuid %s", diskUUID)
41+
disk, err := getVMDiskInfo("default", vbox)
42+
43+
assert.Nil(t, disk)
44+
assert.EqualError(t, err, "BUG")
45+
}
46+
47+
func TestVMDiskInfoInvalidOutput(t *testing.T) {
48+
vbox := &VBoxManagerMock{
49+
args: "showvminfo default --machinereadable",
50+
stdOut: "INVALID",
3551
}
52+
53+
disk, err := getVMDiskInfo("default", vbox)
54+
55+
assert.Empty(t, disk.Path)
56+
assert.Empty(t, disk.UUID)
57+
assert.NoError(t, err)
3658
}

drivers/virtualbox/network.go

Lines changed: 50 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -31,75 +31,65 @@ type hostOnlyNetwork struct {
3131
NetworkName string // referenced in DHCP.NetworkName
3232
}
3333

34-
// TODO: use VBoxManager.vbm() instead
35-
func vbm(args ...string) error {
36-
vBoxManager := &VBoxCmdManager{}
37-
_, _, err := vBoxManager.vbmOutErr(args...)
38-
return err
39-
}
40-
41-
// TODO: use VBoxManager.vbmOut() instead
42-
func vbmOut(args ...string) (string, error) {
43-
vBoxManager := &VBoxCmdManager{}
44-
stdout, _, err := vBoxManager.vbmOutErr(args...)
45-
return stdout, err
46-
}
47-
4834
// Save changes the configuration of the host-only network.
49-
func (n *hostOnlyNetwork) Save() error {
35+
func (n *hostOnlyNetwork) Save(vbox VBoxManager) error {
5036
if n.IPv4.IP != nil && n.IPv4.Mask != nil {
51-
if err := vbm("hostonlyif", "ipconfig", n.Name, "--ip", n.IPv4.IP.String(), "--netmask", net.IP(n.IPv4.Mask).String()); err != nil {
37+
if err := vbox.vbm("hostonlyif", "ipconfig", n.Name, "--ip", n.IPv4.IP.String(), "--netmask", net.IP(n.IPv4.Mask).String()); err != nil {
5238
return err
5339
}
5440
}
5541

5642
if n.IPv6.IP != nil && n.IPv6.Mask != nil {
5743
prefixLen, _ := n.IPv6.Mask.Size()
58-
if err := vbm("hostonlyif", "ipconfig", n.Name, "--ipv6", n.IPv6.IP.String(), "--netmasklengthv6", fmt.Sprintf("%d", prefixLen)); err != nil {
44+
if err := vbox.vbm("hostonlyif", "ipconfig", n.Name, "--ipv6", n.IPv6.IP.String(), "--netmasklengthv6", fmt.Sprintf("%d", prefixLen)); err != nil {
5945
return err
6046
}
6147
}
6248

6349
if n.DHCP {
64-
vbm("hostonlyif", "ipconfig", n.Name, "--dhcp") // not implemented as of VirtualBox 4.3
50+
vbox.vbm("hostonlyif", "ipconfig", n.Name, "--dhcp") // not implemented as of VirtualBox 4.3
6551
}
6652

6753
return nil
6854
}
6955

7056
// createHostonlyNet creates a new host-only network.
71-
func createHostonlyNet() (*hostOnlyNetwork, error) {
72-
out, err := vbmOut("hostonlyif", "create")
57+
func createHostonlyNet(vbox VBoxManager) (*hostOnlyNetwork, error) {
58+
out, err := vbox.vbmOut("hostonlyif", "create")
7359
if err != nil {
7460
return nil, err
7561
}
62+
7663
res := reHostonlyInterfaceCreated.FindStringSubmatch(string(out))
7764
if res == nil {
7865
return nil, errors.New("failed to create hostonly interface")
7966
}
67+
8068
return &hostOnlyNetwork{Name: res[1]}, nil
8169
}
8270

8371
// listHostOnlyNetworks gets all host-only networks in a map keyed by HostonlyNet.NetworkName.
84-
func listHostOnlyNetworks() (map[string]*hostOnlyNetwork, error) {
85-
out, err := vbmOut("list", "hostonlyifs")
72+
func listHostOnlyNetworks(vbox VBoxManager) (map[string]*hostOnlyNetwork, error) {
73+
out, err := vbox.vbmOut("list", "hostonlyifs")
8674
if err != nil {
8775
return nil, err
8876
}
89-
s := bufio.NewScanner(strings.NewReader(out))
77+
9078
m := map[string]*hostOnlyNetwork{}
9179
n := &hostOnlyNetwork{}
80+
81+
s := bufio.NewScanner(strings.NewReader(out))
9282
for s.Scan() {
9383
line := s.Text()
9484
if line == "" {
95-
m[n.NetworkName] = n
96-
n = &hostOnlyNetwork{}
9785
continue
9886
}
87+
9988
res := reColonLine.FindStringSubmatch(line)
10089
if res == nil {
10190
continue
10291
}
92+
10393
switch key, val := res[1], res[2]; key {
10494
case "Name":
10595
n.Name = val
@@ -131,8 +121,11 @@ func listHostOnlyNetworks() (map[string]*hostOnlyNetwork, error) {
131121
n.Status = val
132122
case "VBoxNetworkName":
133123
n.NetworkName = val
124+
m[val] = n
125+
n = &hostOnlyNetwork{}
134126
}
135127
}
128+
136129
if err := s.Err(); err != nil {
137130
return nil, err
138131
}
@@ -153,35 +146,37 @@ func getHostOnlyNetwork(nets map[string]*hostOnlyNetwork, hostIP net.IP, netmask
153146
return nil
154147
}
155148

156-
func getOrCreateHostOnlyNetwork(hostIP net.IP, netmask net.IPMask, dhcpIP net.IP, dhcpUpperIP net.IP, dhcpLowerIP net.IP) (*hostOnlyNetwork, error) {
157-
nets, err := listHostOnlyNetworks()
149+
func getOrCreateHostOnlyNetwork(hostIP net.IP, netmask net.IPMask, dhcpIP net.IP, dhcpLowerIP net.IP, dhcpUpperIP net.IP, vbox VBoxManager) (*hostOnlyNetwork, error) {
150+
nets, err := listHostOnlyNetworks(vbox)
158151
if err != nil {
159152
return nil, err
160153
}
161154

162155
hostOnlyNet := getHostOnlyNetwork(nets, hostIP, netmask)
156+
if hostOnlyNet != nil {
157+
return hostOnlyNet, nil
158+
}
163159

164-
if hostOnlyNet == nil {
165-
// No existing host-only interface found. Create a new one.
166-
hostOnlyNet, err = createHostonlyNet()
167-
if err != nil {
168-
return nil, err
169-
}
170-
hostOnlyNet.IPv4.IP = hostIP
171-
hostOnlyNet.IPv4.Mask = netmask
172-
if err := hostOnlyNet.Save(); err != nil {
173-
return nil, err
174-
}
160+
// No existing host-only interface found. Create a new one.
161+
hostOnlyNet, err = createHostonlyNet(vbox)
162+
if err != nil {
163+
return nil, err
164+
}
175165

176-
dhcp := dhcpServer{}
177-
dhcp.IPv4.IP = dhcpIP
178-
dhcp.IPv4.Mask = netmask
179-
dhcp.LowerIP = dhcpUpperIP
180-
dhcp.UpperIP = dhcpLowerIP
181-
dhcp.Enabled = true
182-
if err := addHostonlyDHCP(hostOnlyNet.Name, dhcp); err != nil {
183-
return nil, err
184-
}
166+
hostOnlyNet.IPv4.IP = hostIP
167+
hostOnlyNet.IPv4.Mask = netmask
168+
if err := hostOnlyNet.Save(vbox); err != nil {
169+
return nil, err
170+
}
171+
172+
dhcp := dhcpServer{}
173+
dhcp.IPv4.IP = dhcpIP
174+
dhcp.IPv4.Mask = netmask
175+
dhcp.LowerIP = dhcpLowerIP
176+
dhcp.UpperIP = dhcpUpperIP
177+
dhcp.Enabled = true
178+
if err := addHostonlyDHCP(hostOnlyNet.Name, dhcp, vbox); err != nil {
179+
return nil, err
185180
}
186181

187182
return hostOnlyNet, nil
@@ -196,12 +191,12 @@ type dhcpServer struct {
196191
Enabled bool
197192
}
198193

199-
func addDHCPServer(kind, name string, d dhcpServer) error {
194+
func addDHCPServer(kind, name string, d dhcpServer, vbox VBoxManager) error {
200195
command := "modify"
201196

202197
// On some platforms (OSX), creating a hostonlyinterface adds a default dhcpserver
203198
// While on others (Windows?) it does not.
204-
dhcps, err := getDHCPServers()
199+
dhcps, err := getDHCPServers(vbox)
205200
if err != nil {
206201
return err
207202
}
@@ -222,17 +217,18 @@ func addDHCPServer(kind, name string, d dhcpServer) error {
222217
} else {
223218
args = append(args, "--disable")
224219
}
225-
return vbm(args...)
220+
221+
return vbox.vbm(args...)
226222
}
227223

228224
// addHostonlyDHCP adds a DHCP server to a host-only network.
229-
func addHostonlyDHCP(ifname string, d dhcpServer) error {
230-
return addDHCPServer("--netname", "HostInterfaceNetworking-"+ifname, d)
225+
func addHostonlyDHCP(ifname string, d dhcpServer, vbox VBoxManager) error {
226+
return addDHCPServer("--netname", "HostInterfaceNetworking-"+ifname, d, vbox)
231227
}
232228

233229
// getDHCPServers gets all DHCP server settings in a map keyed by DHCP.NetworkName.
234-
func getDHCPServers() (map[string]*dhcpServer, error) {
235-
out, err := vbmOut("list", "dhcpservers")
230+
func getDHCPServers(vbox VBoxManager) (map[string]*dhcpServer, error) {
231+
out, err := vbox.vbmOut("list", "dhcpservers")
236232
if err != nil {
237233
return nil, err
238234
}

0 commit comments

Comments
 (0)