Skip to content

Commit

Permalink
Merge pull request #72 from openebs/hostpath-volume-provisioning-test
Browse files Browse the repository at this point in the history
chore(hostpath): add hostpath volume provisioning test
  • Loading branch information
rohan2794 authored Oct 4, 2024
2 parents a42e7dc + c7652f1 commit 090f896
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 67 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/e2e-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,23 @@ jobs:
- name: Zfs e2e test
run: |
nix-shell shell.nix --run "./scripts/e2e-test.sh --testplan zfs"
hostpath:
needs: ['lint']
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: DeterminateSystems/nix-installer-action@v11
with:
kvm: true
- uses: DeterminateSystems/magic-nix-cache-action@v6
- name: Pre-populate nix-shell
run: |
export NIX_PATH=nixpkgs=$(jq '.nixpkgs.url' nix/sources.json -r)
echo "NIX_PATH=$NIX_PATH" >> $GITHUB_ENV
nix-shell shell.nix --run "echo"
- name: BootStrap k8s cluster
run: |
nix-shell shell.nix --run "./scripts/k8s/deployer.sh start --workers 1"
- name: Hostpath e2e test
run: |
nix-shell shell.nix --run "./scripts/e2e-test.sh --testplan hostpath"
25 changes: 25 additions & 0 deletions common/hostpath/util.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package hostpath

import (
"encoding/json"
"fmt"

"github.com/openebs/openebs-e2e/common/e2e_agent"
Expand Down Expand Up @@ -75,3 +76,27 @@ func (hostPathConfig *HostPathDeviceNodeConfig) ConfigureHostPathDevices() error
}
return nil
}

func GetHostPathAnnotationConfig() (map[string]string, error) {
type hostpathConfig struct {
Name string `json:"name"`
Value string `json:"value"`
}
config := []hostpathConfig{
{Name: "StorageType", Value: "hostpath"},
{Name: "BasePath", Value: "/var/local-hostpath"},
}
// Marshal the configuration to a JSON string
configBytes, err := json.Marshal(config)
if err != nil {
logf.Log.Info("Error marshalling configuration:", "Error", err)
return nil, err

}
configString := string(configBytes)

return map[string]string{
"openebs.io/cas-type": "local",
"cas.openebs.io/config": configString,
}, err
}
83 changes: 83 additions & 0 deletions common/k8stest/util_busybox.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package k8stest

import (
"fmt"

"github.com/openebs/openebs-e2e/common"
coreV1 "k8s.io/api/core/v1"
logf "sigs.k8s.io/controller-runtime/pkg/log"
)

var defBusyboxTimeoutSecs = 120 // in seconds

func DeployBusyBoxPod(podName, pvcName string, volType common.VolumeType) error {
args := []string{"sleep", "10000000"}
podContainer := coreV1.Container{
Name: podName,
Image: "busybox",
ImagePullPolicy: coreV1.PullAlways,
Args: args,
}

volume := coreV1.Volume{
Name: "ms-volume",
VolumeSource: coreV1.VolumeSource{
PersistentVolumeClaim: &coreV1.PersistentVolumeClaimVolumeSource{
ClaimName: pvcName,
},
},
}

podObj, err := NewPodBuilder(podName).
WithName(podName).
WithNamespace(common.NSDefault).
WithRestartPolicy(coreV1.RestartPolicyNever).
WithContainer(podContainer).
WithVolume(volume).
WithVolumeDeviceOrMount(volType).Build()

if err != nil {
return fmt.Errorf("failed to generate busybox pod definition, error: %v", err)
}
if podObj == nil {
return fmt.Errorf("busybox pod definition is nil")
}

_, err = CreatePod(podObj, common.NSDefault)
if err != nil {
return fmt.Errorf("failed to create busybox pod, error: %v", err)
}

isPodRunning := WaitPodRunning(podName, common.NSDefault, defBusyboxTimeoutSecs)
if !isPodRunning {
return fmt.Errorf("failed to create busybox pod, error: %v", err)
}
logf.Log.Info(fmt.Sprintf("%s pod is running.", podName))
return nil
}

