Merge pull request #4136 from jwcesign/sync-show-v1

e2e: add test case for hpa replicas syncer
This commit is contained in:
karmada-bot 2023-10-31 20:34:35 +08:00 committed by GitHub
commit bea718a0c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 154 additions and 0 deletions

28
test/e2e/framework/hpa.go Normal file
View File

@ -0,0 +1,28 @@
package framework
import (
"context"
"fmt"
"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
autoscalingv2 "k8s.io/api/autoscaling/v2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)
// CreateHPA create HPA.
func CreateHPA(client kubernetes.Interface, hpa *autoscalingv2.HorizontalPodAutoscaler) {
ginkgo.By(fmt.Sprintf("Creating HPA(%s/%s)", hpa.Namespace, hpa.Name), func() {
_, err := client.AutoscalingV2().HorizontalPodAutoscalers(hpa.Namespace).Create(context.TODO(), hpa, metav1.CreateOptions{})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
})
}
// RemoveHPA delete HPA.
func RemoveHPA(client kubernetes.Interface, namespace, name string) {
ginkgo.By(fmt.Sprintf("Removing HPA(%s/%s)", namespace, name), func() {
err := client.AutoscalingV2().HorizontalPodAutoscalers(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
})
}

View File

@ -0,0 +1,91 @@
package e2e
import (
"context"
"time"
"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
appsv1 "k8s.io/api/apps/v1"
autoscalingv2 "k8s.io/api/autoscaling/v2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/rand"
"k8s.io/utils/pointer"
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
"github.com/karmada-io/karmada/test/e2e/framework"
"github.com/karmada-io/karmada/test/helper"
)
var _ = ginkgo.Describe("hpa replicas synchronization testing", func() {
ginkgo.Context("Replicas synchronization testing", func() {
var policyNamespace, policyName string
var namespace, deploymentName, hpaName string
var deployment *appsv1.Deployment
var hpa *autoscalingv2.HorizontalPodAutoscaler
var policy *policyv1alpha1.PropagationPolicy
ginkgo.BeforeEach(func() {
policyNamespace = testNamespace
namespace = testNamespace
policyName = deploymentNamePrefix + rand.String(RandomStrLength)
deploymentName = policyName
hpaName = policyName
deployment = helper.NewDeployment(namespace, deploymentName)
deployment.Spec.Replicas = pointer.Int32(1)
hpa = helper.NewHPA(namespace, hpaName, deploymentName)
hpa.Spec.MinReplicas = pointer.Int32(2)
policy = helper.NewPropagationPolicy(policyNamespace, policyName, []policyv1alpha1.ResourceSelector{
{
APIVersion: deployment.APIVersion,
Kind: deployment.Kind,
Name: deployment.Name,
},
{
APIVersion: hpa.APIVersion,
Kind: hpa.Kind,
Name: hpa.Name,
},
}, policyv1alpha1.Placement{
ClusterAffinity: &policyv1alpha1.ClusterAffinity{
ClusterNames: framework.ClusterNames(),
},
})
})
ginkgo.BeforeEach(func() {
framework.CreatePropagationPolicy(karmadaClient, policy)
framework.CreateDeployment(kubeClient, deployment)
framework.CreateHPA(kubeClient, hpa)
ginkgo.DeferCleanup(func() {
framework.RemovePropagationPolicy(karmadaClient, policy.Namespace, policy.Name)
framework.RemoveDeployment(kubeClient, deployment.Namespace, deployment.Name)
framework.RemoveHPA(kubeClient, namespace, hpa.Name)
framework.WaitDeploymentDisappearOnClusters(framework.ClusterNames(), deployment.Namespace, deployment.Name)
})
})
ginkgo.It("deployment has been scaled up and synchronized to Karmada", func() {
framework.WaitDeploymentPresentOnClustersFitWith(framework.ClusterNames(), deployment.Namespace, deployment.Name,
func(deployment *appsv1.Deployment) bool {
return true
})
framework.WaitDeploymentPresentOnClustersFitWith(framework.ClusterNames(), deployment.Namespace, deployment.Name,
func(deployment *appsv1.Deployment) bool {
return *deployment.Spec.Replicas == *hpa.Spec.MinReplicas
})
expectedReplicas := *hpa.Spec.MinReplicas * int32(len(framework.ClusterNames()))
gomega.Eventually(func() bool {
deploymentExist, err := kubeClient.AppsV1().Deployments(deployment.Namespace).Get(context.TODO(), deployment.Name, metav1.GetOptions{})
if err != nil {
return false
}
return (*deploymentExist.Spec.Replicas == expectedReplicas) && (deploymentExist.Generation == deploymentExist.Status.ObservedGeneration)
}, time.Minute, pollInterval).Should(gomega.Equal(true))
})
})
})

View File

@ -133,6 +133,41 @@ func NewFederatedHPA(namespace, name, scaleTargetDeployment string) *autoscaling
}
}
// NewHPA will build a HorizontalPodAutoscaler object.
func NewHPA(namespace, name, scaleDeployment string) *autoscalingv2.HorizontalPodAutoscaler {
return &autoscalingv2.HorizontalPodAutoscaler{
TypeMeta: metav1.TypeMeta{
APIVersion: "autoscaling/v2",
Kind: "HorizontalPodAutoscaler",
},
ObjectMeta: metav1.ObjectMeta{
Namespace: namespace,
Name: name,
},
Spec: autoscalingv2.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{
Kind: "Deployment",
Name: scaleDeployment,
APIVersion: "apps/v1",
},
MinReplicas: pointer.Int32(4),
MaxReplicas: 6,
Metrics: []autoscalingv2.MetricSpec{
{
Type: autoscalingv2.ResourceMetricSourceType,
Resource: &autoscalingv2.ResourceMetricSource{
Name: corev1.ResourceCPU,
Target: autoscalingv2.MetricTarget{
Type: autoscalingv2.UtilizationMetricType,
AverageUtilization: pointer.Int32(80),
},
},
},
},
},
}
}
// NewDeployment will build a deployment object.
func NewDeployment(namespace string, name string) *appsv1.Deployment {
podLabels := map[string]string{"app": "nginx"}