Skip to content

Commit

Permalink
test: thinpool auto-extend test
Browse files Browse the repository at this point in the history
This change adds a test that verifies a thinpool auto-extends in size
as configured in the lvm.conf file.

Signed-off-by: Diwakar Sharma <[email protected]>
  • Loading branch information
dsharma-dc committed Jun 10, 2024
1 parent 6121473 commit 2ca22d9
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 16 deletions.
8 changes: 6 additions & 2 deletions ci/ci-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ cleanup() {

# setup the lvm volume group to create the volume
cleanup_lvmvg
truncate -s 1024G /tmp/openebs_ci_disk.img
truncate -s 100G /tmp/openebs_ci_disk.img
disk="$(sudo losetup -f /tmp/openebs_ci_disk.img --show)"
sudo pvcreate "${disk}"
sudo vgcreate lvmvg "${disk}"

# setup a foreign lvm to test
cleanup_foreign_lvmvg
truncate -s 1024G /tmp/openebs_ci_foreign_disk.img
truncate -s 100G /tmp/openebs_ci_foreign_disk.img
foreign_disk="$(sudo losetup -f /tmp/openebs_ci_foreign_disk.img --show)"
sudo pvcreate "${foreign_disk}"
sudo vgcreate foreign_lvmvg "${foreign_disk}" --config="${FOREIGN_LVM_CONFIG}"
Expand All @@ -97,6 +97,10 @@ sudo vgcreate foreign_lvmvg "${foreign_disk}" --config="${FOREIGN_LVM_CONFIG}"
sudo modprobe dm-snapshot
sudo modprobe dm_thin_pool

# Set the configuration for thin pool autoextend in lvm.conf
sudo sed -i '/^[^#]*thin_pool_autoextend_threshold/ s/= .*/= 50/' /etc/lvm/lvm.conf
sudo sed -i '/^[^#]*thin_pool_autoextend_percent/ s/= .*/= 20/' /etc/lvm/lvm.conf

# Prepare env for running BDD tests
# Minikube is already running
kubectl apply -f "${LVM_OPERATOR}"
Expand Down
2 changes: 1 addition & 1 deletion pkg/collector/lv_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (c *lvCollector) Describe(ch chan<- *prometheus.Desc) {
}

func (c *lvCollector) Collect(ch chan<- prometheus.Metric) {
lvList, err := lvm.ListLVMLogicalVolume()
lvList, err := lvm.ListLVMLogicalVolume("")
if err != nil {
klog.Errorf("error in getting the list of lvm logical volumes: %v", err)
} else {
Expand Down
49 changes: 46 additions & 3 deletions pkg/lvm/lvm_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@ const (
LVCreate = "lvcreate"
LVRemove = "lvremove"
LVExtend = "lvextend"
LVChange = "lvchange"
LVList = "lvs"

PVList = "pvs"
PVScan = "pvscan"

YES = "yes"
LVThinPool = "thin-pool"
SUDO = "sudo"
)

var (
Expand Down Expand Up @@ -868,13 +870,46 @@ func decodeLvsJSON(raw []byte) ([]LogicalVolume, error) {
return lvs, nil
}

func ListLVMLogicalVolume() ([]LogicalVolume, error) {
// Change the attributes of an LV. Let the caller provide the args string
// since we won't know what attrs and to what values need changing.
func ChangeLVMLogicalVolumeAttrs(lvname string, args []string) error {
cmd := LVChange

// append lvname to args
args = append([]string{lvname}, args...)

// Are we running privileged or not?
if os.Geteuid() != 0 {
args = append([]string{cmd}, args...)
cmd = SUDO
}

_, _, err := RunCommandSplit(cmd, args...)
if err != nil {
klog.Errorf("lvm: error while running command %s %v: %v", LVChange, args, err)
return err
}

return nil
}

// Get all, or a particular LVM LV. If lvname is nil, all LVs are listed, otherwise the requested one.
func ListLVMLogicalVolume(lvname string) ([]LogicalVolume, error) {
cmd := LVList
args := []string{
"--options", "lv_all,vg_name,segtype",
"--reportformat", "json",
"--units", "b",
lvname,
}

// Are we running privileged or not?
if os.Geteuid() != 0 {
args = append([]string{cmd}, args...)
cmd = SUDO
}
output, _, err := RunCommandSplit(LVList, args...)

output, _, err := RunCommandSplit(cmd, args...)
if err != nil {
klog.Errorf("lvm: error while running command %s %v: %v", LVList, args, err)
return nil, err
Expand All @@ -891,12 +926,20 @@ func ListLVMPhysicalVolume() ([]PhysicalVolume, error) {
return nil, err
}

cmd := PVList
args := []string{
"--options", "pv_all,vg_name",
"--reportformat", "json",
"--units", "b",
}
output, _, err := RunCommandSplit(PVList, args...)

// Are we running privileged or not?
if os.Geteuid() != 0 {
args = append([]string{cmd}, args...)
cmd = SUDO
}

output, _, err := RunCommandSplit(cmd, args...)
if err != nil {
klog.Errorf("lvm: error while running command %s %v: %v", PVList, args, err)
return nil, err
Expand Down
17 changes: 16 additions & 1 deletion tests/provision_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,20 @@ func thinVolCreationTest() {
By("Deleting thinProvision storage class", deleteStorageClass)
}

func thinVolCapacityTest() {
By("Creating thinProvision storage class", createThinStorageClass)
By("creating and verifying PVC bound status", createAndVerifyPVC)
By("creating and verifying PVC bound status", enableThinpoolMonitoring)
By("Creating and deploying app pod", createDeployVerifyApp)
By("verifying thinpool auto-extended", VerifyThinpoolExtend)
By("verifying LVMVolume object", VerifyLVMVolume)
By("Deleting application deployment")
deleteAppDeployment(appName)
By("Deleting pvc")
deleteAndVerifyPVC(pvcName)
By("Deleting thinProvision storage class", deleteStorageClass)
}

func leakProtectionTest() {
By("Creating default storage class", createStorageClass)
ds := deleteNodeDaemonSet() // ensure that provisioning remains in pending state.
Expand All @@ -116,8 +130,9 @@ func leakProtectionTest() {
}

func volumeCreationTest() {
By("Running volume creation test", fsVolCreationTest)
By("Running filesystem volume creation test", fsVolCreationTest)
By("Running block volume creation test", blockVolCreationTest)
By("Running thin volume creation test", thinVolCreationTest)
By("Running thin volume capacity test", thinVolCapacityTest)
By("Running leak protection test", leakProtectionTest)
}
19 changes: 10 additions & 9 deletions tests/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,16 @@ var (
nodeDaemonSet = "openebs-lvm-node"
controllerDeployment = "openebs-lvm-controller"

nsObj *corev1.Namespace
scObj *storagev1.StorageClass
deployObj *appsv1.Deployment
pvcObj *corev1.PersistentVolumeClaim
appPod *corev1.PodList
accessModes = []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}
capacity = "5368709120" // 5Gi
KubeConfigPath string
OpenEBSNamespace string
nsObj *corev1.Namespace
scObj *storagev1.StorageClass
deployObj *appsv1.Deployment
pvcObj *corev1.PersistentVolumeClaim
appPod *corev1.PodList
accessModes = []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}
capacity = "5368709120" // 5Gi
expanded_capacity = "6442450944" // 6Gi
KubeConfigPath string
OpenEBSNamespace string
)

func init() {
Expand Down
36 changes: 36 additions & 0 deletions tests/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package tests
import (
"context"
"fmt"
"strconv"
"time"

"github.com/onsi/ginkgo"
Expand Down Expand Up @@ -706,3 +707,38 @@ func createNodeDaemonSet(ds *appsv1.DaemonSet) {
gomega.BeNil(),
"creating node plugin daemonset %v", nodeDaemonSet)
}

func enableThinpoolMonitoring() {
lv := VOLGROUP + "/" + pvcObj.Spec.VolumeName
vol, err := lvm.ListLVMLogicalVolume(lv)

gomega.Expect(err).To(gomega.BeNil(), "list LVM LV")
gomega.Expect(len(vol)).To(gomega.Equal(1), "retrieve LVM LV")

thinpool := VOLGROUP + "/" + vol[0].PoolName

args := []string{
"--monitor", "y",
}

err = lvm.ChangeLVMLogicalVolumeAttrs(thinpool, args)
gomega.Expect(err).To(gomega.BeNil(), "run lvchange command")
}

func VerifyThinpoolExtend() {
expect_size, _ := strconv.ParseInt(expanded_capacity, 10, 64)
lv := VOLGROUP + "/" + pvcObj.Spec.VolumeName
vol, err := lvm.ListLVMLogicalVolume(lv)

gomega.Expect(err).To(gomega.BeNil(), "list LVM LV")
gomega.Expect(len(vol)).To(gomega.Equal(1), "retrieve LVM LV")

thinpool := VOLGROUP + "/" + vol[0].PoolName
vol, err = lvm.ListLVMLogicalVolume(thinpool)
gomega.Expect(err).To(gomega.BeNil(), "list LVM thinpool LV")
gomega.Expect(len(vol)).To(gomega.Equal(1), "retrieve LVM thinpool LV")

// This expectation is a factor of the lvm.conf settings we do from ci-test.sh
// and the original volume size.
gomega.Expect(vol[0].Size).To(gomega.Equal(expect_size))
}

0 comments on commit 2ca22d9

Please sign in to comment.