Skip to content

Commit de16cb0

Browse files
committed
Integration tests and Job
1 parent b72bc50 commit de16cb0

File tree

14 files changed

+209
-100
lines changed

14 files changed

+209
-100
lines changed

Dockerfile

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ COPY go.sum ./
77
RUN go mod download
88

99
COPY *.go ./
10+
COPY pkg ./pkg
11+
COPY Makefile ./
12+
COPY tests ./tests
1013

1114
RUN go build -o /lister-sa
1215

deploy/job.yaml

+7-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ spec:
1515
automountServiceAccountToken: true
1616
containers:
1717
- name: command-demo-container
18-
image: lister-sa:0.1
19-
imagePullPolicy: Never
18+
image: ksraj123/stale-sts-pvc-cleaner:0.1
19+
imagePullPolicy: IfNotPresent
20+
env:
21+
- name: PROVISIONERS
22+
value: "openebs.io/local"
23+
- name: NAMESPACES
24+
value: "default"
2025
restartPolicy: Never

deploy/mongodb/pv.yaml

-15
This file was deleted.

deploy/mongodb/pvc.yaml

-11
This file was deleted.

deploy/mongodb/sts.yaml

+2-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ spec:
1212
clusterIP: None
1313
selector:
1414
role: mongo
15-
sts-pvc-selector: sts-pvc
15+
sts-pvc: "true"
1616
---
1717
apiVersion: apps/v1
1818
kind: StatefulSet
@@ -29,11 +29,8 @@ spec:
2929
metadata:
3030
labels:
3131
role: mongo
32-
sts-pvc-selector: sts-pvc
32+
sts-pvc: "true"
3333
environment: test
34-
#This label will be used by openebs to place in replica
35-
# pod anti-affinity to make sure data of different mongo
36-
# instances are not co-located on the same node
3734
openebs.io/replica-anti-affinity: vehicle-db
3835
spec:
3936
terminationGracePeriodSeconds: 10

deploy/pod-sa.yaml

+7-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@ spec:
77
automountServiceAccountToken: true
88
containers:
99
- name: command-demo-container
10-
image: ksraj123/sts-pv:0.1.1
11-
imagePullPolicy: Never
10+
image: ksraj123/stale-sts-pvc-cleaner:0.1
11+
imagePullPolicy: IfNotPresent
1212
command: ["sleep"]
1313
args: ["infinity"]
14+
env:
15+
- name: PROVISIONERS
16+
value: "openebs.io/local"
17+
- name: NAMESPACES
18+
value: "default"
1419
restartPolicy: Never

deploy/sc.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
apiVersion: storage.k8s.io/v1
22
kind: StorageClass
33
metadata:
4-
name: test-storage-class
4+
name: test-storage-class-1
55
annotations:
66
openebs.io/delete-dangling-pvc: "true"
77
openebs.io/cas-type: local

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
github.com/golang/protobuf v1.5.2 // indirect
77
github.com/onsi/ginkgo v1.16.5 // indirect
88
github.com/onsi/gomega v1.17.0 // indirect
9-
k8s.io/api v0.22.3
9+
k8s.io/api v0.22.4
1010
k8s.io/apimachinery v0.22.4
1111
k8s.io/client-go v0.22.3
1212
sigs.k8s.io/controller-runtime v0.10.3 // indirect

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,8 @@ k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw=
727727
k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8=
728728
k8s.io/api v0.22.3 h1:wOoES2GoSkUsdped2RB4zYypPqWtvprGoKCENTOOjP4=
729729
k8s.io/api v0.22.3/go.mod h1:azgiXFiXqiWyLCfI62/eYBOu19rj2LKmIhFPP4+33fs=
730+
k8s.io/api v0.22.4 h1:UvyHW0ezB2oIgHAxlYoo6UJQObYXU7awuNarwoHEOjw=
731+
k8s.io/api v0.22.4/go.mod h1:Rgs+9gIGYC5laXQSZZ9JqT5NevNgoGiOdVWi1BAB3qk=
730732
k8s.io/apiextensions-apiserver v0.22.2 h1:zK7qI8Ery7j2CaN23UCFaC1hj7dMiI87n01+nKuewd4=
731733
k8s.io/apiextensions-apiserver v0.22.2/go.mod h1:2E0Ve/isxNl7tWLSUDgi6+cmwHi5fQRdwGVCxbC+KFA=
732734
k8s.io/apimachinery v0.22.2 h1:ejz6y/zNma8clPVfNDLnPbleBo6MpoFy/HBiBqCouVk=

