Skip to content

Commit

Permalink
feat: add method to check pvc exists (#167)
Browse files Browse the repository at this point in the history
* build: go 1.21, godog 0.14.1, api, apimachinery & client-go v0.28.12 (#161)

* build: go 1.21, godog 0.14.1, api, apimachinery & client-go v0.28.12

* ci: building examples

* ci(examples): check-dirty-repo

* test(UT): fixing getIngressWithHostname

* test(UT): fixing TestGetInstanceGroupList

* refactor: replace 'err == wait.ErrWaitTimeout' with 'wait.Interrupted(err)'

* chore: adding missed space

Signed-off-by: sbhat14 <[email protected]>

* feat: add method to check pvc exists

Signed-off-by: sbhat14 <[email protected]>

* fix: address review comments

Signed-off-by: sbhat14 <[email protected]>

* fix: retry

Signed-off-by: sbhat14 <[email protected]>

* remove unnecessary string formatting

Signed-off-by: sbhat14 <[email protected]>

---------

Signed-off-by: sbhat14 <[email protected]>
Co-authored-by: Alfredo Garo <[email protected]>
Co-authored-by: sbhat14 <[email protected]>
  • Loading branch information
3 people authored Nov 12, 2024
1 parent 982eb78 commit 89d8f79
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 14 deletions.
1 change: 1 addition & 0 deletions docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Below you will find the step syntax next to the name of the method it utilizes.
- `<GK> [the] deployment <any-characters-except-(")> is running in namespace <any-characters-except-(")>` kdt.KubeClientSet.DeploymentIsRunning
- `<GK> [the] data in [the] ConfigMap "<any-characters-except-(")>" in namespace "<any-characters-except-(")>" has key "<any-characters-except-(")>" with value "<any-characters-except-(")>"` kdt.KubeClientSet.ConfigMapDataHasKeyAndValue
- `<GK> [the] persistentvolume <any-characters-except-(")> exists with status (Available|Bound|Released|Failed|Pending)` kdt.KubeClientSet.PersistentVolExists
- `<GK> [the] persistentvolumeclaim <any-characters-except-(")> exists with status (Available|Bound|Released|Failed|Pending) in namespace <any-characters-except-(")>` kdt.KubeClientSet.PersistentVolClaimExists
- `<GK> [the] (clusterrole|clusterrolebinding) with name <any-characters-except-(")> should be found` kdt.KubeClientSet.ClusterRbacIsFound
- `<GK> [the] ingress <non-whitespace-characters> in [the] namespace <non-whitespace-characters> [is] [available] on port <digits> and path <any-characters-except-(")>` kdt.KubeClientSet.IngressAvailable
- `<GK> [I] send <digits> tps to ingress <non-whitespace-characters> in [the] namespace <non-whitespace-characters> [available] on port <digits> and path <any-characters-except-(")> for <digits> (minutes|seconds) expecting up to <digits> error[s]` kdt.KubeClientSet.SendTrafficToIngress
Expand Down
1 change: 1 addition & 0 deletions kubedog.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func (kdt *Test) SetScenario(scenario *godog.ScenarioContext) {
kdt.scenario.Step(`^(?:the )?deployment ([^"]*) is running in namespace ([^"]*)$`, kdt.KubeClientSet.DeploymentIsRunning)
kdt.scenario.Step(`^(?:the )?data in (?:the )?ConfigMap "([^"]*)" in namespace "([^"]*)" has key "([^"]*)" with value "([^"]*)"$`, kdt.KubeClientSet.ConfigMapDataHasKeyAndValue)
kdt.scenario.Step(`^(?:the )?persistentvolume ([^"]*) exists with status (Available|Bound|Released|Failed|Pending)$`, kdt.KubeClientSet.PersistentVolExists)
kdt.scenario.Step(`^(?:the )?persistentvolumeclaim ([^"]*) exists with status (Available|Bound|Released|Failed|Pending) in namespace ([^"]*)$`, kdt.KubeClientSet.PersistentVolClaimExists)
kdt.scenario.Step(`^(?:the )?(clusterrole|clusterrolebinding) with name ([^"]*) should be found$`, kdt.KubeClientSet.ClusterRbacIsFound)
kdt.scenario.Step(`^(?:the )?ingress (\S+) in (?:the )?namespace (\S+) (?:is )?(?:available )?on port (\d+) and path ([^"]*)$`, kdt.KubeClientSet.IngressAvailable)
kdt.scenario.Step(`^(?:I )?send (\d+) tps to ingress (\S+) in (?:the )?namespace (\S+) (?:available )?on port (\d+) and path ([^"]*) for (\d+) (minutes|seconds) expecting up to (\d+) error(?:s)?$`, kdt.KubeClientSet.SendTrafficToIngress)
Expand Down
4 changes: 4 additions & 0 deletions pkg/kube/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,10 @@ func (kc *ClientSet) PersistentVolExists(name, expectedPhase string) error {
return structured.PersistentVolExists(kc.KubeInterface, name, expectedPhase)
}

func (kc *ClientSet) PersistentVolClaimExists(name, expectedPhase string, namespace string) error {
return structured.PersistentVolClaimExists(kc.KubeInterface, name, expectedPhase, namespace)
}

func (kc *ClientSet) ClusterRbacIsFound(resourceType, name string) error {
return structured.ClusterRbacIsFound(kc.KubeInterface, resourceType, name)
}
Expand Down
22 changes: 22 additions & 0 deletions pkg/kube/structured/structured.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"net/http"
"os"
"strconv"
"strings"
"time"

log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -235,6 +236,27 @@ func PersistentVolExists(kubeClientset kubernetes.Interface, name, expectedPhase
return nil
}

func PersistentVolClaimExists(kubeClientset kubernetes.Interface, name, expectedPhase string, namespace string) error {
_, err := util.RetryOnError(
&util.DefaultRetry,
func(err error) bool {
msg := "persistentvolumeclaim had unexpected phase"
return util.IsRetriable(err) || strings.Contains(err.Error(), msg)
},
func() (interface{}, error) {
vol, err := GetPersistentVolumeClaim(kubeClientset, name, namespace)
if err != nil {
return nil, err
}
phase := string(vol.Status.Phase)
if phase != expectedPhase {
return nil, fmt.Errorf("persistentvolumeclaim had unexpected phase %v, expected phase %v", phase, expectedPhase)
}
return nil, nil
})
return err
}

func ValidatePrometheusVolumeClaimTemplatesName(kubeClientset kubernetes.Interface, statefulsetName, namespace, volumeClaimTemplatesName string) error {
// Prometheus StatefulSets deployed, then validate volumeClaimTemplate name.
// Validation required:
Expand Down
14 changes: 14 additions & 0 deletions pkg/kube/structured/structured_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,20 @@ func GetPersistentVolume(kubeClientset kubernetes.Interface, name string) (*core
return pvs.(*corev1.PersistentVolume), nil
}

func GetPersistentVolumeClaim(kubeClientset kubernetes.Interface, name string, namespace string) (*corev1.PersistentVolumeClaim, error) {
if err := common.ValidateClientset(kubeClientset); err != nil {
return nil, err
}

pvc, err := util.RetryOnError(&util.DefaultRetry, util.IsRetriable, func() (interface{}, error) {
return kubeClientset.CoreV1().PersistentVolumeClaims(namespace).Get(context.Background(), name, metav1.GetOptions{})
})
if err != nil {
return nil, errors.Wrap(err, "failed to get persistentvolumeclaim")
}
return pvc.(*corev1.PersistentVolumeClaim), nil
}

func GetStatefulSetList(kubeClientset kubernetes.Interface, namespace string) (*appsv1.StatefulSetList, error) {
if err := common.ValidateClientset(kubeClientset); err != nil {
return nil, err
Expand Down
94 changes: 80 additions & 14 deletions pkg/kube/structured/structured_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,21 @@ import (
)

const (
configMapType = "configmap"
deploymentType = "deployment"
serviceType = "service"
hpaType = "horizontalpodautoscaler"
pdbType = "poddisruptionbudget"
saType = "serviceaccount"
clusterRoleType = "clusterrole"
clusterRoleBindingType = "clusterrolebinding"
nodeType = "node"
daemonSetType = "daemonset"
persistentVolumeType = "persistentvolume"
statefulSetType = "statefulset"
secretType = "secret"
ingressType = "ingress"
configMapType = "configmap"
deploymentType = "deployment"
serviceType = "service"
hpaType = "horizontalpodautoscaler"
pdbType = "poddisruptionbudget"
saType = "serviceaccount"
clusterRoleType = "clusterrole"
clusterRoleBindingType = "clusterrolebinding"
nodeType = "node"
daemonSetType = "daemonset"
persistentVolumeType = "persistentvolume"
persistentVolumeClaimType = "persistentVolumeClaim"
statefulSetType = "statefulset"
secretType = "secret"
ingressType = "ingress"
)

func TestNodesWithSelectorShouldBe(t *testing.T) {
Expand Down Expand Up @@ -480,6 +481,60 @@ func TestPersistentVolExists(t *testing.T) {
}
}

func TestPersistentVolClaimExists(t *testing.T) {
type args struct {
kubeClientset kubernetes.Interface
name string
namespace string
expectedPhase string
}
// expectedPhase: Available|Bound|Released|Failed|Pending
persistentvolumeClaimName := "persistentvolumeclaim1"
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "pvc found",
args: args{
kubeClientset: fake.NewSimpleClientset(getResource(t, persistentVolumeClaimType, persistentvolumeClaimName)),
name: persistentvolumeClaimName,
namespace: "",
expectedPhase: "Bound",
},
wantErr: false,
},
{
name: "pvc found with wrong phase",
args: args{
kubeClientset: fake.NewSimpleClientset(getResource(t, persistentVolumeClaimType, persistentvolumeClaimName)),
name: persistentvolumeClaimName,
namespace: "",
expectedPhase: "Released",
},
wantErr: true,
},
{
name: "pvc not found Test",
args: args{
kubeClientset: fake.NewSimpleClientset(getResource(t, persistentVolumeClaimType, "testabc")),
name: persistentvolumeClaimName,
namespace: "",
expectedPhase: "",
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := PersistentVolClaimExists(tt.args.kubeClientset, tt.args.name, tt.args.expectedPhase, tt.args.namespace); (err != nil) != tt.wantErr {
t.Errorf("PersistentVolClaimExists() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func TestValidatePrometheusVolumeClaimTemplatesName(t *testing.T) {
type args struct {
kubeClientset kubernetes.Interface
Expand Down Expand Up @@ -833,6 +888,17 @@ func getResourceWithAll(t *testing.T, resourceType, name, namespace, label strin
Labels: labels,
},
}
case persistentVolumeClaimType:
return &corev1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: labels,
},
Status: corev1.PersistentVolumeClaimStatus{
Phase: corev1.ClaimBound,
},
}
case statefulSetType:
return &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Expand Down

0 comments on commit 89d8f79

Please sign in to comment.