func CleanUpBusyboxResources(pods []string, pvcName string) error {
for _, pod := range pods {
err := DeletePod(pod, common.NSDefault)
if err != nil {
return fmt.Errorf("failed to delete pod %s err %v", pod, err)
}

}
if pvcName != "" {
pvc, err := GetPVC(pvcName, common.NSDefault)
if err != nil {
return fmt.Errorf("failed to get pvc %s err %v", pvcName, err)
}
err = RemovePVC(pvcName, *pvc.Spec.StorageClassName, common.NSDefault, true)
if err != nil {
return fmt.Errorf("failed to delete pvc %s err %v", pvcName, err)
}
err = RmStorageClass(*pvc.Spec.StorageClassName)
if err != nil {
return fmt.Errorf("failed to delete sc from pvc %s err %v", pvcName, err)
}
}

return nil
}
3 changes: 3 additions & 0 deletions scripts/exec-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,9 @@ for testname in $tests; do
elif [ -d "$TESTDIR/zfs/$testname" ]; then
testrootdir=$TESTDIR
fqtestname="zfs/$testname"
elif [ -d "$TESTDIR/hostpath/$testname" ]; then
testrootdir=$TESTDIR
fqtestname="hostpath/$testname"
elif [ -d "$TESTDIR/$testname" ]; then
testrootdir=$TESTDIR
fqtestname="$testname"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package hostpath_ci_smoke_test