pkg/constants/constants.go

+1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ const (
66
PROVISIONERS_ENV_VAR = "PROVISIONERS"
77
STORAGE_CLASS_ANNOTATION = "openebs.io/delete-dangling-pvc"
88
STS_PVC_SELECTOR = "sts-pvc-selector"
9+
OPENEBS_NAMESPACe = "openebs"
910
)

tests/generators/generators.go

+39-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package generators
22

33
import (
44
AppsV1 "k8s.io/api/apps/v1"
5+
BatchV1 "k8s.io/api/batch/v1"
56
CoreV1 "k8s.io/api/core/v1"
67
StorageV1 "k8s.io/api/storage/v1"
78
"k8s.io/apimachinery/pkg/api/resource"
@@ -77,13 +78,48 @@ func GeneratePersistentVolumeClaim(name string, namespace string, storageClassNa
7778

7879
func GenerateStorageClass(name string, annotations map[string]string, parameters map[string]string, provisioner string) *StorageV1.StorageClass {
7980
var deletePolicy CoreV1.PersistentVolumeReclaimPolicy = "Delete"
81+
mode := StorageV1.VolumeBindingWaitForFirstConsumer
8082
return &StorageV1.StorageClass{
8183
ObjectMeta: metav1.ObjectMeta{
8284
Name: name,
8385
Annotations: annotations,
8486
},
85-
Parameters: parameters,
86-
Provisioner: provisioner,
87-
ReclaimPolicy: &deletePolicy,
87+
Parameters: parameters,
88+
Provisioner: provisioner,
89+
ReclaimPolicy: &deletePolicy,
90+
VolumeBindingMode: &mode,
91+
}
92+
}
93+
94+
func GenerateJob(name string, labels map[string]string, serviceAccountName string, image string, env []CoreV1.EnvVar) *BatchV1.Job {
95+
automountServiceAccountToken := true
96+
imagePullPolicy := CoreV1.PullIfNotPresent
97+
restartPolicy := CoreV1.RestartPolicyNever
98+
return &BatchV1.Job{
99+
ObjectMeta: metav1.ObjectMeta{
100+
Name: name,
101+
Labels: labels,
102+
},
103+
Spec: BatchV1.JobSpec{
104+
Template: CoreV1.PodTemplateSpec{
105+
ObjectMeta: metav1.ObjectMeta{
106+
Name: name,
107+
Labels: labels,
108+
},
109+
Spec: CoreV1.PodSpec{
110+
ServiceAccountName: serviceAccountName,
111+
AutomountServiceAccountToken: &automountServiceAccountToken,
112+
Containers: []CoreV1.Container{
113+
{
114+
Name: "container",
115+
Image: image,
116+
ImagePullPolicy: imagePullPolicy,
117+
Env: env,
118+
},
119+
},
120+
RestartPolicy: restartPolicy,
121+
},
122+
},
123+
},
88124
}
89125
}

tests/setup/setup.go

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package setup
2+
3+
import (
4+
"context"
5+
"testing"
6+
"time"
7+
8+
"github.com/ksraj123/lister-sa/pkg/constants"
9+
"github.com/ksraj123/lister-sa/tests/generators"
10+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11+
"k8s.io/client-go/kubernetes"
12+
)
13+
14+
func TestOpenEbsPodRunningState(t *testing.T, clientset *kubernetes.Clientset, ctx context.Context, maxRetry int) {
15+
LocalPVProvisionerLabelSelector := "openebs.io/component-name=openebs-localpv-provisioner"
16+
17+
openebsNamespace := constants.OPENEBS_NAMESPACe
18+
19+
tests := map[string]struct {
20+
expected int
21+
}{
22+
"Testing openebs-localpv-provisioner pod state": {
23+
expected: 1,
24+
},
25+
}
26+
27+
testPassed := false
28+
29+
for name, test := range tests {
30+
t.Run(name, func(t *testing.T) {
31+
for i := 0; i < maxRetry; i++ {
32+
pods, _ := clientset.CoreV1().Pods(openebsNamespace).List(ctx, metav1.ListOptions{
33+
LabelSelector: LocalPVProvisionerLabelSelector,
34+
})
35+
if len(pods.Items) == test.expected {
36+
testPassed = true
37+
break
38+
}
39+
time.Sleep(5 * time.Second)
40+
}
41+
if !testPassed {
42+
t.Fatalf("openebs-localpv-provisioner pod not running in namespace, %v", openebsNamespace)
43+
}
44+
})
45+
}
46+
}
47+
48+
func CreateStorageClass(t *testing.T, clientset *kubernetes.Clientset, ctx context.Context, maxRetry int) {
49+
storageClass := generators.GenerateStorageClass(
50+
"test-storage-class",
51+
map[string]string{
52+
constants.STORAGE_CLASS_ANNOTATION: "true",
53+
"openebs.io/cas-type": "local",
54+
"cas.openebs.io/config": `- name: StorageType
55+
value: "hostpath"
56+
- name: BasePath
57+
value: "/var/openebs/local/"`,
58+
},
59+
map[string]string{
60+
constants.STS_PVC_SELECTOR: "sts-pvc",
61+
},
62+
"openebs.io/local")
63+
_, err := clientset.StorageV1().StorageClasses().Create(ctx, storageClass, metav1.CreateOptions{})
64+
if err != nil {
65+
panic(err.Error())
66+
}
67+
time.Sleep(5 * time.Second)
68+
}
69+
70+
func CreateStatefulSet(t *testing.T, clientset *kubernetes.Clientset, ctx context.Context, name string, maxRetry int) {
71+
statefulset := generators.GenerateStatefulSet(name, "default", 2, map[string]string{"sts-pvc": "true"}, "test-storage-class")
72+
_, err := clientset.AppsV1().StatefulSets("default").Create(ctx, statefulset, metav1.CreateOptions{})
73+
if err != nil {
74+
panic(err.Error())
75+
}
76+
time.Sleep(5 * time.Second)
77+
}

tests/suite_test.go

+69-32
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,89 @@
11
package tests
22

33
import (
4-
"flag"
5-
"os"
4+
"context"
5+
"fmt"
6+
"strings"
67
"testing"
8+
"time"
79

8-
. "github.com/onsi/ginkgo"
9-
. "github.com/onsi/gomega"
10+
"github.com/ksraj123/lister-sa/tests/generators"
11+
"github.com/ksraj123/lister-sa/tests/setup"
12+
CoreV1 "k8s.io/api/core/v1"
13+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1014
"k8s.io/client-go/kubernetes"
11-
"k8s.io/client-go/tools/clientcmd"
15+
envtest "sigs.k8s.io/controller-runtime/pkg/envtest"
1216
)
1317

14-
var (
15-
kubeConfigPath string
16-
openebsNamespace string
17-
clientset *kubernetes.Clientset
18-
LocalPVProvisionerLabelSelector = "openebs.io/component-name=openebs-localpv-provisioner"
19-
)
20-
21-
func init() {
22-
flag.StringVar(&kubeConfigPath, "kubeconfig", os.Getenv("KUBECONFIG"), "path to kubeconfig to invoke kubernetes API calls")
23-
flag.StringVar(&openebsNamespace, "openebs-namespace", "openebs", "kubernetes namespace where the OpenEBS components are present")
24-
config, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath)
18+
func startCluster() (*kubernetes.Clientset, *envtest.Environment) {
19+
testenv := &envtest.Environment{}
20+
cfg, err := testenv.Start()
2521
if err != nil {
2622
panic(err.Error())
2723
}
28-
clientset, err = kubernetes.NewForConfig(config)
24+
clientset, err := kubernetes.NewForConfig(cfg)
2925
if err != nil {
3026
panic(err.Error())
3127
}
28+
return clientset, testenv
3229
}
3330

34-
func TestSource(t *testing.T) {
35-
RegisterFailHandler(Fail)
36-
RunSpecs(t, "Test application deployment")
31+
func stopCluster(testenv *envtest.Environment) {
32+
testenv.Stop()
3733
}
3834

39-
var _ = BeforeSuite(func() {
40-
By("waiting for openebs-localpv-provisioner pod to come into running state")
41-
provPodCount := GetPodRunningCountEventually(
42-
openebsNamespace,
43-
LocalPVProvisionerLabelSelector,
44-
1,
45-
clientset,
46-
)
47-
Expect(provPodCount).To(Equal(1))
35+
func TestMain(t *testing.T) {
36+
ctx := context.Background()
37+
clientSet, clusterTestEnv := startCluster()
38+
defer stopCluster(clusterTestEnv)
39+
40+
// Ensure openebs-localpv-provisioner pod running
41+
setup.TestOpenEbsPodRunningState(t, clientSet, ctx, 90)
42+
setup.CreateStorageClass(t, clientSet, ctx, 10)
43+
statefulsetName := "test-sts"
44+
setup.CreateStatefulSet(t, clientSet, ctx, statefulsetName, 10)
4845

49-
// run our job
50-
})
46+
// Delete the statefulset
47+
48+
err := clientSet.AppsV1().StatefulSets("default").Delete(ctx, statefulsetName, metav1.DeleteOptions{})
49+
if err != nil {
50+
panic(err.Error())
51+
}
52+
53+
time.Sleep(5 * time.Second)
54+
55+
// now the statefulset PVCs are in dangling state
56+
57+
serviceAccountName := "openebs-maya-operator"
58+
image := "ksraj123/stale-sts-pvc-cleaner:0.1"
59+
env := []CoreV1.EnvVar{
60+
{
61+
Name: "PROVISIONERS",
62+
Value: "openebs.io/local",
63+
},
64+
{
65+
Name: "NAMESPACES",
66+
Value: "default",
67+
},
68+
}
5169

52-
var _ = Describe("Shopping cart", func() {})
70+
job := generators.GenerateJob("test-job", map[string]string{"jobGroup": "test"}, serviceAccountName, image, env)
71+
_, err = clientSet.BatchV1().Jobs("default").Create(ctx, job, metav1.CreateOptions{})
72+
if err != nil {
73+
panic(err.Error())
74+
}
75+
76+
time.Sleep(5 * time.Second)
77+
78+
pvcs, err := clientSet.CoreV1().PersistentVolumeClaims("default").List(ctx, metav1.ListOptions{})
79+
if err != nil {
80+
fmt.Printf("error %s, getting PVCs\n", err.Error())
81+
}
82+
for _, pvc := range pvcs.Items {
83+
if strings.Contains(pvc.Name, statefulsetName) {
84+
t.Fatalf("Dangling PVCs %v not deleted by Job", pvc.Name)
85+
}
86+
}
87+
88+
// clientSet.BatchV1().Jobs("default").Delete(ctx, "test-job", metav1.DeleteOptions{})
89+
}

0 commit comments

Comments
 (0)