Skip to content

Commit

Permalink
test (machine) : add some unit tests for growLVMForMicroshift
Browse files Browse the repository at this point in the history
Signed-off-by: Rohan Kumar <[email protected]>
  • Loading branch information
rohanKanojia committed Feb 18, 2025
1 parent 457b653 commit 1fbfdeb
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pkg/crc/machine/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func getrootPartition(sshRunner *crcssh.Runner, preset crcPreset.Preset) (string
return rootPart, nil
}

func growLVForMicroshift(sshRunner *crcssh.Runner, lvFullName string, rootPart string, persistentVolumeSize int) error {
func growLVForMicroshift(sshRunner crcos.CommandRunner, lvFullName string, rootPart string, persistentVolumeSize int) error {
if _, _, err := sshRunner.RunPrivileged("Resizing the physical volume(PV)", "/usr/sbin/pvresize", "--devices", rootPart, rootPart); err != nil {
return err
}
Expand Down
128 changes: 128 additions & 0 deletions pkg/crc/machine/start_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package machine

import (
"errors"
"fmt"
"slices"
"strings"
"testing"

"github.com/containers/common/pkg/strongunits"
"github.com/stretchr/testify/assert"
)

type MockedSSHRunner struct {
mockedSSHCommandToOutputMap map[string]string
mockedSSHCommandToError map[string]error
mockedSSHCommandToArgsMap map[string]string
}

func (r *MockedSSHRunner) RunPrivileged(reason string, cmdAndArgs ...string) (string, string, error) {
if r.mockedSSHCommandToError[reason] != nil {
return "", "", r.mockedSSHCommandToError[reason]
}
r.mockedSSHCommandToArgsMap[reason] = strings.Join(cmdAndArgs, ",")
output, ok := r.mockedSSHCommandToOutputMap[reason]
if !ok {
r.mockedSSHCommandToOutputMap[reason] = ""
}
return output, "", nil
}

func (r *MockedSSHRunner) Run(_ string, _ ...string) (string, string, error) {
// No-op
return "", "", nil
}

func (r *MockedSSHRunner) RunPrivate(_ string, _ ...string) (string, string, error) {
// No-op

Check failure on line 38 in pkg/crc/machine/start_test.go

View workflow job for this annotation

GitHub Actions / build (macOS-13, 1.22)

File is not properly formatted (gofmt)

Check failure on line 38 in pkg/crc/machine/start_test.go

View workflow job for this annotation

GitHub Actions / build (macOS-14, 1.22)

File is not properly formatted (gofmt)

Check failure on line 38 in pkg/crc/machine/start_test.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.22)

File is not properly formatted (gofmt)

Check failure on line 38 in pkg/crc/machine/start_test.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, 1.22)

File is not properly formatted (gofmt)
return "", "", nil
}

func NewMockedSSHRunner() *MockedSSHRunner {
return &MockedSSHRunner{
mockedSSHCommandToOutputMap: map[string]string{},
mockedSSHCommandToArgsMap: map[string]string{},
mockedSSHCommandToError: map[string]error{},
}
}