import (
"testing"

"github.com/openebs/openebs-e2e/common"
"github.com/openebs/openebs-e2e/common/e2e_ginkgo"
"github.com/openebs/openebs-e2e/src/tests/hostpath/hostpath_volume_provisioning"

"github.com/openebs/openebs-e2e/common/k8stest"
logf "sigs.k8s.io/controller-runtime/pkg/log"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var podName, pvcName string
var err error

func TestHostpathCiSmokeTest(t *testing.T) {
// Initialise test and set class and file names for reports
e2e_ginkgo.InitTesting(t, "hostpath_ci_smoke_test", "hostpath_ci_smoke_test")
}

var _ = Describe("hostpath_ci_smoke_test", func() {

BeforeEach(func() {
// Check ready to run
err := e2e_ginkgo.BeforeEachK8sCheck()
Expect(err).ToNot(HaveOccurred())
})

AfterEach(func() {
// cleanup k8s resources if exist
logf.Log.Info("cleanup k8s resources")
err := k8stest.CleanUpBusyboxResources([]string{podName}, pvcName)
Expect(err).ToNot(HaveOccurred(), "failed delete busybox resource")

// Check resource leakage.
after_err := e2e_ginkgo.AfterEachK8sCheck()
Expect(after_err).ToNot(HaveOccurred())

})

It("hostpath ext4: should verify a volume can be created, used and deleted", func() {
podName, pvcName, err = hostpath_volume_provisioning.VolumeProvisioningTest("ext4", common.Ext4FsType)
Expect(err).ToNot(HaveOccurred())
})

})

var _ = BeforeSuite(func() {
err = e2e_ginkgo.SetupTestEnv()
Expect(err).ToNot(HaveOccurred(), "failed to setup test environment in BeforeSuite : SetupTestEnv %v", err)

})

var _ = AfterSuite(func() {
err = k8stest.TeardownTestEnv()
Expect(err).ToNot(HaveOccurred(), "failed to tear down test environment in AfterSuite : TeardownTestEnv %v", err)
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package hostpath_volume_provisioning

import (
"testing"

"github.com/openebs/openebs-e2e/common"
"github.com/openebs/openebs-e2e/common/e2e_ginkgo"
logf "sigs.k8s.io/controller-runtime/pkg/log"

"github.com/openebs/openebs-e2e/common/k8stest"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var podName, pvcName string
var err error

func TestHostpathVolumeProvisioningTest(t *testing.T) {
// Initialise test and set class and file names for reports
e2e_ginkgo.InitTesting(t, "hostpath_volume_provisioning", "hostpath_volume_provisioning")
}

var _ = Describe("hostpath_volume_provisioning", func() {

BeforeEach(func() {
// Check ready to run
err := e2e_ginkgo.BeforeEachK8sCheck()
Expect(err).ToNot(HaveOccurred())
})

AfterEach(func() {

// cleanup k8s resources
logf.Log.Info("cleanup k8s resources ")
err = k8stest.CleanUpBusyboxResources([]string{podName}, pvcName)
Expect(err).ToNot(HaveOccurred(), "failed to k8s resource")

// Check resource leakage.
err := e2e_ginkgo.AfterEachK8sCheck()
Expect(err).ToNot(HaveOccurred())

})

It("hostpath ext4: should verify a volume can be created, used and deleted", func() {
podName, pvcName, err = VolumeProvisioningTest("ext4", common.Ext4FsType)
Expect(err).ToNot(HaveOccurred())
})
It("hostpath xfs: should verify a volume can be created, used and deleted", func() {
podName, pvcName, err = VolumeProvisioningTest("xfs", common.XfsFsType)
Expect(err).ToNot(HaveOccurred())
})
It("hostpath btrfs: should verify a volume can be created, used and deleted", func() {
podName, pvcName, err = VolumeProvisioningTest("btrfs", common.BtrfsFsType)
Expect(err).ToNot(HaveOccurred())
})

})

var _ = BeforeSuite(func() {
err = e2e_ginkgo.SetupTestEnv()
Expect(err).ToNot(HaveOccurred(), "failed to setup test environment in BeforeSuite : SetupTestEnv %v", err)

})

var _ = AfterSuite(func() {
err = k8stest.TeardownTestEnv()
Expect(err).ToNot(HaveOccurred(), "failed to tear down test environment in AfterSuite : TeardownTestEnv %v", err)
})
69 changes: 69 additions & 0 deletions src/tests/hostpath/hostpath_volume_provisioning/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package hostpath_volume_provisioning

import (
"fmt"

"github.com/openebs/openebs-e2e/common"
"github.com/openebs/openebs-e2e/common/k8stest"

"github.com/openebs/openebs-e2e/common/hostpath"
logf "sigs.k8s.io/controller-runtime/pkg/log"
)

func VolumeProvisioningTest(decor string,
fstype common.FileSystemType,
) (string, string, error) {

// FIXME: here we are using k8stest.FioApplication to use its functionality
// and not deploying FIO, instead busybox application will be deployed.
app := k8stest.FioApplication{
Decor: decor,
VolSizeMb: 1024,
OpenEbsEngine: common.Hostpath,
VolType: common.VolFileSystem,
FsType: fstype,
VolWaitForFirstConsumer: true,
}

hostpathConfig, err := hostpath.GetHostPathAnnotationConfig()
if err != nil {
return "", "", err
}

// setup sc parameters
app.HostPath = k8stest.HostPathOptions{
Annotations: hostpathConfig,
}

// Create volume
logf.Log.Info("create volume")
err = app.CreateVolume()
if err != nil {
return "", "", err
}

// Deploy BusyBox pod and create file with MD5 checksum
podName := "busybox"
err = k8stest.DeployBusyBoxPod(podName, app.GetPvcName(), app.VolType)
if err != nil {
return "", app.GetPvcName(), err
}

filePath := "/volume/testfile.txt"
fileContent := "This is some test data."
md5FilePath1 := "/volume/md5sum1.txt"
combinedCmd1 := fmt.Sprintf(
"echo '%s' > %s && md5sum %s > %s",
fileContent,
filePath,
filePath,
md5FilePath1,
)

out, _, err := k8stest.ExecuteCommandInPod(common.NSDefault, podName, combinedCmd1)
if err != nil {
logf.Log.Info("Failed to execute command", "Error", err, "Output", out)
return podName, app.GetPvcName(), err
}
return podName, app.GetPvcName(), nil
}
Loading

0 comments on commit 090f896

Please sign in to comment.