Merge pull request #4136 from jwcesign/sync-show-v1
e2e: add test case for hpa replicas syncer
This commit is contained in:
commit
bea718a0c3
|
@ -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())
|
||||
})
|
||||
}
|
|
@ -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))
|
||||
})
|
||||
})
|
||||
})
|
|
@ -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"}
|
||||
|
|
Loading…
Reference in New Issue