func TestGrowLVForMicroShift_WhenResizeAttemptFails_ThenThrowErrorExplainingWhereItFailed(t *testing.T) {
testCases := []struct {
name string
volumeGroupSizeOutput string
logicalVolumeSizeOutput string
physicalVolumeListCommandFailed error
physicalVolumeGroupSizeCommandFailed error
logicalVolumeSizeCommandFailed error
extendingLogicalVolumeSizeCommandFailed error
expectedReturnedError error
}{
{"when listing physical volume devices failed, then throw error", "", "", errors.New("listing volumes failed"), nil, nil, nil, errors.New("listing volumes failed")},
{"when fetching volume group size failed, then throw error", "", "", nil, errors.New("fetching volume group size failed"), nil, nil, errors.New("fetching volume group size failed")},
{"when parsing volume group size failed, then throw error", "invalid", "", nil, nil, nil, nil, errors.New("strconv.Atoi: parsing \"invalid\": invalid syntax")},
{"when fetching lv size failed, then throw error", "42966450176", "", nil, nil, errors.New("fetching lvm size failed"), nil, errors.New("fetching lvm size failed")},
{"when parsing lv size failed, then throw error", "42966450176", "invalid", nil, nil, nil, nil, errors.New("strconv.Atoi: parsing \"invalid\": invalid syntax")},
{"when extending lv size failed, then throw error", "42966450176", "16106127360", nil, nil, nil, errors.New("extending lv failed"), errors.New("extending lv failed")},
}

// Loop through each test case
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Given
sshRunner := NewMockedSSHRunner()
sshRunner.mockedSSHCommandToError["Resizing the physical volume(PV)"] = tc.physicalVolumeListCommandFailed
sshRunner.mockedSSHCommandToError["Get the volume group size"] = tc.physicalVolumeGroupSizeCommandFailed
sshRunner.mockedSSHCommandToOutputMap["Get the volume group size"] = tc.volumeGroupSizeOutput
sshRunner.mockedSSHCommandToError["Get the size of root logical volume"] = tc.logicalVolumeSizeCommandFailed
sshRunner.mockedSSHCommandToOutputMap["Get the size of root logical volume"] = tc.logicalVolumeSizeOutput
sshRunner.mockedSSHCommandToError["Extending and resizing the logical volume(LV)"] = tc.extendingLogicalVolumeSizeCommandFailed

// When
err := growLVForMicroshift(sshRunner, "rhel/root", "/dev/vda5", 15)

// Then
assert.EqualError(t, err, tc.expectedReturnedError.Error(), "Error messages should match")
})
}
}

func TestGrowLVForMicroShift_WhenPhysicalVolumeAvailableForResize_ThenSizeToIncreaseIsCalculatedAndGrown(t *testing.T) {
testCases := []struct {
name string
existingVolumeGroupSize strongunits.B
oldPersistentVolumeSize strongunits.B
persistentVolumeSize int
expectPVSizeToGrow bool
expectedIncreaseInSize strongunits.B
}{
{"when disk size can not accommodate persistent volume size growth, then do NOT grow lv", strongunits.GiB(31).ToBytes(), strongunits.GiB(15).ToBytes(), 20, false, strongunits.B(0)},
{"when disk size can accommodate persistent volume size growth, then grow lv", strongunits.GiB(41).ToBytes(), strongunits.GiB(15).ToBytes(), 20, true, strongunits.GiB(6).ToBytes()},
{"when requested persistent volume size less than present persistent volume size, then do NOT grow lv", strongunits.GiB(31).ToBytes(), strongunits.GiB(20).ToBytes(), 15, false, strongunits.B(0)},
{"when requested disk size less than present persistent volume size, then do NOT grow lv", strongunits.GiB(31).ToBytes(), strongunits.GiB(20).ToBytes(), 41, false, strongunits.B(0)},
// https://github.com/crc-org/crc/issues/4186#issuecomment-2656129015
{"when disk size has more space than requested persistent volume growth, then lv growth larger than requested", strongunits.GiB(45).ToBytes(), strongunits.GiB(15).ToBytes(), 20, true, strongunits.GiB(10).ToBytes()},
}

// Loop through each test case
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Given
sshRunner := NewMockedSSHRunner()
sshRunner.mockedSSHCommandToOutputMap["resizing the physical volume(PV)"] = "Physical volume \"/dev/vda5\" changed"
sshRunner.mockedSSHCommandToOutputMap["Get the volume group size"] = fmt.Sprintf("%d", tc.existingVolumeGroupSize.ToBytes())
sshRunner.mockedSSHCommandToOutputMap["Get the size of root logical volume"] = fmt.Sprintf("%d", tc.oldPersistentVolumeSize.ToBytes())

// When
err := growLVForMicroshift(sshRunner, "rhel/root", "/dev/vda5", tc.persistentVolumeSize)

// Then
assert.NoError(t, err)
_, lvExpanded := sshRunner.mockedSSHCommandToOutputMap["Extending and resizing the logical volume(LV)"]
assert.Equal(t, tc.expectPVSizeToGrow, lvExpanded)
if tc.expectPVSizeToGrow {
assert.True(t, slices.Contains(strings.Split(sshRunner.mockedSSHCommandToArgsMap["Extending and resizing the logical volume(LV)"], ","), fmt.Sprintf("+%db", tc.expectedIncreaseInSize.ToBytes())))
}
})
}
}

0 comments on commit 1fbfdeb

Please sign in to comment.