Skip to content

Commit

Permalink
add sts e2e case for pr (#3800)
Browse files Browse the repository at this point in the history
* add sts e2e case for pr
#3777

---------

Signed-off-by: Changlu Yi <[email protected]>
  • Loading branch information
changluyi authored Mar 8, 2024
1 parent 9e3fdab commit a8dc9ab
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 1 deletion.
66 changes: 65 additions & 1 deletion test/e2e/framework/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,26 @@ package framework

import (
"context"
"errors"
"fmt"
"strings"
"time"

"github.com/onsi/gomega"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
v1apps "k8s.io/client-go/kubernetes/typed/apps/v1"
"k8s.io/kubectl/pkg/polymorphichelpers"
"k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/framework/statefulset"

"github.com/onsi/gomega"
"github.com/kubeovn/kube-ovn/pkg/util"
)

type StatefulSetClient struct {
Expand Down Expand Up @@ -96,6 +104,62 @@ func (c *StatefulSetClient) WaitToDisappear(name string, _, timeout time.Duratio
return nil
}

func (c *StatefulSetClient) PatchSync(original, modified *appsv1.StatefulSet) *appsv1.StatefulSet {
sts := c.Patch(original, modified)
return c.RolloutStatus(sts.Name)
}

func (c *StatefulSetClient) Patch(original, modified *appsv1.StatefulSet) *appsv1.StatefulSet {
patch, err := util.GenerateMergePatchPayload(original, modified)
ExpectNoError(err)

var patchedSts *appsv1.StatefulSet
err = wait.PollUntilContextTimeout(context.Background(), 2*time.Second, timeout, true, func(ctx context.Context) (bool, error) {
sts, err := c.StatefulSetInterface.Patch(ctx, original.Name, types.StrategicMergePatchType, patch, metav1.PatchOptions{}, "")
if err != nil {
return handleWaitingAPIError(err, false, "patch StatefulSet %s/%s", original.Namespace, original.Name)
}
patchedSts = sts
return true, nil
})
if err == nil {
return patchedSts.DeepCopy()
}

if errors.Is(err, context.DeadlineExceeded) {
Failf("timed out while retrying to patch StatefulSet %s/%s", original.Namespace, original.Name)
}
Failf("error occurred while retrying to patch StatefulSet %s/%s: %v", original.Namespace, original.Name, err)

return nil
}

func (c *StatefulSetClient) RolloutStatus(name string) *appsv1.StatefulSet {
var sts *appsv1.StatefulSet
WaitUntil(2*time.Second, timeout, func(_ context.Context) (bool, error) {
var err error
sts = c.Get(name)
unstructured := &unstructured.Unstructured{}
if unstructured.Object, err = runtime.DefaultUnstructuredConverter.ToUnstructured(sts); err != nil {
return false, err
}

viewer := &polymorphichelpers.StatefulSetStatusViewer{}
msg, done, err := viewer.Status(unstructured, 0)
if err != nil {
return false, err
}
if done {
return true, nil
}

Logf(strings.TrimSpace(msg))
return false, nil
}, "")

return sts
}

func MakeStatefulSet(name, svcName string, replicas int32, labels map[string]string, image string) *appsv1.StatefulSet {
sts := statefulset.NewStatefulSet(name, "", svcName, replicas, nil, nil, labels)
sts.Spec.Template.Spec.Containers[0].Image = image
Expand Down
66 changes: 66 additions & 0 deletions test/e2e/kube-ovn/pod/statefulset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package pod

import (
"fmt"

"github.com/onsi/ginkgo/v2"

"github.com/kubeovn/kube-ovn/pkg/util"
"github.com/kubeovn/kube-ovn/test/e2e/framework"
)

var _ = framework.Describe("[group:pod]", func() {
f := framework.NewDefaultFramework("pod")

var podClient *framework.PodClient
var stsClient *framework.StatefulSetClient
var stsName string

ginkgo.BeforeEach(func() {
podClient = f.PodClient()
stsClient = f.StatefulSetClient()
stsName = "sts-" + framework.RandomSuffix()
})
ginkgo.AfterEach(func() {
ginkgo.By("Deleting sts " + stsName)
stsClient.DeleteSync(stsName)
})

framework.ConformanceIt("Should support statefulset scale Replica", func() {
// add this case for pr https://github.com/kubeovn/kube-ovn/pull/3777
replicas := 3
labels := map[string]string{"app": stsName}

ginkgo.By("Creating statefulset " + stsName)
sts := framework.MakeStatefulSet(stsName, stsName, int32(replicas), labels, framework.PauseImage)
sts = stsClient.CreateSync(sts)
ginkgo.By("Delete pod for statefulset " + stsName)
pod2Name := stsName + "-2"
pod2 := podClient.GetPod(pod2Name)
pod2IP := pod2.Annotations[util.IPAddressAnnotation]
err := podClient.Delete(pod2Name)
framework.ExpectNoError(err, "failed to delete pod "+pod2Name)
stsClient.WaitForRunningAndReady(sts)
pod2 = podClient.GetPod(pod2Name)
framework.ExpectEqual(pod2.Annotations[util.IPAddressAnnotation], pod2IP)

ginkgo.By("Scale sts replicas to 1")
sts = stsClient.Get(stsName)
patchSts := sts.DeepCopy()
*patchSts.Spec.Replicas = 1
stsClient.PatchSync(sts, patchSts)

for index := 1; index <= 2; index++ {
podName := fmt.Sprintf("%s-%d", stsName, index)
ginkgo.By(fmt.Sprintf("Waiting pod %s to be deleted", podName))
podClient.WaitForNotFound(podName)
}
ginkgo.By("Scale sts replicas to 3")
sts = stsClient.Get(stsName)
patchSts = sts.DeepCopy()
*patchSts.Spec.Replicas = 3
stsClient.PatchSync(sts, patchSts)
ginkgo.By("Waiting for statefulset " + stsName + " to be ready")
stsClient.WaitForRunningAndReady(patchSts)
})
})

0 comments on commit a8dc9ab

Please sign in to comment.