-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add tests for volume group utility
Signed-off-by: Santosh Pillai <sapillai@redhat.com>
- Loading branch information
Showing
2 changed files
with
212 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package test | ||
|
||
type MockExecutor struct { | ||
MockExecuteCommandWithOutput func(command string, arg ...string) (string, error) | ||
MockExecuteCommandWithOutputAsHost func(command string, arg ...string) (string, error) | ||
} | ||
|
||
// ExecuteCommandWithOutput mocks ExecuteCommandWithOutput | ||
func (e *MockExecutor) ExecuteCommandWithOutput(command string, arg ...string) (string, error) { | ||
if e.MockExecuteCommandWithOutput != nil { | ||
return e.MockExecuteCommandWithOutput(command, arg...) | ||
} | ||
|
||
return "", nil | ||
} | ||
|
||
// ExecuteCommandWithOutputAsHost mocks ExecuteCommandWithOutputAsHost | ||
func (e *MockExecutor) ExecuteCommandWithOutputAsHost(command string, arg ...string) (string, error) { | ||
if e.MockExecuteCommandWithOutputAsHost != nil { | ||
return e.MockExecuteCommandWithOutputAsHost(command, arg...) | ||
} | ||
|
||
return "", nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
package vgmanager | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
"testing" | ||
|
||
mockExec "github.com/red-hat-storage/lvm-operator/pkg/internal/test" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
var mockVgsOutput = `{ | ||
"report": [ | ||
{ | ||
"vg": [ | ||
{"vg_name":"vg1", "pv_count":"3", "lv_count":"3", "snap_count":"0", "vg_attr":"wz--n-", "vg_size":"<475.94g", "vg_free":"0 "}, | ||
{"vg_name":"vg2", "pv_count":"3", "lv_count":"3", "snap_count":"0", "vg_attr":"wz--n-", "vg_size":"<475.94g", "vg_free":"0 "} | ||
] | ||
} | ||
] | ||
}` | ||
|
||
var mockPvsOutputForVG1 = ` | ||
{ | ||
"report": [ | ||
{ | ||
"pv": [ | ||
{"pv_name":"/dev/sda", "vg_name":"vg1", "pv_fmt":"lvm2", "pv_attr":"a--", "pv_size":"<475.94g", "pv_free":"0 "}, | ||
{"pv_name":"/dev/sdb", "vg_name":"vg1", "pv_fmt":"lvm2", "pv_attr":"a--", "pv_size":"<475.94g", "pv_free":"0 "}, | ||
{"pv_name":"/dev/sdc", "vg_name":"vg1", "pv_fmt":"lvm2", "pv_attr":"a--", "pv_size":"<475.94g", "pv_free":"0 "} | ||
] | ||
} | ||
] | ||
} | ||
` | ||
|
||
var mockPvsOutputForVG2 = ` | ||
{ | ||
"report": [ | ||
{ | ||
"pv": [ | ||
{"pv_name":"/dev/sdd", "vg_name":"vg2", "pv_fmt":"lvm2", "pv_attr":"a--", "pv_size":"<475.94g", "pv_free":"0 "}, | ||
{"pv_name":"/dev/sde", "vg_name":"vg2", "pv_fmt":"lvm2", "pv_attr":"a--", "pv_size":"<475.94g", "pv_free":"0 "} | ||
] | ||
} | ||
] | ||
} | ||
` | ||
|
||
func TestGetVolumeGroup(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
vgName string | ||
pvCount int | ||
wantErr bool | ||
}{ | ||
{"Invalid volume group name", "invald-vg", 0, true}, | ||
{"Valid volume group name", "vg1", 3, false}, | ||
{"Valid volume group name", "vg2", 2, false}, | ||
} | ||
executor := &mockExec.MockExecutor{ | ||
MockExecuteCommandWithOutputAsHost: func(command string, args ...string) (string, error) { | ||
if args[0] == "vgs" { | ||
return mockVgsOutput, nil | ||
} else if args[0] == "pvs" { | ||
if strings.HasSuffix(args[2], "vg1") { | ||
return mockPvsOutputForVG1, nil | ||
} else if strings.HasSuffix(args[2], "vg2") { | ||
return mockPvsOutputForVG2, nil | ||
} | ||
} | ||
return "", fmt.Errorf("invalid args %q", args[0]) | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
vg, err := GetVolumeGroup(executor, tt.vgName) | ||
if tt.wantErr { | ||
assert.Error(t, err) | ||
} else { | ||
assert.NoError(t, err) | ||
assert.Equal(t, tt.vgName, vg.Name) | ||
assert.Equal(t, tt.pvCount, len(vg.PVs)) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestListVolumeGroup(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
wantErr bool | ||
}{ | ||
{"List all volume groups", false}, | ||
} | ||
executor := &mockExec.MockExecutor{ | ||
MockExecuteCommandWithOutputAsHost: func(command string, args ...string) (string, error) { | ||
if args[0] == "vgs" { | ||
return mockVgsOutput, nil | ||
} else if args[0] == "pvs" { | ||
if strings.HasSuffix(args[2], "vg1") { | ||
return mockPvsOutputForVG1, nil | ||
} else if strings.HasSuffix(args[2], "vg2") { | ||
return mockPvsOutputForVG2, nil | ||
} | ||
} | ||
return "", fmt.Errorf("invalid args %q", args[0]) | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
vgs, err := ListVolumeGroups(executor) | ||
if tt.wantErr { | ||
assert.Error(t, err) | ||
} else { | ||
assert.NoError(t, err) | ||
for _, vg := range vgs { | ||
if vg.Name == "vg1" { | ||
assert.Equal(t, 3, len(vg.PVs)) | ||
} else if vg.Name == "vg2" { | ||
assert.Equal(t, 2, len(vg.PVs)) | ||
} | ||
} | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestCreateVolumeGroup(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
volumeGroup *VolumeGroup | ||
pvs []string | ||
wantErr bool | ||
}{ | ||
{"No Volume Group Name", &VolumeGroup{}, []string{}, true}, | ||
{"No Physical Volumes", &VolumeGroup{Name: "vg1"}, []string{}, true}, | ||
{"Volume Group created successfully", &VolumeGroup{Name: "vg1"}, []string{"/dev/sdb"}, false}, | ||
} | ||
|
||
executor := &mockExec.MockExecutor{ | ||
MockExecuteCommandWithOutputAsHost: func(command string, args ...string) (string, error) { | ||
return "", nil | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
err := tt.volumeGroup.Create(executor, tt.pvs) | ||
if tt.wantErr { | ||
assert.Error(t, err) | ||
} else { | ||
assert.NoError(t, err) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestExtendVolumeGroup(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
volumeGroup *VolumeGroup | ||
PVs []string | ||
wantErr bool | ||
}{ | ||
{"No PVs are available", &VolumeGroup{Name: "vg1"}, []string{}, true}, | ||
{"New PVs are available", &VolumeGroup{Name: "vg1"}, []string{"/dev/sdb", "/dev/sdc"}, false}, | ||
} | ||
|
||
executor := &mockExec.MockExecutor{ | ||
MockExecuteCommandWithOutputAsHost: func(command string, args ...string) (string, error) { | ||
return "", nil | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
err := tt.volumeGroup.Extend(executor, tt.PVs) | ||
if tt.wantErr { | ||
assert.Error(t, err) | ||
} else { | ||
assert.NoError(t, err) | ||
} | ||
}) | ||
} | ||
} |